Exporting Block instances as meshes

Hello,

I am writing a rhino plugin to export the rhino file to my viewer, I am able to get the meshes which are polysurfaces in rhino but block instances are missing. How Can I export block instances as meshes.

I am trying to convert block instance objects to meshes, but I am not able to get the meshes.

Here is my code.

// Set up objects and object iterator
	ON_SimpleArray<const CRhinoObject*> allObjects(256);
ON_ClassArray<CRhinoInstanceObjectPiece> piece_list;
  CRhinoObjectIterator it(rhinoDocument, CRhinoObjectIterator::undeleted_and_idef_objects, CRhinoObjectIterator::active_and_reference_objects);
	it.EnableVisibleFilter();
	const CRhinoObject* currentObj = 0;
	for (currentObj = it.First(); currentObj; currentObj = it.Next())
	{
		
		if (currentObj->ObjectType() == CRhinoObject::instance_reference)
		{
			const CRhinoInstanceObject* iref = CRhinoInstanceObject::Cast(currentObj);
			if (0 != iref && iref->IsMeshable(ON::any_mesh))
			{								
				iref->Explode(piece_list, true);
			}			
		}

for (size_t i = 0; i < piece_list.Count(); i++)
	{
		allObjects.Append(piece_list.At(i)->m_object);
	}

// Store the meshes in a custom array
	ON_ClassArray<CRhinoObjectMesh> meshes(allObjects.Count());

	// Get all the mesh objects into meshes array
	CRhinoCommand::result res = RhinoMeshObjects(allObjects, mesh_parameters, mesh_ui_style, meshes);

There is no meshes in the array.

Need help.

The block is only the instance. You have to get the geometry from the

iref->InstanceDefinition()->GetObjects(objs);

From this objs you can get the meshes (if there are meshes in the block).
Don’t forget to apply the instance transformation. :wink:

If you are solely interested in mesh geometry and materials for your model you could also implement a changequeue. This will handle converting all objects, including block instances (and nested ones). Although the changequeue was originally conceived for realtime display integration it can be used for exporting purposes as well.

Hi @dsw ! I am interested in getting the meshes from block instances too.
So, what exactly do you mean by applying “instance transformation” ?
Currently, I am getting the sub-objects from an instance, but my problem is that if the block is duplicated, all the subobjects have the same ID, and all the subobjects get the same mesh.
I have explained my problem in detail in here:


Please look into it, if you have the time.
Thank you !

hi @alexian007, i think you do not understand the behavior of blocks? Of course you get the same mesh for all copies of your block instance. because you have the same block definition.
You have created one block definition, which is used 2 times in your case. This is represented in the Rhino document as an instance. The instance more ore less just holds a transformation and which block definition. Not like other rhino objects it does not have geometry itself.

Therefore if you want to “explode” the blocks you have to get the block definition geometry, apply the transformation from the first block instance and add it to the document. Next get again the definition geometry apply the transformation of the second instance and add to document.

Hope i explained it in a way you understand.

Hi @dsw, thank you for the quick and helpful reply :slight_smile:
So, I have a few questions regarding this:

  1. How will I get the block definition geometry? Please guide me to the method that does this. I did found this one for C++, is this suitable?
    https://developer.rhino3d.com/api/cpp/class_c_rhino_instance_object.html#aae00378d1f913e64dd1b7d826bd7cac7
    I will be glad to take a look at any other sources too.

  2. If I explode the object with block definition, will it automatically add the exploded objects into the document ? There is a function Explode() in C++ API which will let me explode the object into its pieces, but I am not sure if it will add it in the document or not. How did you do this when you faced this type of situation?

So, I think I did get the way you have explained. I understood it this way:

  1. Find out which objects in the document which contain block definition.
  2. For those objects, get their block definition geometry.
  3. Apply the transformation of the parent object (block instance) in the block definition.
  4. Add the block definition into the document as an object.
  5. Repeat for all block instances.

Did I get that right?

Again, thank you so much for taking your time to explain this to me.

hi @alexian007,

for question 1, use this method of the CRhinoInstanceObject:

ON_SimpleArray<const CRhinoObject*> objs;
iref->InstanceDefinition()->GetObjects(objs);

for question 2, no i would not expect that the C++ API does add the exploded objects to the document.

for the step by step explanation: i did not mentioned it but logically you have to make duplicates (between 2 and 3) of the definition geometry to apply the transformation.