RhinoDoc.WriteFile and IO related stuff

Hi. Never know who to pin to this kind of topic @pascal @dale @stevebaer ? I’d like to talk about this method as its behavior is different than description besides gives different results than usually expected.

At first glance description of it currently is wrong as it does NOT change the current document to saved document while -> https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_RhinoDoc_WriteFile.htm says that “Note, the active document’s name will be changed to that of the path provided” i guess its time to fix the description of it.

Now to the business why this command when providing WriteSelectedObjectsOnly=true with -> https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_FileIO_FileWriteOptions.htm is saving tons of unnecessary data i guess @Jarek is also fighting with it is it so hard to write only selected models materials to that file do i really need 200 others when I do that in complex scene? The only way of cleaning them is to reload and purging - I will certainly do it via File3dm so I would like to know at least if i should do only materials cleaning or there is more garbage kept?

Note: Don’t tell me i should use File3dm for writing/reading if I want fancy handling as there is no way to cast for eg. InstanceDefinition to InstanceDefinitionGeometry and without it there are always some parts missing in it (just as example)

Next differences in v5 and v6 - what is the purpose of showing in command prompt information that file was saved in v6 as this is done via code and it returns bool it should be up to developer if he/she wants to RhinoApp.Write shouldn’t it ?

Due to API - Write3dmFile vs WriteFile and also vs v5 WriteFile - i understand that v6 and v5 writefile is the same (ofc extended by v6 stuff) but what introduces Write3dmFile only that it auto adds extension or it should be v5 writefile and v6 writefile description is good but behavior bad?

I struggle more than a two weeks with proper saving selected assets from the opened file and loading them. Can someone prepare short example but COMPLETE of writing InstanceDefinition with all its properties/attributes etc. (without unnecessary garbage) to a file and reading it back?

Note: I am aware of this one but it is incomplete - API lacks URLs.

Sorry for wall of text about it but working with this IO is a real pain lately - maybe i just have weird needs.

Dear @dale is it possible to acquire information about what happens on copy/paste action? I’m aware that when file is copied it is written to tmp file and read back to buffer i managed to fetch those files on EndSaveDocument and inspected those - those as on copy action I get always two - one contains simple material second contains valid materials. Though the files still contain all unnecessary data (so i assume it is the same routine as write with selected only) most interesting for me is that on paste in new rhino instance I see exactly what I would like to export so only adequate materials to pasted model. As in tmp files there is still garbage i would like to know at what moment there are decisions made which materials need pasting - is it during buffer read (so basically IO operation - so i wont be able to reach it with API) or after reading and making some kind of hash equalities between existing imported and actually used materials?

I really need some answer and guidance on this as this is fairly important for the usability of my plugin.

I’m pretty confused on what to focus on in this thread. If I understood what you are trying to do, that would be a good first step.

Hi @stevebaer,

the end product of all operations in ideal conditions is a single model defined as a block with related materials for various renderers. The cornerstone for automated models library which supports material picking on load time for desired/auto-detected renderer.

Those models have to come in two variants (based on user needs):

  • first, fully-featured geometry inside this block (one 3dm file)
  • second, a proxy object in block which contains data for hot-swapping on render time by supported renderers (second 3dm file)

In ideal conditions it would also support relative paths for dependencies like texture maps so those models would be usable on any system right of the bat - ofc this one is limited by renderers API though with RenderMaterials access in File3dm maybe I would come with some nifty/nasty workaround.

My current workaround for this is far away from perfect and is like traveling to Mars visiting Andromeda… Only one workaround quasi working and fulifing some of above promises is doing other rhino instance automation using copy/paste actions and scripting (which takes years to execute - the copy as it is dependant on original model complexity) for doing export of such model and the only way back with import is running script ("_-Import… etc. without any control which material is read so last resort for this is bloating user file and picking materials after the import fact.

Does the above explain clearly what’s my goal?

Sorry, this still isn’t clear. It seems like you are trying to write a 3dm file that can be referenced as a block through code. There appear to be problems that I still don’t understand that are occurring when you try to write a 3dm file.

Is my summary correct?

Well not really as referencing aka linking won’t be able to solve material picking as original 3dm would have to change and then we end with embeding with bloating user file - eventualy could do hashset of existing and revert back to original state after imports but then i dont have option what to do for eg on duplicate (mat overwrite, use both or use existing) - it would be perfect if it would but rhino doesn’t have any material library format to keep several related in one file and from which materials could be picked on the fly and what’s more important default material format do not carry external engines data so useless in my case.

Exactly - actually lacking methods of handling various types of data on read/write in RhinoCommon via FIle3dm. One of those is the lack of URL param on writing 3dm at least one renderer use this to reference original model while the block is only a proxy. Next lack of ability to write/read RenderMaterials those are not materials and are kept as (I guess it was) plugin object in ON 3dm. Its kinda weird as Material is in general unwanted legacy thing and RenderMaterial is not accesible.

Then I tried directly to export the selected objects to 3dm file but it caused huge bloat in the exported file as I used a fairly complex model and i had more than 140 mats in file with a single model of a cube which actually didn’t had any material on it…

Other notes were just about some inconsistencies in API. Besides, there could be one method to cast InstanceDefinition to InstanceDefinitionGeometry and back especially that rhino already has this when reading 3dm on its own am i right?

I’m having so much trouble following here. Please help me focus on single issues that we can understand and improve upon.

What URL are you referring to?

From everything that I have read I think you are requesting the ability to write a 3dm file with a specific set of RenderMaterials that you control. Is this what you are attempting to do?

This one. - Though I think Dale fixed some part of it but last time I saw it on youtrack was pending for testing.

Very simplified but yes - write and read and pass to doc only what i truly need from it.

Will try to break whole thing down to individual pieces in the upcoming week - I can imagine it’s not that straight forward to understand as a whole concept.

Though in short it is like i want two write 3dm file with some object and for eg 3 render materials (for cycles, thea, vray) and later i want to import this object with material that is working for currently picked renderer - to be clear not swap on renderer change but just read desired one on import and apply it to object during import. As some object is always a block stuff just gets more complicated.

Dale implemented the addition of InstanceDefinition.Url and UrlDescription a few weeks ago. This functionality is in 6.27 which is in the release candidate phase and should be the official service release around June 23.