I have a huge collection of lines in Rhino forming a network. I would like to update their start and end points based on a list of new coordinates for their start and end points. So far I am deleting all line objects and creating new ones with the new coordinates given. All other attributes such as object name and colour should remain the same. However this is rather slow. How can I avoid creating new line objects but only updating their start and end points.
LineCurve has a property “Line” for access to the underlaying Line object. Line has the pleasant properties From and To which would do the trick for you. In C# it would look something like so:
var _linecurve = < your LineCurve >;
_linecurve.Line.From = < new point >; // or ...
_linecurve.Line.From += < offset vector >; // or ...
_linecurve.Line.From.X += < your x offset >; // or ...
_linecurve.Line.From.Y += < your y offset >; // or ...
_linecurve.Line.From.Z += < your z offset >; // or ...
// And ditto for your end points
_linecurve.Line.To = < new point >; // or ...
_linecurve.Line.To += < offset vector >; // or ...
_linecurve.Line.To.X += < your x offset >; // or ...
_linecurve.Line.To.Y += < your y offset >; // or ...
_linecurve.Line.To.Z += < your z offset >; // or ...
many thanks for your help. That sounded easy but I am missing a piece of the puzzle. My previous post was not very precise. The first thing I get is actually a bunch of curve objects (simple, straight lines in Rhino). So, my problem is how to “cast” them into LineCurves to make the modifications you suggested. The snipped below gets me all objects from a layer. As curve objects I can ask for their start and end points but how can I modify their start and end points without generating new curve objects??
rh_objs = sc.doc.Objects.FindByLayer(layer)
# global_start = Rhino.Geometry.Point3d(0., 0., 0.)
# global_end = Rhino.Geometry.Point3d(1., 1., 1.)
for rh_obj in rh_objs:
curve = rh_obj.Geometry
start = curve.PointAtStart
end = curve.PointAtEnd
# -> how to do something like this: curve.Line.From = global_start
# -> how to do something like this: curve.Line.To = global_end
Receive the “straight curves” as Lines instead. If they are Lines in Rhino, then they should come in as “Line” in your “curve” variable. Have you tried accessing the .From and .To properties directly from your curve variable, like so “curve.From” ? (It was you saying that you had “LineCurves” in Rhino… )
I’m not versed in Python and casting, but it seems to me that if you have Lines in Rhino, then they should come in as Lines in the script as well.
In any case, it is the Line type which has then .From and .To properties.
curve.From results in “Message: ‘CurveObject’ object has no attribute ‘From’”. So, I am getting the objects from the layer as curves but I still don’t know how to update their start and end points. To test the *.From / *.To I need to get them as or convert them to LineCurves. Does anyone have any ideas on this? Thanks!
The properties of the objects in Rhino show the following:
curve
ID: 67e2e785-3633-4e6f-91cd-bf6759df49da (375432)
Object name: e_396_280_0
Layer name: Layer 01
Render Material:
source = from layer
index = -1
Attribute UserData:
UserData ID: 563238F9-C201-411d-A7B1-13895A0317AD
Plug-in: Rhino
description: AutoPointsOn
saved in file: no
copy count: 1
Geometry:
Valid curve.
Line
start = (-233.19,217.437,0)
end = (-236.496,217.437,0)
domain = 0 to 3.30628
line length = 3.30628
Hm. In an image in the link I posted it looked like there were lines as well. But obviously I was wrong, sorry.
Then I know of nothing else but to create new Line objects based on the curves. But that would be slow if you have many curves.
You should look into C# instead. It’s not too different, only add some “;” to the line ends, and enclose code blocks with “{…}” (instead of indent) and… off you go!
We should consult @Helvetosaur or @piac or some other expert on Python on this.