It appears that when the progress logger was broken up into separate
classes, the progress_end function was not properly split and some
threading functionality remained in the base class.
I have also added some poll helpers to the idprops module so every time
we use an ID Datablock Property, we won't have to reinvent the wheel. I
also noticed that PointerProperties have to be a direct descendent of
`bpy.types.ID` otherwise Blender crashes. This kind of makes sense and
is not a huge issue to have to work around.
This effectively bumps the minimum requirement to Blender 2.79.
Furthermore, any blendfiles saved with ID Datablock properties will
crash earlier versions of Blender. You have been warned...
After approximately 24 hours of writing, rewriting, and cursing Blender,
this appears to be the most flexible way of magically upgrading our old
string properties to ID Datablock properties. The general hacky-ness is
due to limitations in Blender's API.
Here's how it works... In your property group (node, modifier, etc) you
will need to implement the classmethod `_idprop_mapping`. This will map
new ID Datablock property attribute names to old string property
attribute names. Further, you will need to implement the
`_idprop_sources` method. This will map string property attribute names
to a collection to fetch the ID from. If you have specific filtering
rules to follow, they can be implemented here :).
To ensure code sanity, any attempts to access string properties that
have been marked as converted will now fail with an AttributeError.
Happy haxxoring!
The only major issue with the console based progress solution is that
the user would have to remember to press "Toggle System Console" before
the export. This button corresponds to the operator
`bpy.ops.wm.console_toggle`. Unfortunately, Blender does not expose a
way for us to query the console state. So, we have to get nasty and use
ctypes to ask the OS if the console window is active. The user may
already have it open and hidden behind Blender's UI, after all.
This changeset causes the console to open during the export (unless
disabled in the export operator). If the console was closed before the
export, it closes again once the export is finished, unless there is an
error. If the console was open, it remains open.
Unfortunately, this only works on Windows. But, according to the source
code of `bpy.ops.wm.console_toggle`, Blender's `ghost_toggleConsole`
only functions on the Win32 subsystem... SDL, X11, and Cocoa are all
no-ops. Future work would include a patch submitted to Blender adding an
enum property to the console operator to avoid this code duplication.
Now the progress display will recognize errors using the `__exit__`
magic method and print out an error header with the actual error
message. This is useful because when the mouse leaves the Blender
operator's report error, the error "window" is destroyed. This led to
potential silent failures.
For sanity, I stripped the progress manager into a subclass. From there,
I moved all of the progress printing into a thread so that we can accept
signals for step progress. If there is no step progress for a time, we
show the user a rolling set of ellipses to prove we're not dead (yet).
A common complaint that I have heard (and have nyself) is that there is
little indication of what Korman is doing in the background. In PyPRP,
the raw export log was dumped to the console, and many liked to watch it
travel by as an indicator of progress. As such, I have implemented a
rudimentary progress monitor that outputs to the console into the export
logger.
Unfortunately, there is no "easy" way to show progress in the Blender UI
currently. Korman makes the assumption that nothing will touch
Blender's context while it is executing. Attempts to mvoe the exporter
into a background thread have all resulted in spectacular failures. So,
this will have to do for now.
The export logger and export reporter have been merged together to form
an eventually much more powerful export analysis feature. For now, the
benefit is that general log messages don't have to be so fiddly with
print statements and string formatting. You're welcome.
plGeometrySpan.TempVertex.uvs now returns an immutable tuple, so we have
to convert that to a list. Furthermore, I took the liberty of changing
to code to avoid spin-washing on the first encounter of a bumpmapped
vertex.
The changeset referenced makes the assumption that
`grouped_fcurves[chan]` is a dict. We really can't assume anything about
types this deep inside the animation converter.
The "strength" of the normal mapping is the red channel of its runtime
colour.
If the normal map is a specular map, it should be Add blending,
otherwise it should use MADD blending.
A few unfinished bits:
1. This doesn't properly handle multi-material objects, which are
permitted to have separate bumpmaps on each material.
2. This doesn't generate the BumpLutRamp image for the Du, Dv, Dw
layers.