I am developing a Plugin to read Rhino Files within vvvv gamma.
As most of it is working, I get some strange behavior from some Meshes.
Starting with closed object (Brep or Mesh) it seems to work almost fine, if I use transparency you can see that it also looks like every second face is flipped.
Having non solid objects, the face culling does not seem to work properly. Having culling set to “none” the meshes still are only visible from one side.
Are there any bugs related to this topic or am I the bug? I am converting non planar quads to triangles and quads to triangles and use “ToIntArray” to get the indices.
I am developing a Plugin to read Rhino Files within vvvv gamma.
Can you post the code?
It appears to be an issue with some individual face normals flipping, or a problem with the triangle indices order/ face winding order. I don’t know if this is a pre or post export or on import issue. Are you importing the 3dm file directly inside vvvv app? If yes then how was the mesh created inside Rhino? Have you tried importing an OBJ file exported from Rhino? I would check the face normal directions in Rhino to be sure and try importing the Rhino mesh in another app like Blender.
Why not OBJ or something else instead of 3dm directly?
I use the 3dm format in my custom projects but I don’t generate meshes from the 3dm I use OBJ for mesh importing and the 3dm format to access Rhino/Grasshopper data like layers, identifying brep edges, faces, vertices, etc.
Your plugin can:
- ask for a .3dm file
- export the 3dm to a format VVVV supports
- then you import the generated file into VVVV
- After the file is imported into VVVV you can still access the 3DM file via your plugin and do stuff in VVVV with Rhino data.
Another possibility is the VVVV rendering api/engine has a quirk to be solved. I recently started to learn VVVV but am not familiar with the api.
If you really want or need to write a custom importer/exporter based on 3dm and not use an intermediate format, I would view how other importers/exporters work inside vvvv. You’ll need to translate from 3dm to vvvv so it would help to view how it’s done by other vvvv supported api’s.
The links below may help:
thank you very much for your effort. I am mostly aware of the things you posted. But always helpful to rethink some things.
I want to achieve a more straight forward workflow. For sure it is possible to choose another format to export to and import in to vvvv. But as I am working quite a lot with both of them and having projects that are on the one hand physical (building real objects with the help of Rhino) and on the other hand digitally enhance those projects (Projection mapping, light control, using displays and having interaction) It is quite helpful to work with only one file on both sides. Also it is possible to get much more useful information out of the file/geometry, that can will get lost in conversion.
So speaking of this, most of it is working, and its already useful. If you do not use transparency e.g. most of the objects look as they should. But it seems like something minor is not as it should be.
For the conversion I use the Rendermeshes of the geometry if it is not a mesh already. They exist for all objects, that have been displayed in Rhino in any other way than Wireframe display.
So my question would be, how is the order of vertices and face indices and of those rendermeshes and is there a difference to regular meshes. I cannot find the right documentation for it.
Its a bit difficult to post the code, cause it is “written” fully in vvvv.
Maybe somebody understands…
You can find the repo here:
Render Mesh is the mesh representation of an object. It is used when exporting to mesh formats like obj. You can set in the document properties your preferred render mesh quality or set it during export. If you want the highest quality or have some control over the mesh settings you can choose the custom render mesh option. The custom render mesh option will bypass the “Polygon Mesh Options” dialog. So in other words there is no difference. The render mesh represents what will be exported, It is created from the model itself. You may need to generate new UV’s and unwrap the model after every change made. Not sure how vvvv handles UV’s and materials but this may be an area to review.
I attached images which show some render mesh related settings. You can use the render mesh and other mesh tools to rebuild a mesh. This gives you control over the final mesh topology and can help when importing into vvvv. Exporters have different features so some things may not export as you would expect. This may include how vvvv handles meshes.
But it’s important to mention the face normals, ordering, winding sequence matter for uv, texturing, materials, uvw space, translation, and other similar functions. These are mostly rendering-related issues and not structural as you said it works otherwise. I’ll need to review your network but I think the Rhino3dm API is correct. I didn’t have a problem when I was experimenting with it and WPF 3D the API is straightforward. I believe you can use any order as long as you haven’t modified the mesh and it doesn’t have any problems in Rhino otherwise it shouldn’t matter. But if the normals are flipped it is likely a mix match in your code, a bug in the Rhino3dm library, or a problem with the input geometry. I think you may have a simple inversion or order-of-operation problem because you do need to be careful and structure things in the order the API expects so the Rhino3dm lib and vvvv may implement winding order and normals Clockwise vs Counter Clockwise or something like that.
You can do a lot with Rhino mesh tools:
- unify normals
- merge faces
- merge coplanar faces
- reduce mesh
- welding commands
- ngons commands
- quad remesh
Then you can export the mesh with your modifications. Rhino’s exporters can be tricky and I often have to make adjustments to the mesh topology before exporting. Lots of trial and error. For instance, I use Blender for visualization and some faces need to be ngons or the mesh will be harder to work with, especially with complex dense geometry that you plan to UV unwrap and texture so the mesh topology is important.
You want a tight integration with Rhino and vvvv. I was trying to say, you can use only one format the .3dm file. It is common to sometimes use an intermediate/temporary format or data structure when translating from one system to another. You don’t have to work directly with the intermediate/temporary format, you do so in a file or in-memory in the background even asynchronously. You then do as you wish with the .3dm file in vvvv. The benefit of this is you will always be sure the model will import correctly since you’re using a format supported by vvvv or any host app. Again this would all happen in the background, during normal usage you will only load the .3dm file your plugin does all the work. Another benefit is that you can have Rhino open and make changes while vvvv is also open. I don’t know how vvvv handles threading/processes but because you’re loading the .3dm geometry from a temp file or in-memory in the background and separately Rhino and vvvv running processes won’t be locked allowing you to use both apps at the same time. A hot reload-like feature with non-blocking realtime updates. I do this in a Solidworks project where I do stuff then export step files automatically and import them in Rhino/Grasshopper and do more stuff. I make changes in Solidworks on saving Rhino/Grasshopper reloads files. I don’t work with any step files, after Rhino imports the files they’re deleted automatically. I built similar systems for SolidEdge, Alibre Design, and my own custom tools. It all happens asynchronously in the background ( but I don’t think it needs to be async because it all works fast as is but I made all functions background workers just in case ).
You’re not losing any information. The conversion is from Rhino to a supported vvvv 3D format. The temp file/in-memory option is only loading geometry. There will be some translation done as I see in your file from Rhino data structures to vvvv types. Using vvvv supported 3D formats is handling the translation step for you. You still have access to the Rhino/Grasshopper data in the .3dm. My plugin for Solidworks does all kinds of checks, brep edge and id selection for holes all inside Solidworks loaded from a .3dm file. I don’t even need Rhino installed for many of my functions. The temp file/in-memory setup can happen entirely in the same process as the host app ( Solidworks ), out-of-process using COM, or using RhinoScript. I also have setups that work from the command line only without opening or showing the host app or Rhino window.
Sidenote: SolidWorks has support for 3dm files but my plugin does more with Rhino/Grasshopper data.
I’ll look over vvvv docs and see how it handles geometry. I understand you want to have everything coded from vvvv with only .3dm. This option has its benefits and I too sometimes have to write custom 2D/3D readers/writers. But only for performance reasons, experiments, TCP streaming geometry, or similar tasks. Existing 2D/3D formats are very stable and used across industries. I prefer the intermediate format / in-memory option because It gives me a simpler, more reliable workflow that is easy to code and can be applied to all the 3D apps I use without needing to write a custom importer/exporter implementation for each one.
You may know all of this, I’m just brain-dumping to be clearer I hope.
Fyi, these are some important classes I remember.
is also useful and can help work out mesh construction and deconstruction.
Hi Stephen, thanks again for you effort.
Maybe there is a little misunterstanding. I am working with Rhino and Rhinocommon quite a lot and I am asking this in the Rhino Developer / Rhino3dm section. There is no need to explain all this basic stuff. And for sure I know most of the docs related to this. My question might have been not precise enough, I am sorry for that.
Not sure if I fully understand your explanation in the first paragraph but this seems not to be true, custom render mesh settings do not bypass the polygon mesh options dialog, when exporting to a different format.
Yes, for sure this has to do with normals, ordering, winding… thats why I am asking if there are any differences between those meshes or known bugs related to this in Rhino3dm Nuget…
For the plugin the goal is not to have a “tight integration” between both, this would be Rhino.Inside. I am developing this as well, but first wanted to have a simple file reader. Meant for a consistent and easy workflow (Also working if you do not have a Rhino License → Working in Teams with different tasks). And I can surely reuse all the conversions. Speaking of this, your way seems quite interesting, but I do not see the need, for this overhead of double conversion (e.g. Rhino Mesh → Some kind of Mesh → vvvv (or Stride) Mesh) Especially if it would be a “live” connection between both.
You also have to understand this plugin is not solely for my own workflow, but meant to be a help to everyone working in this kind of field.
I hope this clarifies, thanks again for your input.
Meanwhile it seems that this is a bug on the vvvv side.
I don’t think this issue is in rhino3dm. It looks like it may have to do with how you are handling quads in meshes based on the image you posted. Have you tried converting your mesh to be entirely triangles? Maybe vvv doesn’t like quads?
Yes, I did, vvvv does not like quads.
Also tried flipping the face winding and so on…
I right now think there is some issues with the materials I am generating from the material of the object. But seems to be a problem on the vvvv side.
Another question for me would be, why there is no GetMesh() for a RhinoObject in Rhino3dm?
I saw a c++ example (From McNeel) for the use of Rhino3dm, where there is a GetMesh() function for a Brep like you still have for extrusion. But right now there is only a GetMesh() for the BrepFace. Will this change in the future?
We always keep meshes as one per face in brep. Whatever function you saw would just be making a joined copy of all of these meshes.
Ok, I understand much more. I use the geometry3Sharp library in between e.g. .3dm and the host app or format. I write interface/wrappers around those libraries in my own lib. geometry3Sharp has a wide range of meshing tools that Rhino3dm, RhinoCommon, and other CAD APIs don’t have.
I was talking about the polygon mesh options dialog being bypass/not shown for .obj format when you select the “Use render meshes option” check box when exporting to obj.
I struggle with idea overload, so maybe I didn’t get it exactly right.
Use render meshes
Enable to export objects with document mesh settings. Polygon mesh export options will not display. Object custom meshes will save to the OBJ file.
Disable to export objects with the polygon mesh export options. Object custom meshes will not save to the OBJ file.
So RhinoObject.GetMeshes Method (from Rhinocommon) this just does the same as if I cycle through the BrepFace Meshes? Still would make it easier and somehow more consistend if every object as this function, or not? A mesh would just return itself e.g.
But anyway as I am using the Brep as it is for other functions, i still cast it as such. But there would be no need if can directly get the mesh from a Rhinoobject.
Rendermeshes: Ah I see. Ok, to be fair it is not standard
I get your point with geometry3Sharp. Having additonal meshing options could be interesting.
But this is still not the idea behind this workflow.
It would also be possible to integrated geometry3Sharp in vvvv, then you could use it also for vvvv generated stuff. This would make more sense to me.
I would export several different obj files with different render mesh, poly count and topology e.g. triangles, quads, and QuadRemesh versions. This will allow you to see how vvvv renders them. It may also be a good idea to export other formats to see what happens, using the same geometry/file from Rhino. If they import and render correctly then your VL.Rhino.3dm.vl.dll code may be the culprit.
The Rhino3dm and RhinoCommon libraries don’t have crystal clear mappings between them. So I use them separately not intermingling classes, properties, and functions. I believe the intent is for the Rhino3dm library to be used completely as a standalone .3dm library for your custom app 2D/3D format. Problems arise when you’re thinking of Rhino/RhinoCommon but are trying to use Rhino3dm.
I think RhinoObject.GetMeshes() returns an array of meshes from your objects in the rhino file. This is what renders and handles meshing calculations like in the Rhino GUI. It is the polygon mesh ( a geometry type that is defined by vertices and faces) for a RhinoObject. There is also the GetRenderMeshes method which is what I was talking about earlier but in the Rhino GUI. It will either use the document settings or you can change meshing parameters in your code. Some of these methods and classes are used only for calculations. You then use the results to do more work e.g. ( using it with the geometry3Sharp lib).
BrepFace.GetMesh() is an array of meshes from a BrepFace ( surface and trim curves ) not the entire rhino object in your rhino file. It is the brep face ( surface or polysurface ). But if you’re simply trying to import all your objects in your rhino file, you can just stick with the Rhino3dm meshing classes.
I’m confused, here are some scenarios:
- To import rhino file as a vvvv rendered 3D model. Using the .3dm the same as .obj, .fbx, etc. Models and Meshes | vvvv gamma documentation
- Have read-only access to the low-level Mesh and Brep data ( edges, faces, vertices, surfaces ) in the rhino file.
*Have complete access to the low-level Mesh and Brep data ( edges, faces, vertices, surfaces ) in the rhino file and create geometry inside vvvv as Grasshopper does.
*Have complete access to Rhino/Grasshopper from vvvv ( Rhino.Inside ).
These are all valid and I’m not saying pick one over another. I was thinking in terms of file importing and exporting. In fact, you said you want a simple reader. But from what your VL.Rhino.3dm.vl has in it you don’t want to only import/read the .3dm. You want to access other Rhino data.
vvvv is s polygon mesh-based engine (based on Stride) breps won’t render as in Rhino unless you implement it yourself. As seen in your 3D image that is a polygon mesh. Do you want to access brep faces, edges, or vertices? How do you plan to use this information? What data will you query? What data will you change or save? To contrast this with to my Solidworks plugin for 3dm it has brep support because SolidWorks is a Brep kernel. But my little WPF/Helixtoolkit 3dm importer does not, it generates a polygon mesh from the Rhino file to render. My code for polygon mesh based geometry is much simpler than the code for brep based geometry.
The Blender 3dm importer may be useful to peek into. It uses Rhino3dm.py and I think the way it’s structured is straightforward. The rendermesh.py file in particular is a good reference.