Updating to this version of Rhino 8 SR6 (8.6.24101.5001, 2024-04-10) has broken an unchanged and previously working GH IronPython 2 script component.
Example attached:
Edit - code retracted
Updating to this version of Rhino 8 SR6 (8.6.24101.5001, 2024-04-10) has broken an unchanged and previously working GH IronPython 2 script component.
Example attached:
Edit - code retracted
How is it broken exactly? I don’t see an error in SR 7 8.7.24113.23001.
"""
Ataraxia G-Code tool_path Visualizer scripting component
"""
__author__ = "Leo Pedersen"
__version__ = "2024.01.20"
import Grasshopper.Kernel as gh
import rhinoscriptsyntax as rs
import scriptcontext as sc
sc.doc = ghdoc
e = gh.GH_RuntimeMessageLevel.Error
arcs_centers_points = []
boolean_feed = []
float_drill_R_retract = 0.0
float_drill_Z_bottom = 0.0
int_rapid_dashes = 10
int_rapid_divisions = ((int_rapid_dashes - 1) * 2) + 1
int_T = 0
paths = []
point_current = rs.CreatePoint(point_start.X,point_start.Y,point_start.Z)
point_previous = rs.CreatePoint(point_current.X,point_current.Y,point_current.Z)
str_arc_center_mode = "incremental"
str_mode = ""
def Main():
global curves_tool_path
global point_tool_path_end
process_Gcode()
curves_tool_path = paths
point_tool_path_end = rs.CreatePoint(point_current)
def process_Gcode():
for i in range(len(cut_Gcode)):
#print("line "+str(i)) # uncomment for debugging
str_block = str(cut_Gcode[i])
set_mode(str_block)
# substring block before comments
str_block = str_block[:str_block.find("(")]
if set_point_current(str_block):
global str_mode
#print str_mode # uncomment for debugging
if str_mode == "rapid":
G00_rapid()
elif str_mode == "feed line":
G01_feed()
elif str_mode.find("arc") >= 0:
G02_G03_arc(str_block)
elif str_mode == "drill":
G81_drill(str_block)
elif str_mode == "peck drill":
G83_peck_drill(str_block)
def set_mode(str_block):
global str_mode
# no mode change
if str_block.startswith("X"):
return
elif str_block.startswith("Y"):
return
elif str_block.startswith("Z"):
return
elif str_block.startswith("A"):
return
elif str_block.startswith("B"):
return
elif str_block.startswith("C"):
return
elif str_block.startswith("("):
return
# set movement mode
elif str_block.startswith("G00"):
str_mode = "rapid"
elif str_block.startswith("G01"):
str_mode = "feed line"
elif str_block.startswith("G02"):
str_mode = "feed arc clockwise"
elif str_block.startswith("G03"):
str_mode = "feed arc counterclockwise"
elif str_block.startswith("G80"):
str_mode = ""
elif str_block.startswith("G81"):
str_mode = "drill"
elif str_block.startswith("G83"):
str_mode = "peck drill"
# tool change
elif str_block.startswith("M06"):
# cutter radius
global float_cutter_diameter
global float_cutter_radius
int_diameter = str_block.find("Tool Change ") + 12
int_inch = str_block.find('"')
if int_inch != -1:
float_cutter_diameter = float(str_block[int_diameter:int_inch])
else:
int_mm = str_block.find("mm")
if int_mm != -1:
float_cutter_diameter = float(str_block[int_diameter:int_mm]) * 0.03937
else:
float_cutter_diameter = 0.125 # tolken diameter for center drills etc.
float_cutter_radius = float_cutter_diameter / 2
# set arc center mode (works in Mach4 but not UCCNC)
elif str_block.startswith("G90.1"):
str_arc_center_mode = "absolute"
elif str_block.startswith("G91.1"):
str_arc_center_mode = "incremental"
def set_point_current(str_block):
global point_current
global point_previous
global float_drill_Z_bottom
# detect position change for each axis
bool_movement = False
point_new = rs.CreatePoint(point_current.X,point_current.Y,point_current.Z)
int_X_start = str_block.find("X") + 1
if int_X_start > 0:
bool_movement = True
int_X_end = str_block.find(" ", int_X_start)
point_new.X = float(str_block[int_X_start:int_X_end])
int_Y_start = str_block.find("Y") + 1
if int_Y_start > 0:
bool_movement = True
int_Y_end = str_block.find(" ", int_Y_start)
point_new.Y = float(str_block[int_Y_start:int_Y_end])
int_Z_start = str_block.find("Z") + 1
if int_Z_start > 0:
bool_movement = True
int_Z_end = str_block.find(" ", int_Z_start)
point_new.Z = float(str_block[int_Z_start:int_Z_end])
"""if "drill" in str_mode:
float_drill_Z_bottom = point_new.Z
point_new.Z = point_current.Z"""
int_A_start = str_block.find("A") + 1
if int_A_start > 0:
bool_movement = True
int_B_start = str_block.find("B") + 1
if int_B_start > 0:
bool_movement = True
int_C_start = str_block.find("C") + 1
if int_C_start > 0:
bool_movement = True
if bool_movement == False:
return False
else:
point_previous = rs.CreatePoint(point_current.X,point_current.Y,point_current.Z)
point_current = rs.CreatePoint(point_new.X,point_new.Y,point_new.Z)
return True
def G00_rapid():
global paths
global point_current
global point_previous
if rs.PointCompare(point_previous, point_current):
return
else:
# rapid line
line = rs.AddLine(point_previous, point_current)
paths.append(line)
boolean_feed.append(False)
point_previous = rs.CreatePoint(point_current.X,point_current.Y,point_current.Z)
def G01_feed():
global paths
global point_current
global point_previous
if rs.PointCompare(point_previous, point_current):
print "Error - G01 Feed distance 0"
else:
line = rs.AddLine(point_previous, point_current)
paths.append(line)
boolean_feed.append(True)
point_previous = rs.CreatePoint(point_current.X,point_current.Y,point_current.Z)
def G02_G03_arc(str_block):
global paths
global point_current
global point_previous
global str_arc_center_mode
point_arc_start = rs.CreatePoint(point_previous.X,point_previous.Y,point_previous.Z)
point_arc_end = rs.CreatePoint(point_current.X, point_current.Y, point_current.Z)
# find arc center coordinate I
int_I_start = str_block.find("I") + 1
if int_I_start > 0:
int_I_end = str_block.find(" ", int_I_start)
float_arc_I = float(str_block[int_I_start:int_I_end])
if str_arc_center_mode == "incremental":
float_arc_center_X = point_arc_start.X + float_arc_I
elif str_arc_center_mode == "absolute":
float_arc_center_X = float_arc_I
else:
ghenv.Component.AddRuntimeMessage(e, "Error: arc center I undefined.")
else:
ghenv.Component.AddRuntimeMessage(e, "Error: can't find I coordinate for arc center point")
# find arc center coordinate J
int_J_start = str_block.find("J") + 1
if int_J_start > 0:
int_J_end = str_block.find(" ", int_J_start)
float_arc_J = float(str_block[int_J_start:int_J_end])
if str_arc_center_mode == "incremental":
float_arc_center_Y = point_arc_start.Y + float_arc_J
elif str_arc_center_mode == "absolute":
float_arc_center_Y = float_arc_J
else:
ghenv.Component.AddRuntimeMessage(e, "Error: arc center J undefined.")
else:
ghenv.Component.AddRuntimeMessage(e, "Error: can't find J coordinate for arc center point")
# find arc radius
float_arc_center_Z = point_arc_start[2]
point_arc_center = rs.CreatePoint(float_arc_center_X, float_arc_center_Y, float_arc_center_Z)
float_arc_radius = rs.Distance(point_arc_center, point_arc_start)
# find arc plane
if str_mode == "feed arc clockwise":
vector_plane_arc_axis_Z = [0,0,-1]
elif str_mode == "feed arc counterclockwise":
vector_plane_arc_axis_Z = [0,0,1]
vector_plane_arc_axis_X = rs.VectorCreate(point_arc_start, point_arc_center)
plane_arc_center = rs.PlaneFromNormal(point_arc_center, vector_plane_arc_axis_Z, vector_plane_arc_axis_X)
# check if arc is a circle or helix 360°
if point_arc_end.X == point_arc_start.X and point_arc_end.Y == point_arc_start.Y:
feed_arc = rs.AddCircle(plane_arc_center,float_arc_radius)
else:
# create arc
vector_arc_start = rs.VectorCreate(point_arc_start,point_arc_center)
vector_arc_end = rs.VectorCreate(point_arc_end,point_arc_center)
float_arc_angle = rs.VectorAngle(vector_arc_start,vector_arc_end)
float_angle_direction = rs.VectorCrossProduct(vector_arc_start,vector_arc_end)[2]
if float_angle_direction < 0 and str_mode == "feed arc counterclockwise":
float_arc_angle = 360 - float_arc_angle
elif float_angle_direction > 0 and str_mode == "feed arc clockwise":
float_arc_angle = 360 - float_arc_angle
feed_arc = rs.AddArc(plane_arc_center, float_arc_radius, float_arc_angle)
# check if arc is helical
if point_arc_start.Z != point_arc_end.Z:
# check for closed circle
if rs.IsCurveClosed(feed_arc):
# split circle at start
circle_splits = rs.SplitCurve(feed_arc,0.000000001)
feed_arc = circle_splits[1]
# morph arc into helix
# get arc control points
points_arc = rs.CurvePoints(feed_arc)
float_knots_arc = rs.CurveKnots(feed_arc)
int_degree_arc = rs.CurveDegree(feed_arc)
float_weights_arc = rs.CurveWeights(feed_arc)
float_helix_depthZ = point_arc_end.Z - point_arc_start.Z
int_arc_points = len(points_arc)
int_stepsZ = int_arc_points - 1
float_stepZ = float_helix_depthZ / int_stepsZ
points_helix = []
float_knots_helix = []
float_weights_helix = []
# distribute control points through Z axis
for i in range(int_arc_points):
point_helix = [points_arc[i].X, points_arc[i].Y, points_arc[i].Z + (i * float_stepZ)]
points_helix.append(point_helix)
feed_arc = rs.AddNurbsCurve(points_helix, float_knots_arc, int_degree_arc, float_weights_arc)
paths.append(feed_arc)
boolean_feed.append(True)
point_previous = rs.CreatePoint(point_current.X,point_current.Y,point_current.Z)
def G81_drill(str_block):
global float_cutter_radius
global float_drill_R_retract
global float_drill_Z_bottom
global paths
global point_current
global point_previous
global str_mode
# rapid to position at retract height
int_R_start = str_block.find("R") + 1
if int_R_start > 0:
int_R_end = str_block.find(" ", int_R_start)
float_drill_R_retract = float(str_block[int_R_start:int_R_end])
float_drill_Z_bottom = point_current.Z
point_current.Z = float_drill_R_retract
G00_rapid()
# drill feed to bottom
point_current.Z = float_drill_Z_bottom
G01_feed()
plane_circle = rs.PlaneFromNormal(point_current, [0,0,1])
paths.append(rs.AddCircle(plane_circle, float_cutter_radius))
boolean_feed.append(True)
# drill rapid retract
point_current.Z = float_drill_R_retract
G00_rapid()
def G83_peck_drill(str_block):
global float_cutter_radius
global float_drill_R_retract
global float_drill_Z_bottom
global float_Q_peck
global paths
global point_current
global point_previous
global str_mode
#drill rapid to position at retract height
int_R_start = str_block.find("R") + 1
if int_R_start > 0:
int_R_end = str_block.find(" ", int_R_start)
float_drill_R_retract = float(str_block[int_R_start:int_R_end])
float_drill_Z_bottom = point_current.Z
point_current.Z = float_drill_R_retract
G00_rapid()
# drill pecking
int_Q_start = str_block.find("Q") + 1
if int_Q_start > 0:
int_Q_end = str_block.find(" ", int_Q_start)
float_Q_peck = float(str_block[int_Q_start:int_Q_end])
while point_current.Z >= (float_drill_Z_bottom + float_Q_peck):
point_current.Z = point_current.Z - float_Q_peck
G01_feed()
plane_circle = rs.PlaneFromNormal(point_current, [0,0,1])
paths.append(rs.AddCircle(plane_circle, float_cutter_radius))
boolean_feed.append(True)
point_current.Z = float_drill_Z_bottom
G01_feed()
plane_circle = rs.PlaneFromNormal(point_current, [0,0,1])
paths.append(rs.AddCircle(plane_circle, float_cutter_radius))
boolean_feed.append(True)
# drill rapid retract
point_current.Z = float_drill_R_retract
G00_rapid()
Main()
It’s broken in SR6.
Thanks for testing it in the SR7 release candidate James.
I’ll have to work in the SR7 release candidates until SR7 becomes the current release.
Hi @LeoPedersen ,
Can you try not to internalize the values for the “point_start” input. So just add an actual point to this point_start
input. Does warning about type conversion happen again? How does the warning message look like in that case?
Hi @djordje there is no change when I add a point to the point_start input. Error is identical.
I see. Sorry then for the dumb suggestion.