jesterKing / import_3dm

Blender importer script for Rhinoceros 3D files
MIT License
302 stars 38 forks source link

Feat/import blocks #45

Closed lfertig closed 4 years ago

lfertig commented 4 years ago

Support for Blocks

adds methods to import blocks from the 3dm file as collection instances. still experimental, raises several issues on how to deal with visibility states, structure of the main import loop, etc.

depends on latest git code for rhino3dm

detailed explanation

adds an option to enable experimental block import handler reads instance definitions from 3dm file and builds skeletal structure of collections for them importer catches instance reference objects and links them to their corresponding layers sorting method filters through objects and fishes out instance definition objects, to link them into their respective collections. this still needs to be integrated into the main import loop

fixes / resolves

Fixes #13

lfertig commented 4 years ago

I know, a lot of changes and additions in one pr, I'll try to avoid this in the future. I also added an "option" argument to be able to toggle behavior within the importer.

tsvilans commented 4 years ago

I'm happy to give my +1 to merging the change in converter functions, but I guess we need to wait for the rhino3dm update to address the rest. I see that InstanceDefinitions doesn't have many options in the current version (0.7.3)...

@jesterKing Still not sure how to file issues for rhino3dm (we probably can't directly?) but it would be great if the InstanceDefinition objects had a list of the involved objects, so we could just parse all the objects in the model, then the instance definitions and create those collections without iterating over the objects list again.

lfertig commented 4 years ago

InstanceDefinition actually now has a list of objects, returned as a list of guids by GetObjectIds =) . That was the first of the 2 PRs I mentioned. Well need to wait though until the next release.

Do you have any idea on how to improve the populate-method? I was wondering if it would be better to include this in the importer, but then i would need to loop through all instance definitions for every object.

tsvilans commented 4 years ago

@lfertig The Rhino Python and C# API have a ObjectTable.Find(Guid) method which would be perfect for this. If this was included in rhino3dm, then we could get the relevant objects just by using the Guid list. Perhaps something to push for on the rhino3dm side...

lfertig commented 4 years ago

Ahh you're right. I didn't think about checking the openNURBS code that it relies on... facepalm

/ Returns: True if id is in the InstanceGeometryIdList(). / bool IsInstanceGeometryId( ON_UUID id ) const;

There's also just a loop hiding behind it to fish out the id, but cpp should execute significantly faster and it would keep our function a bit less convoluted.

lfertig commented 4 years ago

The PR for the aforementioned InstanceGeometryIdList() just got merged into rhino3dm, will change the code and also adapt to the new read3dm()

jesterKing commented 4 years ago

I'm happy to give my +1 to merging the change in converter functions, but I guess we need to wait for the rhino3dm update to address the rest. I see that InstanceDefinitions doesn't have many options in the current version (0.7.3)...

@jesterKing Still not sure how to file issues for rhino3dm (we probably can't directly?) but it would be great if the InstanceDefinition objects had a list of the involved objects, so we could just parse all the objects in the model, then the instance definitions and create those collections without iterating over the objects list again.

You can create issues directly to https://github.com/mcneel/rhino3dm . It has been hooked up to the YouTrack system we use for our main bug tracking, so it will end up nicely also on the right plate.

tsvilans commented 4 years ago

It doesn't appear the File3dm.Objects has a FindById() function or anything like that.

To avoid crawling the object table twice, we can go over it once and build a dict that has the GUID as a key and a reference to the Blender object as a value. After we go over the object table, we can use the dict to find the objects for our Collections for InstanceReferences and groups, then get rid of it.

lfertig commented 4 years ago

File3dm.Objects doesnt, but the Rhinocommon object table does. Following its tracks I found that the underlying ONX_Model, that the ObjectTable is based on, has a method ComponentFromId(). This is already used in the bindings to implement the FindId() method for the InstanceDefitionionTable. I'll have a look...

Right now I'm doing it the other way around though, checking all instance definitions while importing the objects if the current guid is part of the definition.

lfertig commented 4 years ago

I'm a bit undecided about how the hierarchy structure performs in blender. In order to get a clean scene you have to hide the instance collections and everything in side. If you then want to hide some layers, you have to viewport disable them, to toggle them. I wonder if there's a better way to handle this..