Trying to access mesh in an Instance

I’m trying to access a geometry inside an instance, i can’t seem to find a way to get anything from instance.Geometry apart from : “AttributeError: ‘InstanceReferenceGeometry’ object has no attribute ‘Vertices’”

def CreateCutters(self):
    rc, obj_refs = Rhino.Input.RhinoGet.GetMultipleObjects(
        "Sélectionnez les pierres pour y ajouter les cutters", False, Rhino.DocObjects.ObjectType.InstanceReference)

    if rc != Rhino.Commands.Result.Success or not obj_refs:
        return

    cutter_ids = []
    
    for obj_ref in obj_refs:
        rhino_obj = obj_ref.Object()
        
        gem = rhino_obj.Geometry
        gem_vector, gem_size, gem_center = StoneFinder.get_gem_info(gem)
        print(gem_center)
        print(gem_vector)
        print(gem_size)

        plane_start = Rhino.Geometry.Plane(self.center, self.normal)
        plane_end = Rhino.Geometry.Plane(gem_center, gem_vector)
        orient_transform = Rhino.Geometry.Transform.PlaneToPlane(plane_start, plane_end)

        cutter_id = self.Cutters()

        sc.doc.Objects.Transform(cutter_id, orient_transform, True)
        scale_transform = Rhino.Geometry.Transform.Scale(gem_center, float(gem_size))
        sc.doc.Objects.Transform(cutter_id, scale_transform, True)

        cutter_ids.append(cutter_id)
    if cutter_ids:
        sc.doc.Groups.Add("Cutters Group", cutter_ids)

    sc.doc.Views.Redraw()

Hi @Yves_Gobinet,

You might want to include a sample .3dm file.

Thanks,

– Dale

There is the sample, thanks for the fast reply.
Sample.3dm (1.1 MB)

Hi @Yves_Gobinet,

Your code doesn’t include StoneFinder.get_gem_info. What does it to?

– Dale

Hi @dale,
Sorry for the late reply, get_gem_info check some vertices of the stone mesh and return size, normal vector and center point of the mesh.

import Rhino
import scriptcontext as sc
import rhinoscriptsyntax as rs

def get_gem_info(mesh):

    index5, index6 = 231,191
    index7, index8 = 59,19
    index9, index10 = 105, 145

    intermediate_point1 = (1 - 0.5) * indexToPoint(mesh, index5) + 0.5 * indexToPoint(mesh, index6)
    intermediate_point2 = (1 - 0.5) * indexToPoint(mesh, index7) + 0.5 * indexToPoint(mesh, index8)
    intermediate_point3 = (1 - 0.5) * indexToPoint(mesh, index9) + 0.5 * indexToPoint(mesh, index10)

    center_point = (1 - 0.5) * intermediate_point1 + 0.5 * intermediate_point2
    gem_size = intermediate_point1.DistanceTo(intermediate_point2)
    gem_vector = calculate_vector_from_points(intermediate_point3,center_point, intermediate_point1 )
    print(gem_vector)
    print(gem_size)
    print(center_point)
    
    return gem_vector, gem_size, center_point

def indexToPoint(mesh, index):
    vertex = mesh.Vertices[index]
    point = Rhino.Geometry.Point3d(vertex.X, vertex.Y, vertex.Z)
    return point

def calculate_vector_from_points(point1, point2, point3):
    vector1 = point2 - point1
    vector2 = point3 - point1

    normal = Rhino.Geometry.Vector3d.CrossProduct(vector1, vector2)

    if normal.IsValid and normal.Length > 0:
        normal.Unitize()
    return normal

To access a mesh inside a block instance you need to first ‘drill into’ the block instance.

With a block instance in rhino_object you’d do something like:

idef = rhino_object.InstanceDefinition
idef_objects = idef.GetObjects()
for ob in idef_objects:
    gem = ob.Geometry

Hi @nathanletwory
Unfortunately, this solution gives me the mesh of the block reference rather than the mesh of the selected block instance.

If you need the vertices in the space of the block instance you need to apply the InstanceXform.

I don’t know of a function that gives instance geometry transformed into the block instance space. @dale am I missing something

1 Like

It works !
Thank you so much for your help @nathanletwory and @dale