Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # DRAG_KNIFE.PY
- # Rev: 23-Sep-2013
- # Bill Trondsen
- ###########################################################################
- # This CAMBAM script creates a polyline for Drag-Knife cutting
- # Select all desired polylines and run the script
- # Note: Material Surface set to Z=0
- # Use an engraving path with depth of cut set to zero
- # Drag-Knife Path Concept comes from: www.DonekTools.com
- # Cut path is simulated by the path of a rear bicycle wheel
- # Knowing the rear wheel path, calculate the front wheel (tool path)
- # Formulas come from: http://math.ucsd.edu/~ebender/87/bicycle.pdf
- #
- ###########################################################################
- # Set these variables for your tool and material
- # Offset: knife tip distance from tool centerline
- # CutDepth: material thickness
- # RetractDepth: a smaller depth used for retract/swivel move
- # SwivelAngle: if larger than this angle, tool retracts between segments
- ###########################################################################
- Offset = .09
- CutDepth = .25
- RetractDepth = .24
- SwivelAngle = 20
- app.log("Offset = "+Offset.ToString())
- app.log("CutDepth = "+CutDepth.ToString())
- app.log("RetractDepth = "+RetractDepth.ToString())
- app.log("SwivelAngle = "+SwivelAngle.ToString())
- ####### MAIN LOOP #########################################
- CamBamUI.MainUI.UndoBuffer.AddUndoPoint("Undo Here")
- CamBamUI.MainUI.UndoBuffer.Add(doc.ActiveLayer.Entities)
- for ent in view.Selection:
- if ent.GetType().Name == "Polyline":
- xpoly = XPolyline(ent)
- app.log("**********************************************************")
- app.log("************************Polyline**************************")
- app.log("**********************************************************")
- app.log("Polyline: "+ent.ID.ToString())
- seg = xpoly.FirstSegment
- poly = Polyline()
- PrevSweep = 0
- SegNum = 1
- ######## Loop for each segment within the Polyline #########
- while seg is not None:
- P1X = seg.P1.X
- P1Y = seg.P1.Y
- P2X = seg.P2.X
- P2Y = seg.P2.Y
- V1 = seg.VNormal1.Normal().Normal().Normal()
- V2 = seg.VNormal2.Normal().Normal().Normal()
- VFirst = Vector2F(1,0)
- VLast = Vector2F(1,0)
- #### First Point is oriented to X-axis and calculate sweep/bulge to first segment
- if seg == xpoly.FirstSegment:
- CFirst = Point2F(P1X+Offset, P1Y)
- CFirstXP = Vector3F.CrossProduct(Vector3F(1,0,0),Vector3F(V1.X,V1.Y,0))
- CFirstDirection = Math.Sign(CFirstXP.Z)
- if CFirstDirection == 0:
- CFirstDirection = 1
- CFirstSweep = Math.Acos(Vector2F.DotProduct(VFirst,V1)/(VFirst.Length*V1.Length))
- CFirstB = Math.Tan(CFirstSweep/4)*CFirstDirection
- app.log("CFirst "+CFirst.ToString())
- app.log("CFirstSweep "+CFirstSweep.ToString())
- app.log("CFirstXP "+CFirstXP.ToString())
- app.log("CFirstDirection"+CFirstDirection.ToString())
- app.log("CFirstB "+CFirstB.ToString())
- C1 = Point2F(P1X+V1.X*Offset,P1Y+V1.Y*Offset)
- if seg.GetType().Name == "XPolySegLine":
- C1B = 0
- C3 = Point2F(P2X+V2.X*Offset, P2Y+V2.Y*Offset)
- elif seg.GetType().Name == "XPolySegArc":
- C1B = Math.Tan(seg.Sweep/4)
- C3X = P2X+Offset/((1+(V2.Y/V2.X)**2)**.5)*Math.Sign(V2.X)
- C3Y = P2Y+(Offset*V2.Y/V2.X)/((1+(V2.Y/V2.X)**2)**.5)*Math.Sign(V2.X)
- C3 = Point2F(C3X,C3Y)
- # After last segment, orient tool to x-axis before fully retracting
- V3 = Vector2F(seg.P2,C3)
- if seg == xpoly.LastSegment:
- C3XP = Vector3F.CrossProduct(Vector3F(V3.X,V3.Y,0),Vector3F(1,0,0))
- C3Direction = Math.Sign(C3XP.Z)
- if C3Direction == 0:
- C3Direction = 1
- C3Sweep = Math.Acos(Vector2F.DotProduct(V3,VLast)/(VLast.Length*V3.Length))
- C3B = Math.Tan((C3Sweep)/4)*C3Direction
- else:
- VN1 = seg.NextSegment.VNormal1.Normal()
- VN1.Invert()
- C3XP = Vector3F.CrossProduct(Vector3F(V3.X,V3.Y,0),Vector3F(VN1.X,VN1.Y,0))
- C3Direction = Math.Sign(C3XP.Z)
- if C3Direction == 0:
- C3Direction = 1
- C3Sweep = Math.Acos(Vector2F.DotProduct(V3,VN1)/(V3.Length*VN1.Length))
- C3B = Math.Tan((C3Sweep)/4)*C3Direction
- # After last segment, orient tool to x-axis before fully retracting
- V3 = Vector2F(seg.P2,C3)
- if seg == xpoly.LastSegment:
- C3XP = Vector3F.CrossProduct(Vector3F(V3.X,V3.Y,0),Vector3F(1,0,0))
- C3Direction = Math.Sign(C3XP.Z)
- if C3Direction == 0:
- C3Direction = 1
- C3Sweep = Math.Acos(Vector2F.DotProduct(V3,VLast)/(VLast.Length*V3.Length))
- C3B = Math.Tan((C3Sweep)/4)*C3Direction
- else:
- VN1 = seg.NextSegment.VNormal1.Normal()
- VN1.Invert()
- C3XP = Vector3F.CrossProduct(Vector3F(V3.X,V3.Y,0),Vector3F(VN1.X,VN1.Y,0))
- C3Direction = Math.Sign(C3XP.Z)
- if C3Direction == 0:
- C3Direction = 1
- C3Sweep = Math.Acos(Vector2F.DotProduct(V3,VN1)/(V3.Length*VN1.Length))
- C3B = Math.Tan((C3Sweep)/4)*C3Direction
- app.log("******************Segment*******************")
- app.log("Segment "+SegNum.ToString())
- app.log("P1 "+seg.P1.ToString())
- app.log("P2 "+seg.P2.ToString())
- app.log("V1 "+V1.ToString())
- app.log("V2 "+V2.ToString())
- app.log("V2X SIGN "+Math.Sign(V2.X).ToString())
- app.log("V2Y SIGN "+Math.Sign(V2.Y).ToString())
- app.log("C1 "+C1.ToString())
- app.log("C3 "+C3.ToString())
- app.log("C1Bulge "+C1B.ToString())
- app.log("C3Bulge "+C3B.ToString())
- ########################################################
- # Add points to path with depth logic###################
- ########################################################
- if seg == xpoly.FirstSegment:
- poly.Add(CFirst.X, CFirst.Y, RetractDepth, CFirstB)
- poly.Add(C1.X, C1.Y, RetractDepth, 0)
- poly.Add(C1.X, C1.Y, CutDepth, C1B)
- elif SwivelAngle >= PrevSweep:
- poly.Add(C1.X, C1.Y, CutDepth, C1B)
- else:
- poly.Add(C1.X, C1.Y, RetractDepth,0)
- poly.Add(C1.X, C1.Y, CutDepth,C1B)
- C3Angle = C3Sweep*180/Math.PI
- if seg == xpoly.LastSegment:
- CLast = Point2F(seg.P2.X+VLast.X*Offset, seg.P2.Y+VLast.Y*Offset)
- poly.Add(C3.X, C3.Y, CutDepth, 0)
- poly.Add(C3.X, C3.Y, RetractDepth, C3B)
- poly.Add(CLast.X, CLast.Y, RetractDepth, 0)
- elif SwivelAngle >= C3Angle:
- poly.Add(C3.X, C3.Y, CutDepth, C3B)
- else:
- poly.Add(C3.X, C3.Y, CutDepth, 0)
- poly.Add(C3.X, C3.Y, RetractDepth, C3B)
- app.log("SwivelAngle "+SwivelAngle.ToString())
- app.log("C3Sweep "+C3Angle.ToString())
- app.log("PrevSweep "+PrevSweep.ToString())
- # End of Main Loop #####################################
- PrevSweep = C3Angle
- SegNum += 1
- seg = seg.NextSegment
- doc.Add(poly)
Add Comment
Please, Sign In to add comment