Count curve length in layer

Hey there!
I working on a script for curve length measure.
I need to select layers by names, measure length and than create text object with that values.
I have 4-5 layers names (more or less) and if the file don’t have any of those layer script should select next one.

For now I use “rs.ObjectsByLayer” by it gives me an error if there are wrong layer name.

import rhinoscriptsyntax as rs
#rs.ObjectsByLayer("thru-cut", True)
object = rs.GetObject("Select a curve")
if rs.IsCurve(object):
    length = round(round(rs.CurveLength(object))/1000,2)
point = rs.GetPoint("Pick point")
Cut="Cut-" + str(length) + "m"
if point:
    rs.AddText(Cut, point, height=10.0)

Hi Maxim
I hope this help you.
————NARUTO
``import rhinoscriptsyntax as rs
objects = rs.ObjectsByLayer(“thru-cut”)

for object in objects:
if rs.IsCurve(object):
length = round(round(rs.CurveLength(object))/1000,2)
point = rs.GetPoint(“Pick point”)
Cut=“Cut-” + str(length) + “m”
if point:
rs.AddText(Cut, point, height=10.0)``

1 Like

Hi Maxim,

If you might pass a layer that does not exist, first test for its existance with rs.IsLayer()

HTH

  • Willem

Thank you.
There are some problems. The script gives me 8 text blocks if there are “thru-cut” layer
it gives lenth for all objects in that layer seperatly
And it gives me an error if there are no “thru-cut” layer (for example I’ve create thru-ct)

As @Willem suggested, you should verify that the layer exists using rs.IsLayer before calling rs.ObjectsByLayer.

For example:

import rhinoscriptsyntax as rs

layer_name = "thru-cut"
if rs.IsLayer(layer_name):
    
    length = 0.0
    object_ids = rs.ObjectsByLayer(layer_name)
    
    for obj_id in object_ids:
        if rs.IsCurve(obj_id):
            length += round(round(rs.CurveLength(obj_id))/1000,2)
            
    if (length > 0.0):
        point = rs.GetPoint("Pick point")
        if point:
            str = "Cut-" + str(length) + "m"
            rs.AddText(str, point, height=10.0)

Thank you, It works pretty good.
Now I’ve made a list of layer names, and a loop for
summarizing theme all. But I have layers with changing name. For example layers “cut-d5-5” ,there is “cut” constant part of the name. How could I select these layers even if there are some common names like “cut-d5-5” and “cut-d3-6”

Or is there a way to get a list of layers in working file?

Something like

if "cut" in layername:
    #do something

or

if layername.startswith("cut"):
    #do something

To get the entire list of layers - rs.LayerNames()

HTH, --Mitch

Thanks, finaly I’ve got working script. There are some things I want to add. For example I want to place the text above the objects. I use rs.BoundingBox(obj_id) command but have no idea how to get point coordinates. How can i get coordinates of bounding box coners ?

rs.BoundingBox() returns a list of 8 3d point objects, starting from the lower left corner and going counterclockwise first along the bottom, then along the top. If the object is planar and parallel to the bounding box plane, the second four will be identical to the first four. You can access the individual point coordinates using several methods:

if pt is the 3d point object -
coords=rs.PointCoordinates(pt) - gives you a list of 3 numbers [x,y,z]
pt.X or pt[0] gets you the X coordinate of the point
pt.Y or pt[1] gets you the Y coordinate of the point
pt.Z or pt[2] gets you the Z coordinate of the point

Note however that you may not need to deal with the individual coordinates, as most rhinoscriptsyntax methods dealing with placement of objects etc, will accept 3d point objects directly.

HTH, --Mitch

Thanks again. Work preaty good!
Here is the part

bobject=rs.AllObjects()
bb=rs.BoundingBox(bobject)
text_plane=bb[3]
#Text height
#kegl=(bb[3]-bb[1])/10
TextObject=rs.AddText(Text,text_plane, height=10)

But i have no clue how to do math calculations with points. Is bb[3] a string ?
I want to make text height=kegl

3d points are python objects. As objects, they have both properties and methods. Properties are things that are intrinsic to the object, like a point’s coordinates. These are addressed by the format object.Property, for example pt.X, pt.Y or pt.Z. Methods are generally operations you can do with the object. In the case of point objects, there aren’t too many methods, but there are things like ptA.DistanceTo(ptB). Methods use parentheses, properties do not.

Another method that works with point objects is the inherent ability to add and subtract them. The result of subtracting one point from another for example results in a vector. It’s also possible to multiply and divide points and vectors by a numerical value - which is the equivalent of scaling.

So, if you write vec=(bb[3]-bb[1]), you will get a vector that is in the direction from bb[1] to bb[3] with the magnitude that is the distance between the two points. If you need a number, not a vector for text height, you would either need to get the length from the vector using L=vec.Length, or simply use bb[3].DistanceTo(bb[1]) or even rs.Distance(bb[3],bb[1]) to get the distance value as a number directly.

HTH, --Mitch

Thanks. It helped me alot.
And is there any way to use rs.DocumentName() working for any others file types
except 3dm?