SolidPtOn edit weird results

If I edit the left shape using solidpton, I get a very weird shape like the one on the right, or sometimes something else crazy.direct edit weird.3dm (450.1 KB)

Yep, I see that, thanks.

http://mcneel.myjetbrains.com/youtrack/issue/RH-29038

-Pascal

Hi @pascal
Here is another one; SolidPt movement creates bad surfaces.
22-10-13- solid points on bad geometry.3dm (4.6 MB)

Points are well aligned, without micro deviations. Moving the geometry close to world origin does not help. Reducing or increasing Tolerance does not help…

Ahh, you’re right, didn’t look close enough…

There seems to be a tolerance issue here, the front planar surface for example, while it selects with SelPlanarSrf, is not 100% planar. If you SetPt in Y (world) on that surface it starts to behave correctly.

There is a 0.04 difference in the Y coordinates of two of the corners:

After “planarizing” the 3 objects, it seems to work correctly:
22-10-13- solid points on bad geometry-planarized.3dm (7.0 MB)

This is getting more strange because that frame is created programmatically…

import rhinoscriptsyntax 

rectangle_pt = rhinoscriptsyntax.GetRectangle (mode=2, base_point=0, prompt1=None, prompt2=None, prompt3=None)
rectangle_open = rhinoscriptsyntax.AddPolyline (rectangle_pt, replace_id=None)

segment1 = rhinoscriptsyntax.AddPolyline (rectangle_pt, replace_id=None)
segment_pt = [rhinoscriptsyntax.CurveStartPoint (segment1), rhinoscriptsyntax.CurveEndPoint (segment1)]
segment2 = rhinoscriptsyntax.AddPolyline (segment_pt, replace_id=None)
rectangle = rhinoscriptsyntax.JoinCurves ( [segment1,segment2], delete_input=False, tolerance=None )
centroid = rhinoscriptsyntax.CurveAreaCentroid (rectangle)

#pt=rhinoscriptsyntax.AddPoint(centroid[0])
distance = rhinoscriptsyntax.GetReal(message='Thickness', number=50, minimum=None, maximum=None)

#rhinoscriptsyntax.GetReal ( message="Offset Distance", number=0.03, minimum=None, maximum=None )



#rectangle_offset = rhinoscriptsyntax.OffsetCurve ( rectangle, pt, distance) # problem is with offset curve
plane = rhinoscriptsyntax.CurvePlane(rectangle)
point = rhinoscriptsyntax.XformCPlaneToWorld([10000,10000,0], plane)
crv_1 = rhinoscriptsyntax.OffsetCurve(rectangle, point, distance, plane.ZAxis)
ac = rhinoscriptsyntax.CurveAreaCentroid(rectangle)
crv_2 = rhinoscriptsyntax.OffsetCurve(rectangle, ac[0], distance, plane.ZAxis)



curves = [rectangle, crv_2]
planar_surface = rhinoscriptsyntax.AddPlanarSrf (curves)




#rhinoscriptsyntax.GetReal ( message="Offset Distance", number=0.06, minimum=None, maximum=None )
print planar_surface

Offsetsurface = rhinoscriptsyntax.OffsetSurface (planar_surface, distance, tolerance=0.0, both_sides=False, create_solid=True)

print Offsetsurface

delete_objects = [rectangle_open, segment1, segment2, rectangle, crv_1, crv_2, planar_surface]

rhinoscriptsyntax.DeleteObjects (delete_objects)

Dunno, if I use your script, even at a start point of like 25’000,25’000 from the origin, the stuff looks pretty accurate and solid point /subobject editing in an axis-aligned direction seems to be fine.

If I use it and create some frame in the file I attached, next to the other , I always get bad result after editing.
So i create a frame , than switch solid points on, and if I move them on the X axes — it fails.

I think this still has to do with your distance from the origin of nearly a million units. If I use your original file with your script and I make a frame near the origin, I have no problem. It’s only when I make one next to your objects at around X -640,000 | Y -250,000 | Z +13,000 that I see this happening.

The distance from the World origin matters, not the distance from a Cplane origin.

Ok, so this is the conclusion:
When the geometry is created closer to World Origin, there are no small deviations that disturb Solid Point Editing.

Still frustrating if you ask me… Why is this happening? Can it be fixed?

uh, this is heavy knowledge … my programming skills are very, very bad.
Maybe you could implement a frame command? I’m also tired of passing this dodgy script around.

The script is fine near world 0. Something in it is causing this imprecision though, as just drawing boxes and making frames that far from the origin and then stretching them does not cause the problem. The script does seem kinda dodgy and overly complex for just creating a box frame. I’ll have a look tomorrow.

OK, so here are a couple of revised scripts, one using exclusively rhinoscriptsyntax (easiest to understand) and the other using some RhinoCommon mixed in. They both have comments. Making a frame at your far away location with those seems to be OK, nothing bad happens when stretching. Still not sure where the original introduced the rounding error.

import rhinoscriptsyntax as rs 

