Strange string issues

Hey, I’m making a little g-code parser that talks rhino geo in and outputs the code as the g-code alternate made for the ShopBot CNC (syntax is nearly the same).

I have two files, one a header and one a footer, which I combine with code that is parsed from the rhino geo. The parsed rhino geo is converted into a polyline (regardless of org. type) then to a nurbs crv and the control points are extracted, formatted, and returned.

the problem that I’m having is that when the geo is not a line/polyline the parsed string will not play nicely with anything! it will not concoct with anything, even itself. do I have an encoding issue? it is very strange… :worried:

attached is the folder

dev.zip (11.6 KB)

Hi Henry
… Not sure if that has anything to do with your script’s problem,
but I noticed in the call to Curve.ToPolyline() that:
maxAngleRadians is set to 5 radians,
maxChordLengthRatio is set to 0.0

HTH … cheers

Haven’t tried your code yet, but the question is why are you doing this? Once the geometry is “polylined”, there’s no reason to turn it back into a NURBS curve to get the control points. A polyline object is actually just a list of 3d points and you can parse it directly with something like

for pt in pline:
    txt+="bla bla bla..."

–Mitch

i think the crv to pline to nurbs pathway was derived from the rs.CurveEditPoints() command:

def CurveEditPoints(curve_id, return_parameters=False, segment_index=-1):
    """Returns the edit, or Greville, points of a curve object. 
    For each curve control point, there is a corresponding edit point.
    Parameters:
      curve_id = identifier of the curve object
      return_parameters[opt] = if True, return as a list of curve parameters.
        If False, return as a list of 3d points
      segment_index[opt] = the curve segment is curve_id identifies a polycurve
    Returns:
      curve parameters of 3d points on success
      None on error
    """
    curve = rhutil.coercecurve(curve_id, segment_index, True)
    nc = curve.ToNurbsCurve()
    if not nc: return scriptcontext.errorhandler()
    if return_parameters: return nc.GrevilleParameters()
    return nc.GrevillePoints()

This should theoretically work, correct? might not be the best way, but i’m not clear about why it isn’t away.

Mitch, I’ll try that line of code, though… I’ll keep you updated. might also save to a .txt file and then read it back see if that changes anything… this should be uber simple. :unamused: once this is done, i can get into the fun parts.

hmmm, i do see that, too… same this happens when i change the code to do it all through python (rhinoscriptsyntax) commands, though.

Yes - except here there is no need for something like edit points, all you need is the polyline points. Also - my bad - pline=crv.ToPolyline() returns a polyline curve object, not a polyline object (they’re different). So to get the points, you will need to convert it to a real polyline object with rc,pl=pline.TryGetPolyline(). (Beware, the function returns a tuple of a boolean success/fail plus the return value if there is one)

–Mitch

Seems to be generating code here for any arbitrary curve I tested - NURBS spline, circle, polyline, polycurve…

I changed the one section to the following:

    def pointList(self):
        # TODO enable options
        ang=Rhino.RhinoMath.ToRadians(5.0)
        crv = rs.coercegeometry(self.geo)
        plc = crv.ToPolyline(0, 0, ang, 0.0, 0.0, 0.01, 0.0, 0.0, True)
        rc,pline=plc.TryGetPolyline()
        if rc: return [pt for pt in pline]

Is there a specific reason why you are importing the header/footer file separately?

Edit: Other small remark - is there a reason why you are outputting 6 decimal places? Most CNC machines can do at most 3 (mm) or 4 (inch). Not sure a ShopBot can hold better than .001" or .01mm…

–Mitch

Hmmmm … the script seems to work on Windows:

