HI,
I am trying to select specific curves by using their area centroid, which is basically three coordinates.
Ive managed to obtain these coordinates using bounding boxes, given these curves are not sitting on cplanes.
However i cant seem to select specific curves by using just the z coordinates. Basically i can put them into lists based on length etc, but not sure how to work with coordinates. Here are my current notes
from Rhino.Commands import Result
from Rhino.DocObjects import ObjectType
import rhinoscriptsyntax as rs
from scriptcontext import doc
layer_objs = rs.ObjectsByType(4,True)
if layer_objs:
#create an empty list
mylist=[]
for obj in layer_objs:
#find curves among the objects
if rs.IsCurve(obj):
if abs(rs.CurveLength(obj)<100):
#curve meets selection criteria, append to “good” list
mylist.append(obj)
rs.UnselectAllObjects()
#bBox = rs.BoundingBox(mylist[0])
#CURVE1
#rs.UnselectAllObjects()
for i in mylist:
bBox = rs.BoundingBox(i)
cent = [(bBox[0][0] + bBox[6][0])/2,(bBox[0][1] + bBox[6][1])/2,(bBox[0][2] + bBox[6][2])/2]
print cent
rs.AddPoint(cent[0],cent[1],cent[2])
newlines = rs.SelectObjects(mylist)
if newlines:
s=[]
for line in newlines:
if rs.IsCurve(line):
if abs(cent[2]< -11):
s.append(line)
rs.UnselectAllObjects()
rs.SelectedObjects(s)
I keep getting the error: expected an indented block.
Help would be appreciated, thank you.
@ZKislost, based on the other example using the length to filter curve objects, you can use a custom function definition to perform the filtering using multiple variables. The example below filters out the curves which have a bounding box centroid.Z coordinate within min_z
and max_z
.
import Rhino
import scriptcontext
import rhinoscriptsyntax as rs
def MyFilterFunction(crv_id, min_z, max_z):
bbox = rs.BoundingBox(crv_id)
cent = (bbox[0] + bbox[6]) * 0.5
if cent.Z > min_z and cent.Z < max_z:
return True
else:
return False
def DoSomething():
curve_ids = rs.ObjectsByType(rs.filter.curve, select=False, state=1)
if not curve_ids: return
min_z, max_z = -10.0, 100.0
mylist = filter(lambda crv_id: MyFilterFunction(crv_id, min_z, max_z), curve_ids)
if mylist:
rs.UnselectAllObjects()
rs.SelectObjects(mylist)
DoSomething()
_
c.
1 Like
HI thank you so much for your response. When i tried using your code on my model however, it gave me no response. But no error either so im assuming its running. thought maybe the min and max z’s were off so i tried readjusting but nothing seems to be working. Also cent.Z doesnt work outside of this code… cent[2] wont accept < Z for some reason.
can you offer any advice
?
@ZKislost, can you upload your model ? Which Rhino version do you use ?
_
c.
ahh never mind, i just got schooled by my boss for haveing such crap coding knowledge… I last coded 5 years ago :") and only in basic C now im trying to work with python.
Anyway he said i was doing it all wrong to begin with and i need to store cent values in a list. the way im doing it it is reproducing the same cent value again and again, over riding my previous cent value. he said to store sent in a list then work with that. I so regret asking him for help but here is how he fixed it
from Rhino.Commands import Result
from Rhino.DocObjects import ObjectType
import rhinoscriptsyntax as rs
from scriptcontext import doc
layer_objs = rs.ObjectsByType(4,True)
if layer_objs:
#create an empty list
mylist=[]
for obj in layer_objs:
#find curves among the objects
if rs.IsCurve(obj):
if abs(rs.CurveLength(obj)<100):
#curve meets selection criteria, append to “good” list
mylist.append(obj)
rs.UnselectAllObjects()
centroid = []
for i in mylist:
bBox = rs.BoundingBox(i)
cent = [(bBox[0][0] + bBox[6][0])/2,(bBox[0][1] + bBox[6][1])/2,(bBox[0][2] + bBox[6][2])/2]
centroid.append(cent)
print centList
this should give me the list of all the cent values with which can work the max thing out? but as long as it uses cent [2] instead of z. so yeah
anyway, if that makes any sense ill leave that here. thanks for the help 
Well, some parts make really no sense, eg:
layer_objs = rs.ObjectsByType(4,True)
you’re getting objects by type and not objects by layer, so the variable name was kind of confusing to me.
if rs.IsCurve(obj):
that should not be required, your list can only include curves since you where collecting it by type=4 which is curve.
abs(rs.CurveLength(obj)
a curve length is a positive value, there is no need to get the absolute value from it.
cent = [(bBox[0][0] + bBox[6][0])/2,(bBox[0][1] + bBox[6][1])/2,(bBox[0][2] + bBox[6][2])/2]
i’ve shown this in my other example, you could make the calculation on the points directly, eg.:
cent = (bbox[0] + bbox[6]) * 0.5
you can do that all in one function as my example above. If you want to access the Z
coordinate of a Point3d
type object it must be uppercase not lowercase.
_
c.