Open wizardgsz opened 5 years ago
I'm not 100% sure I understand the behaviour you're suggesting.
Are you thinking it would be good to support importing a .vox
, but have the result be solely the model shell? That was a little outside of the original scope, and I believe is easier done via MagicaVoxel's export options. I am not opposed to it featuring as an option, however.
Or are you perhaps simply wanting to simplify the scene in some regard, while maintaining the full voxel data, so that it may be used for simulations (the original intent)
I have not looked into it, but I believe one way that the import may be sped up would be the use of instancing (previously known as dupli-faces). That would result in only a single real cube in the scene, with all the others being replaced by single quad faces.
I believe using instancing for rigid body collision modelling is already a common practice, though I'm not sure how material information would be handled. Perhaps it would be that each material would have its own master cube.
My reflection starts from the simple use of VOX models in Blender: move, rotate, or anything else is so slow, but I have a very slow hardware.
For example, after importing a file with 1000 cubes or more, try moving them or simply deleting them all: having to manage 1000 cubes, Blender is really slow. Try doing the same with "joined" objects (CTRL+J) and everything will be instantaneous!
In practise, I have compable times to:
A subsequent reflection is: having to support scene-graph (and therefore objects hierarchically linked), how will Blender work using 1000 roto-translations rather than a single one (the "joined" object)?
Obviously it depends on how you'll use imported data:
Finally, but I understand that it is well beyond the context of the importer:
Working with tens of thousands of voxels, such sort of "optimization" can make the difference. But only for "static" objects of course.
That is, for the 4854 voxels sample:
I preferred to edit the post with a real example :-)
Perhaps my views are best explained if I give a little background to this repository, and why it was made.
October of 2017 I was playing around with making voxel models, working on a reasonably small scale, something like 28³. At that time I was using VoxelShop.
VoxelShop supported exporting the voxel models to several combined formats, such as .obj
, but I wanted to have access to all the voxels for physics simulations (moreso just something easy that looks neat)
That led me down the path of finding VoxelShop's ability to export to .vox
, and therefore to MagicaVoxel. As this format was openly documented, it served as a good interface format for me to get the data I wanted into Blender.
From there I built upon what I had done, to automate the material creation and so forth.
I do seem to remember the process of using Blender on these models running a lot smoother, pre 2.80, this might be a case where the new engine suffers more than previous version. It might also be me misremembering, or perhaps I did some joining and splitting workflow. I don't happen to have 2.7x installed to test.
Hopefully that puts into perspective why I chose to maintain all the original geometry, so far.
Now, going forward, is that the only use case for a vox importer? Certainly not, importing directly rather than having to go via .obj
or something is certainly appealing.
Having an option to join everything down certainly sounds like a good thing to pursue, and if that's something you'd want to work on, I will happily help incorporate it into the repo.
Furthermore, removing internal geometry entirely sounds quite difficult to achieve, but the same applies. I am happy to make this a multi-purpose importer able to handle everything.
The fastest option to join objects should be fine (default=False, do not merge voxels); moreover, I do not know how to remove duplicates data using Python right now 😄
I will work on it later... thanks.
def join_selected(context):
active = context.active_object
selection = context.selected_objects
selected = set(selection).difference(set([active]))
if not (active and selected):
return
print("Active object:", active.name)
print("Selected objects:", len(selected), len(selection))
bpy.ops.object.join()
Having:
active
the "father" object (i.e. the final object)selected
the voxels to mergeHow to set the new "pivot" as the center of the "bounding box" (having x, y, z loaded from SIZE
chunk)?
I write here just a "note", a code snippet, to further investigate about it (especially when scene-graph will be implemented I think):
# Set object pivot using cursor location
saved_location = bpy.context.scene.cursor.location.copy()
bpy.context.scene.cursor.location = (x * voxel_spacing / 2.0, y * voxel_spacing / 2.0, z * voxel_spacing / 2.0)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
bpy.context.scene.cursor.location = saved_location
Hmm, I wonder if there is a common way of handling the origin of imported models.
If the other import options all import it relative to (0, 0, 0), or to the cursor, it would be wise to follow suit.
Having access to the dimensions in the SIZE
will definitely make it straightforward; I could imagine a calculated offset of -x/2, -y/2, -z/2
being applied to each voxel for example, to result in centering upon the origin.
I've never thought about it but your reasoning makes sense!
I have an algorithm for coalescing cubes and removing interior faces in my importer.
How to reduce number of vertices/faces for "high voxels" models? How to speed-up objects roto-translations for new scene-graph structure?
Boolean modifiers (union)? Slow while setting up the scene in Blender and uncomfortable: you have to set a single modifier for each pair of "voxel" first, apply it to remove "merged" voxel then. Pay attention to multi-materials objects.
Join multiple objects/voxels: easy, fast, but it does not reduce number of polygons.