- hisanimations changed review status to Awaiting Review
- 1 mo
Append and link rigs! Save space like never before! OptiPloy, the Optimized Deployment of rigs (and more) is now here.
OptiPloy (optimized deployment) can be considered a better alternative to appending and linking rigs, while having the best of both worlds. Appending them for full functionality, and linking all the data that composes the rig to reduce duplication. And that can save a LOT of space.
(Don't have a set of rigs to test it with? Try my TF2 Buildings port! https://drive.google.com/drive/folders/11vyl_97Xy8LE-VPECfLlJ876poRZp6AT?usp=drive_link)
In the preferences, you will find two sections to add .blend files. Individually or by a folder of them. Now there are two things worth noting. OptiPloy will only spawn objects or collections, if they have been marked as assets. And two, it will not go through sub folders to look for .blend flies of and folder you add
Once you have a .blend file prepared with a rig under a collection marked as an asset, you may now add that .blend file to OptiPloy. It will automatically be scanned for spawnable items, which you can spawn through the OptiPloy tab in the 3D Viewport.
Through the bpy.data.libraries.load
feature, OptiPloy links an object/collection, applies library overrides over hierarchy, then localizes it as much as the user wishes. This is crucial for a fast-working spawning tool that recycles as much data as possible without the hassle of manually localizing IDs. And since the localization options can be entry-specific, I have no doubt this could be a user-favorite when it comes to working with the tens to hundreds of rigs they frequently use.
By default, OptiPloy localizes any collection(s) and any object(s). However, if a user wishes to edit the mesh of an object, they will be required to make a local copy of a mesh. This is a setting you can have enabled so any newly spawned mesh is localized for user modifications. You can always localize it later by clicking the chain link icon of a mesh. This applies to any other object data type.
However, leaving things unlocalized gives users a chance to modify the data in the source file with the changes updating in any other file, so long as the changed attributes aren't overridden. This is great for mass modification in case a user errs.
Spawning the same data with different settings applied will not localize pre-existing data, so long as the data is that of collections, objects, materials, or any other object data type. (see object data types)
Optiploy assigns newly spawned items to a globally accessible variable, context.scene['new_spawn']
. This gives you an opportunity to write a script to further modify data when OptiPloy executes any attached script. Say for example, you have a ragdoll rig and you need to initialize the Rigid Body World and assign collisions and constraints to collections used by the RBW.
In the tools view mode in the OptiPloy tab, you can choose whether to localize meshes, materials, images, node groups, and armature data by default. But if this data gets localized despite having these options disabled, that means they are localized because another asset requires them to be.
In the Tools
view mode in the 3D viewport, you can choose which objects types should be localized or not. Any folder/blend entry can override these options by enabling so in their settings panel.
Here are the list of IDs that can be localized/overridden:
bpy.types.Collection,
bpy.types.Object,
bpy.types.Mesh,
bpy.types.Material,
bpy.types.SurfaceCurve,
bpy.types.Light,
bpy.types.Curve,
bpy.types.GreasePencil,
bpy.types.MetaBall,
bpy.types.TextCurve,
bpy.types.Volume,
bpy.types.Armature,
bpy.types.Camera
IDs like meshes and materials are duplicating when I spawn the same item more than once, despite having the localizing options off. What's going on?
This is a good question. "Data Isolation" was a concept I struggled with when making OptiPloy.
Normally, when you spawn the same item again with more localizing options enabled, the data from the pre-existing item would get localized along with this new instance. To counteract this, a lot of supported IDs are given library overrides to put them in a state between linked and fully localized. While this does result in duplication, it doesn't use as much storage as it could. And it successfully isolates the data tied to the instance of that item, mostly preventing further modification from later spawns.
Theoretically, this data isolation can be done without library overrides. In practice, I've achieved this by having another instance of Blender load, modify, and save the data for the main instance to use in real time. Despite how interesting this concept was, I doubt users would be happy with a background instance of Blender running for each main instance. Another way this could be achieved is by using the bpy.types.BlendData.temp_data()
function to act as the "second instance", but it would cause Blender to crash whenever linking data in this temp_data context. If it didn't crash, it would always prompt the user with a "corrupt data" warning.
I get tons of "bke.liboverride" errors when spawning something!
If this rig saves you a bunch of space, and time, you just might consider supporting! https://ko-fi.com/hisanimations
Thank you to LetUmGo ( https://www.youtube.com/@Letumgo ) for helping with the logo!
Added checks to prevent the localization of bone shapes, unless referenced elsewhere
This extension requests the following permission:
Read and save .blend and folder entries
Removed transmitter.py and operators.py
from . import IDNAME
has been written
Requesting another check-up
There is some strange logic regarding modules & paths still.
__package__
must be used instead of hard-coded "OptiPloy"
.
In your case I'd suggest to:
IDNAME = __package__
.IDNAME
to base_package
(a convention suggested in our docs).Module reload logic is running every time on startup, this is doing a search for all python scripts.
In general it's better not to do these kinds of file-system scans. The modules should be listed explicitly.
Also, there is no reason to run this every time.
if "my_module" in locals():
... reload logic ...
import my_module
Can be used to run reload logic only when the add-on is reloaded.
This line reads quite strangely
name = os.path.basename(self.directory[:-1 if self.directory[-1] in {'/', '\\'} else None])
It can probably be written as:
name = os.path.basename(self.directory.rstrip(os.sep))
or name = os.path.basename(self.directory.rstrip("//\"))
.
IDNAME
to __package__
, and renamed IDNAME
to base_package
I referenced code from an earlier addon with module reloading logic, so I apologize for that. I've written
if 'preferences' in locals():
importlib.reload(preferences)
if 'panel' in locals():
importlib.reload(panel)
rstrip
could do that.In version v.1.1.0, I have added support for library overrides. Hopefully the logic implementing this feature is up to code!
Did not mean to make the comment look like that
I've acknowledged current issues. Will work on them further.
Hello Campbell,
I've taken time off of my project to better grasp Blender's API, and how to work with the Library Override feature. I feel now that I have a much better project with simpler code, and more overall reasonable logic.
Given how drastic the changes are, and how unofficial the addon is, I've decided to re-release it as 1.0. Hopefully that doesn't conflict with anything. I'm here for any feedback you might have.
Sign in to comment.
Ready for review