Selecting object faces in python

Hi,

In Rhino it is possible to select a specific face on an polysurface (like on a box) and assign a material just for this face. The final result can be that the box has 6 different materials (one for each face). Is it possible to achieve the same operation with a python scrip? The only thing that i managed to do at this point is to explode my polysurface and assign a material to the newly created surfaces. The problem is when i join the surfaces together to recreate the polysurface, the materials do not copy on the new polysurface…

Hi @Julien_Labrie,

To select Brep faces, you can do something like this:

import Rhino
import scriptcontext as sc

def test():
    go = Rhino.Input.Custom.GetObject()
    go.SetCommandPrompt("Select surfaces")
    go.GeometryFilter = Rhino.DocObjects.ObjectType.Surface
    go.SubObjectSelect = True
    go.GetMultiple(1, 0)
    if go.CommandResult() != Rhino.Commands.Result.Success:
        return
    
    for objref in go.Objects():
        obj = objref.Object()
        face = objref.Face()
        if obj and face:
            print("Id: {0}, Face: {1}".format(obj.Id, face.FaceIndex))

test()

Also, here are some details in assigning per-face materials:

– Dale

Hi @dale

Thank you for the reply.
I already found this script in another topic and it works very well. But for the purpose of my needs, i need to skip the user input to get the object. To be more detailed, my script create a class “Sawnlumber” and a method “def Mod(self,start,end)” used to model wood members. When a create an instance, i want the script to iterate over all the faces of the newly created object so i can compare the normal vector of the face with the longitudinal vector of the object (wood member). With the result, i can determine if the face must be rendered with an end grain texture or a side face texture of wood…

import rhinoscriptsyntax as rs

class Wood(object):
	def __init__(self,b=38,d=89,start=(0,0,0),end=(1000,0,0)):
		"Instance attribute for wood members"
		self.b = b
		self.d = d
		self.start = start
		self.end = end

class SawnLumber:
	def __init__(self,**kwargs):
		Wood.__init__(self,**kwargs)
		
	def Mod(self,start,end):
		"This function create the 3D model of the member in Rhino"
		rs.EnableRedraw(False)
		start = rs.CreatePoint(start)			#Create a point object for start coord
		end = rs.CreatePoint(end)				#Create a point object for end coord
		vec = rs.VectorCreate(end,start)		#Creation of unitized vector of the member
		x = rs.VectorUnitize(vec)				#
		if rs.VectorCompare(x,(0,0,1))==0:		#
			rs.MessageBox("vectorcompare ok")	#
			y = rs.CreateVector(0,1,0)			#
		else:									#
			y = rs.VectorCrossProduct(x,(0,0,1))#
		z = rs.VectorCrossProduct(y,x)			#
		pt1 = start + self.b*y/2 + self.d*z/2 	#Modeling member
		pt2 = pt1 - self.b*y					#
		pt3 = pt2 - self.d*z					#
		pt4 = pt3 + self.b*y					#
		base = rs.AddSrfPt([pt1,pt2,pt3,pt4])	#
		line = rs.AddLine(start,end)			#
		membrure = rs.ExtrudeSurface(base,line)	#
		rs.DeleteObjects([base,line])			#
		
##########HERE I WANT TO ITERATE OVER THE FACES OF membrure
		membrure_faces = "A script that get the IDs of the faces  of membrure"
		for face in membrure_faces:
			normale = rs.SurfaceNormal(face,[0,0])		#obtiens un vecteur normal a la surface
			compare = rs.VectorCrossProduct(x,normale)
			if compare <> rs.CreateVector(0,0,0):
				rs.SelectObject(face,False)
				rs.Command("-_RenderAssignMaterialToObjects NL_face") :  #assign a side face texture
			else:
				rs.SelectObject(face,False)
				rs.Command("-_RenderAssignMaterialToObjects NL_end_grain")  #assign end grain texture

I begin to understand that i need to use RhinoCommon scripting to achieve more complexe operation. Is there some guide available about this?

Thank you!

Hi @Julien_Labrie,

It looks like you are not using Rhino.Inside, nor are you using CPython but just plain old Rhino Python. Is this correct?

– Dale

Hi @dale

Well it looks like i’m not really sure what i’m doing now :sweat_smile:

All that i know is that i write my script in the Rhino Python Editor and i use rhinoscriptsyntax to create geomtries. Am i missing something?

I’m not sure to understand what is Rhino.inside and how i can use it. If it is to be use within other programs like Revit, i have no need for that rigth now. But if there is a way to improve my skills in scripting and if i am using old stuff, i am interested in learning what i should do differently.

Thank you