#encapsulate the script as a definition to allow graceful exit if aborted
def MakeFrame():
    r_pts=rs.GetRectangle(2)
    if not r_pts: return
    #create polyline - to close, the last point has to be same as first point
    rectangle=rs.AddPolyline([r_pts[0],r_pts[1],r_pts[2],r_pts[3],r_pts[0]])
    #tolerance is just to define a minumum input >0 in this case
    tol=rs.UnitAbsoluteTolerance()
    #get thickness value
    thk=rs.GetReal('Thickness',50,minimum=tol)
    if thk is None: return
    #get depth value
    depth=rs.GetReal('Depth',50,minimum=tol)
    if depth is None: return
    
    #create list of stuff to delete - put rectangle in list already
    to_delete=[rectangle]
    #cut the redraw
    
    rs.EnableRedraw(False)
    centroid=rs.CurveAreaCentroid(rectangle)[0]
    plane=rs.CurvePlane(rectangle)
    
    #make the offset curve
    offsets=rs.OffsetCurve(rectangle,centroid,thk,plane.ZAxis)
    #offsets is a list because it could contain multiple curves
    #in this case we know there will be only one so offsets[0] is what we want
    to_delete.append(offsets[0])
    
    #make planar surface from orignal frame and offset
    p_srfs=rs.AddPlanarSrf([rectangle,offsets[0]])
    #p_srfs is a list, as the function could return multiple surfaces
    #in this case, there will be only one, so p_srfs[0] will be what we need
    to_delete.append(p_srfs[0])
    
    #we need a line for the extrusion
    #trick: multiplying a unit vector by a value makes its lenth that value
    #trick: adding a vector to a point creates a new point,
    # located at the vector's length and direction from the orig point.
    # it's minus because we want to extrude in the -Z direction
    depth_crv=rs.AddLine(r_pts[0],r_pts[0]-plane.ZAxis*depth)
    to_delete.append(depth_crv)
    
    #extrude the surface to make the 3D frame
    frame=rs.ExtrudeSurface(p_srfs[0],depth_crv,True)
    #delete unneeded objects
    rs.DeleteObjects(to_delete)
MakeFrame()

The following is the equivalent using some RhinoCommon - the only thing that this does is allow you to create “virtual geometry” that is not added to the document and thus not have to delete it afterwards.


"""Going to use some RhinoCommon to avoid adding the construction elements
to the document during the process ad then having to delete them after."""
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

#encapsulate the script as a definition to allow graceful exit if aborted
def MakeFrame():
    rpts=rs.GetRectangle(2)
    if not rpts: return
    #create polyline - to close last point has to be same as first point
    rect=Rhino.Geometry.PolylineCurve([rpts[0],rpts[1],rpts[2],rpts[3],rpts[0]])
    #note - this defines the polyline curve, but does not add it to the document
    
    tol=rs.UnitAbsoluteTolerance()
    #get thickness value
    thk=rs.GetReal('Thickness',50,minimum=tol)
    if thk is None: return
    #get depth value
    depth=rs.GetReal('Depth',50,minimum=tol)
    if depth is None: return
    
    #trick - you can add, subtract, multiply and divide points
    #trick - averaging 2 opposite corner points of a rectangle gets its centroid
    centroid=(rpts[0]+rpts[2])/2
    
    plane=rs.CurvePlane(rect)
    #define the offset corner style
    cs=Rhino.Geometry.CurveOffsetCornerStyle.Sharp
    #make the offset curve
    offsets=rect.Offset(centroid,plane.ZAxis,thk,tol,cs)
    #offsets is a list because it could contain multiple curves
    #in this case we know there will be only one so offsets[0] is what we want
    
    #make planar surface from orignal frame and offset
    p_srfs=Rhino.Geometry.Brep.CreatePlanarBreps([rect,offsets[0]])
    #p_srfs is a list, as the function could return multiple surfaces
    #in this case, there will be only one, so p_srfs[0] will be what we need

    #we need a line curve object for the extrusion
    #trick: multiplying a unit vector by a value makes its lenth that value
    #trick: adding a vector to a point creates a new point,
    # located at the vector's length and direction from the orig point.
    # it's minus because we want to extrude in the -Z direction
    depth_crv=Rhino.Geometry.LineCurve(rpts[0],rpts[0]-plane.ZAxis*depth)

    #extrude the surface to make the 3D frame
    frame=p_srfs[0].Faces[0].CreateExtrusion(depth_crv,True)
    
    #finally, just need to add the frame to the document
    #don't need to delete anything because nothing was created in the process
    
    sc.doc.Objects.AddBrep(frame)
    #redraw the scene to see what was done
    sc.doc.Views.Redraw()

MakeFrame()
1 Like

Hey, @Helvetosaur , thanks!
I would for sure include it in Rhino as a frame command. Architects tend to use frames a lot for windows, doors, curtain walls, etc. geometry which is mostly rectangular…

Might be interesting to include with the solid primitive tools, as it is kind of a ‘rectangular tube’, and thus could work similarly to the (round) Tube command…

It is useful when its drawn like we did it, by specifying a 3point rectangle plus the Thickness and Height. Remember previous dimensions for those two inputs would be amazing.

Here you go…

MakeFrame.py (2.1 KB)

Threw in a YouTrack request:
https://mcneel.myjetbrains.com/youtrack/issue/RH-70782/New-feature-request-BoxFrame-command

1 Like

Cool, thank you, maybe it will go fast since you already wrote it :slight_smile:

Now the problem is, that deviations like this happen with Grasshopper baked geometry also.
Baked solids far away from origin do have small deviations and they get destroyed when edited…
What should we do in this situation?