'------------------------------------------------------------------------------
'SHOPBOT Router File
'Generated in Rhino by RhinoPyCAMer
'Sat Feb 14 18:41:48 2015
'
'Length of material in X = 10.000000
'Length of material in Y = 10.000000
'Depth of material in Z = 1.000000
'Home Position Information = Bottom Left Corner, Material Surface
'Home X = 0.000000 Home Y = 0.000000 Home Z = 0.000000
'Rapid clearance gap or Safe Z = 6.000000
'Units: IN
'
M3, 34.000000, 10.000000, 1.000000
M3, 34.363566, 10.000000, 1.510803
M3, 34.705404, 10.000000, 1.922363
M3, 35.027222, 10.000000, 2.240906
M3, 35.330729, 10.000000, 2.472656
M3, 35.617635, 10.000000, 2.623840
M3, 35.889648, 10.000000, 2.700684
M3, 36.148478, 10.000000, 2.709412
M3, 36.395833, 10.000000, 2.656250
M3, 36.633423, 10.000000, 2.547424
M3, 36.862956, 10.000000, 2.389160
M3, 37.086141, 10.000000, 2.187683
M3, 37.304688, 10.000000, 1.949219
M3, 37.734701, 10.000000, 1.386230
M3, 38.612793, 10.000000, 0.089844
M3, 39.079427, 10.000000, -0.546875
M3, 39.321960, 10.000000, -0.841797
M3, 39.571452, 10.000000, -1.113281
M3, 39.828512, 10.000000, -1.355469
M3, 40.093750, 10.000000, -1.562500
M3, 40.367778, 10.000000, -1.728516
M3, 40.651204, 10.000000, -1.847656
M3, 40.944641, 10.000000, -1.914063
M3, 41.248698, 10.000000, -1.921875
M3, 41.563985, 10.000000, -1.865234
M3, 41.891113, 10.000000, -1.738281
M3, 42.230693, 10.000000, -1.535156
M3, 42.583333, 10.000000, -1.250000
M3, 42.949524, 10.000000, -0.881165
M3, 43.329264, 10.000000, -0.443848
M3, 44.981283, 10.000000, 1.602051
M3, 45.426941, 10.000000, 2.090637
M3, 45.885417, 10.000000, 2.531250
M3, 46.356588, 10.000000, 2.904480
M3, 46.596896, 10.000000, 3.059761
M3, 46.840332, 10.000000, 3.190918
M3, 47.086881, 10.000000, 3.295525
M3, 47.336528, 10.000000, 3.371155
M3, 47.589256, 10.000000, 3.415382
M3, 47.845052, 10.000000, 3.425781
M3, 48.103900, 10.000000, 3.399925
M3, 48.365784, 10.000000, 3.335388
M3, 48.630689, 10.000000, 3.229744
M3, 48.898600, 10.000000, 3.080566
M3, 49.169502, 10.000000, 2.885429
M3, 49.
END

Maybe a Mac problem …

Have you tried to draw the polyline obtained from the curve into Rhino ?

Hang on, I’ll give it a shot on Mac - will need to update the computer to the latest version first… Hmm, the file path import for the header/footer may be a problem, file paths on Mac are always tricky for a Windows user…

–Mitch

strange! i’m glad that at the very least i was not crazy in thinking there was an issue… i’ve been playing around with is and I have a shortened version which I reduced the problem down to the maximum:

    import Rhino
    import scriptcontext
    import rhinoscriptsyntax as rs
    
    if __name__ == "__main__":
        # Get Curve:
        crv = rs.coercegeometry(rs.GetObject("Select Curve Object"))
        # Settings:
        angle_tol = Rhino.RhinoMath.ToRadians(5.0)
        min_edge = 0.0
        max_edge = 0 # =ignore
        # Make into "PolyLine Curve"
        plinecrv = crv.ToPolyline( 0, 0, angle_tol, 0.0, 0.0, 0.01, min_edge, max_edge, True)
        # Makeinto "PolyLine"
        rc, polyline = plinecrv.TryGetPolyline()
        if rc: print(polyline)
        ####
        txt = ""  # make blank string
        for point in polyline:
            # >>> print(type(point))
            # >>> [type 'Point3D']
            # >>> print(point.ToString())
            # >>> [type 'string']
            txt += point.ToString() + "\r\n"
            print(txt) # This works...
        # Check
        print(txt) # This doesn't work...

Key thing to note is that the print(txt) within the loop printing as it should. yet when it exits the loop, it prints out only the \r\n (i.e. a whole long screen of white). is this some weird python issue? some mac thing?

I’m bringing in them separately for templating… not a major thing though. i also wanted the flexibility within the system to allow for editing, adding, etc.
as for the six decimal places, I was following the standards from the CAM software that come with the shopbots. you are correct, it is excessive… but we can dream, can’t we? :stuck_out_tongue:

This is certainly a Mac thing, it is working on Windows and I see the problem as well here on my Mac. Have to look into why, I don’t have my code editor installed on the Mac, so I’ll have to do some back and forth here…

Edit: OK, the following works on my Mac, it may simply be the “\r\n” that the Mac doesn’t like, simply “\n” seems to work fine.

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

if __name__ == "__main__":
    # Get Curve:
    crv = rs.coercegeometry(rs.GetObject("Select Curve Object",4,preselect=True))
    # Settings:
    angle_tol = Rhino.RhinoMath.ToRadians(5.0)
    min_edge = 0.0
    max_edge = 0 # =ignore
    # Make into "PolyLine Curve"
    plinecrv = crv.ToPolyline( 0, 0, angle_tol, 0.0, 0.0, 0.01, min_edge, max_edge, True)
    # Makeinto "PolyLine"
    rc, polyline = plinecrv.TryGetPolyline()
    if rc: print(polyline)
    ####
    txt = ""  # make blank string
    for point in polyline:
        txt+="{:.3f}, {:.3f}, {:.3f}\n".format(point.X,point.Y,point.Z)
        #txt += point.ToString() + "\n"
        #print(txt) # This works...
    # Check
    print(txt) # This works...

–Mitch

BTW

"\n"

should work in Windows too.
I think there is no need for the

"\r"

the header.txt and footer.txt files are also formatted using “\n” only.

the question is then, why did it work within the loo yet failed when it exited?

if anything, i’ll see if i can’t go into lab today to see if it makes a major difference when sending to the shopbot.

Eh … right.
I haven’t a Mac, could you post the output text you’re talking about ?
Thanks

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

if __name__ == "__main__":
    # Get Curve:
    crv = rs.coercegeometry(rs.GetObject("Select Curve Object"))
    # Settings:
    angle_tol = Rhino.RhinoMath.ToRadians(5.0)
    min_edge = 0.0
    max_edge = 0 # =ignore
    # Make into "PolyLine Curve"
    plinecrv = crv.ToPolyline( 0, 0, angle_tol, 0.0, 0.0, 0.01, min_edge, max_edge, True)
    # Makeinto "PolyLine"
    rc, polyline = plinecrv.TryGetPolyline()
    if not rc:
        print("error")
    txt = ""
    for pt in polyline:
        txt += "M3, {0[0]:.6f}, {0[1]:.6f}, {0[2]:.6f}\n".format((pt.X, pt.Y, pt.Z)) # even with out the '\n'
        print(txt)
    # print(txt)

When print(txt) statement is within loop:

RunPythonScript [start]
Executing File
M3, 0.000000, 0.000000, -4.000000

M3, 0.000000, 0.000000, -4.000000
M3, 0.545227, 0.000000, -2.643087

M3, 0.000000, 0.000000, -4.000000
M3, 0.545227, 0.000000, -2.643087
M3, 0.805229, 0.000000, -2.068123

M3, 0.000000, 0.000000, -4.000000
M3, 0.545227, 0.000000, -2.643087
M3, 0.805229, 0.000000, -2.068123
M3, 1.057129, 0.000000, -1.558757

...

when it is outside the loop:

RunPythonScript [start]
Executing File

Now, here is where is get really strange:

the above was produced, when using this crv:

when i use this crv:

it works!

RunPythonScript [start]
Executing File
M3, 3.000000, 0.000000, 3.000000
M3, 3.119690, 0.000000, 2.205078
M3, 3.198509, 0.000000, 1.843140
M3, 3.289551, 0.000000, 1.503906
M3, 3.392494, 0.000000, 1.186646
M3, 3.507019, 0.000000, 0.890625
M3, 3.632805, 0.000000, 0.615112
M3, 3.769531, 0.000000, 0.359375
M3, 3.916878, 0.000000, 0.122681
M3, 4.074524, 0.000000, -0.095703
M3, 4.242149, 0.000000, -0.296509
M3, 4.419434, 0.000000, -0.480469
M3, 4.606056, 0.000000, -0.648315
M3, 4.801697, 0.000000, -0.800781
M3, 5.006035, 0.000000, -0.938599
M3, 5.218750, 0.000000, -1.062500
M3, 5.439522, 0.000000, -1.173218
M3, 5.668030, 0.000000, -1.271484
M3, 5.903954, 0.000000, -1.358032
M3, 6.146973, 0.000000, -1.433594
M3, 6.653015, 0.000000, -1.554688
M3, 7.183594, 0.000000, -1.640625
M3, 7.736145, 0.000000, -1.697266
M3, 8.308105, 0.000000, -1.730469
M3, 9.500000, 0.000000, -1.750000
M3, 10.738770, 0.000000, -1.746094
M3, 12.003906, 0.000000, -1.765625
M3, 12.639954, 0.000000, -1.798828
M3, 13.274902, 0.000000, -1.855469
M3, 13.906189, 0.000000, -1.941406
M3, 14.531250, 0.000000, -2.062500
M3, 15.147522, 0.000000, -2.224609
M3, 15.752441, 0.000000, -2.433594
M3, 16.049843, 0.000000, -2.557495
M3, 16.343445, 0.000000, -2.695313
M3, 16.632927, 0.000000, -2.847778
M3, 16.917969, 0.000000, -3.015625
M3, 17.198250, 0.000000, -3.199585
M3, 17.473450, 0.000000, -3.400391
M3, 17.743248, 0.000000, -3.618774
M3, 18.007324, 0.000000, -3.855469
M3, 18.265358, 0.000000, -4.111206
M3, 18.517029, 0.000000, -4.386719
M3, 18.762016, 0.000000, -4.682739
M3, 19.000000, 0.000000, -5.000000


WHAT???
is this some (really strange) memory thing?

Well … actually I cannot understand what happens there … I think we need help from the experts.

A thing I would try, since it seems to work on some curves but not on others,
is checking, on the first curve and printing from inside the loop, if the script actually keeps printing until the end of the loop.
… Or if it stops before reaching the last point.
This in case the problem depend on the total number of points ( … It looks to work on shorter curves … )

Strange things are happening lately … I have a script (about the ‘Python exercise’ thread) that runs in 5 seconds the first time it is run (on Windows), but the second time it takes 40 seconds … unless I restart Rhino … I really don’t know why …

Can you post the two curves - I would like to test here. --Mitch

I’ll test to see if it is exiting the loop early. I think that I going to change the structure a bit, and have it write to a file at each line rather tan store as a python string and only later writing to a file.
Here is the file with the curves. (one pline and curve that work, and one curve that doesn’t)
Untitled.3dm (38.8 KB)