CamBam
News:
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
September 19, 2019, 14:15:48 pm


Login with username, password and session length


Pages: 1 [2] 3 4 ... 7
  Print  
Author Topic: Drag-Knife Script  (Read 56143 times)
billt
Droid
**
Offline Offline

Posts: 90


View Profile
« Reply #15 on: April 24, 2014, 17:42:03 pm »

I checked out your file and it fails at an intermediate point on the curve - the point is also the last point on the polyline.
I deleted the point and changed the curve bulge to 1 and the cut path worked properly.
Maybe the rounding errors of the curve bulge value causes the end point not to exactly match the start point resulting in the error.
By the way, I did not get any error displayed, even with the diagnostic level set to 4 - where did your "division by zero" error show up?
Cheers - BillT


* Test Cut 4-24-14.jpg (31.13 KB, 956x674 - viewed 357 times.)
Logged
lloydsp
CNC Jedi
*****
Offline Offline

Posts: 7987



View Profile
« Reply #16 on: April 24, 2014, 18:26:15 pm »

Bill,
I don't know this is the case, but if that supposed cause of the error is true, you may have to restrict the precision of your arithmetic in the script.

I've already worked with someone else's plugin where it was necessary to round everything to (eh, roughly) 1/100,000th inch or 1/1000th mm.

CB calculates everything out to extreme precision, so 1E-18 <> 0   <G>

LLoyd
Logged

"Pyro for Fun and Profit for More Than Fifty Years"
Dragonfly
CNC Jedi
*****
Offline Offline

Posts: 2154



View Profile
« Reply #17 on: April 24, 2014, 22:57:04 pm »

Bill, the message I got in the message window. On the attached picture your knife offset is far too large than mine.
I should mention also that I am tinkering with your code on a "hit & miss" principle Smiley
With the Roland type tiny knife I thunk there's no need for lifting, so I set lift and DOC = 0. And tried to make the code do an overlap cut at start/end with some success (on a different shape). At least on screen the geometry looks like what I want it to be. But the division by zero on the shape I posted disappeared. I suspect the code never runs through that part because most probably I've messed up with the funky Python syntax which I stumble on for the first time Smiley
Logged
Dragonfly
CNC Jedi
*****
Offline Offline

Posts: 2154



View Profile
« Reply #18 on: April 29, 2014, 18:41:18 pm »

That Python is a real constrictor Cheesy
I've never had any experience with it and in the last days am fighting with the code to not much positive result. Sad
1.
Since vinyl foil is less than 1/10 mm thick there is no need for complex swivel knife maneuvering when turning. So I am trying to change the code to my liking but hit a rock here:
Code:
   C3Sweep = Math.Acos(Vector2F.DotProduct(V3,VN1)/(V3.Length*VN1.Length))
There are cases when
Code:
Vector2F.DotProduct(V3,VLast)
equals zero and consequently
Code:
C3Sweep = Math.Acos(0)
but instead of 90 the calculation returns NaN (not a number). I split the expression to simple ones that result in separate variables and although the latter are displayed with the expected values in the log still the NaN makes a mess of the new polylines.
This happens even in the original code in a special case when there is a 90 degree arc (1/4 circle).

2.
Before the actual calculations begin I am trying to make all selected shapes (polylines only) have a CCW direction of rotation. I do this successfully with a VB script but under Python, acting in a similar way does not change the direction. I suspect I am acting on a copy of the real poly but can't figure where I make a mistake and how to make the changes.

Any help will be appreciated.

P.S.
Quote
xpoly = XPolyline(ent)
seg = xpoly.FirstSegment

What is 'XPolyline'? Couldn't find info in the 'doc/api' section.
Logged
billt
Droid
**
Offline Offline

Posts: 90


View Profile
« Reply #19 on: April 29, 2014, 19:43:45 pm »

Dragonfly -
Thanks for finding these bugs.

The first V3.X divide-by-zero issue I can easily add an "if V3.X==0" condition and a couple of lines to handle the zero value.

Acos(0) should return 90, but if it is giving you NaN there might be a solution.
A wikipedia search on "Inverse trigonometric functions" suggest that functions atan or atan2 might be able to better handle zero (or close to zero) values.
I will modify and check a couple of cases to see if it makes an improvement.

Regarding your CCW rotation, I had the same issue as you - I was acting on a copy of the polyline.
Andy responded with a correction to my code - see the thread below.
http://www.cambam.co.uk/forum/index.php?topic=3652.0

Third regarding XPolyline() - it is a 2-D Polyline entity, and has helpful functions related to 2-D.
Of course this stuff is not in the doc/api, but I have found you can explore the available functions by running a simple script such as:
for m in dir(XPolyline()): print m
print help(XPolyline)
See the topic at: http://www.cambam.co.uk/forum/index.php?topic=3057.0
Logged
Dragonfly
CNC Jedi
*****
Offline Offline

Posts: 2154



View Profile
« Reply #20 on: April 29, 2014, 20:39:08 pm »

Thanks Bill,
I've missed the thread from the first link and will try the modification.
The second one I read but I presume I have to install stand alone Python on my PC in order to explore the functions. Or maybe first I should see where 'print' outputs to under CB.
Apart from being a stranger to Python I've forgotten a lot of things in maths and my brain has gotten very rusty Smiley
Also, I intend to try and see what effect, if any, rounding the point coordinate values have on the drag knife script output. There's a VB script for that by dh42.
Logged
billt
Droid
**
Offline Offline

Posts: 90


View Profile
« Reply #21 on: April 29, 2014, 21:59:24 pm »

Python is actually baked into CB - I believe it is the Iron Python distribution.
The Math Library is now pre-compiled, so you do not need to import it.
Other external libraries can be imported, but you would need to set the import path.
See the following thread:
http://www.cambam.co.uk/forum/index.php?topic=3062.msg19215#msg19215

And the print results will show up in the message window - you can scroll or copy/paste to notepad for easier viewing.

Cheers - BillT
Logged
Dragonfly
CNC Jedi
*****
Offline Offline

Posts: 2154



View Profile
« Reply #22 on: April 30, 2014, 21:41:46 pm »

Hi Bill,
I continue to dig but hit a rock Smiley
I am thinking of an approach to finding the points where tool center should return on a following segment after overshooting the end of the previous. For test purpose I put up script that will walk the segments in sequence and draw a circle (Circle2F needed) using the first point2F (P1) as a center. The radius is set 2 mm for better visual inspection. Then I try to find a point where an Arc intersects with the circle or the circle intersects with a Line. Both methods are said to return a Line2F object. The code runs OK. But I can't access the values of the points. I get a message that Line2F has no property P1 (or P2). Tried X1/Y1, x1/y1, a/b with the same error appearing.
Only ToString method works and in the description it will return a string: (X1,Y1)-(X2,Y2). But because there is only one valid intersection point in the message window there are strange combinations (the attached picture).
At firs I though those are negative signs but it seems they are the dashes from the truncated output. They appear either in front and there are two -- when the result is expected to be negative, or at the end. I presume this is due to which Point2F is valid and which is undefined.
But the main problem is I can't access those values from the script. Otherwise it seems the coordinates are valid.
I wanted to make the CamBam.CAD do the maths internally instead of applying complex calculations within the script. And it seems for now the idea is applicable.
Here's the code: Note, I work with Metric units.
Code:
#PropTest.py

####### MAIN LOOP #########################################

CamBamUI.MainUI.UndoBuffer.AddUndoPoint("Undo Here")
CamBamUI.MainUI.UndoBuffer.Add(doc.ActiveLayer.Entities)

for entity in view.Selection:
  if entity.GetType().Name == "Polyline":
    xpoly = XPolyline(entity)
    app.log("************************Polyline**************************")
    app.log("Polyline:    "+entity.ID.ToString())
    app.log("Segments:    "+entity.NumSegments.ToString())
    seg = xpoly.FirstSegment
    poly = Polyline()
    SegNum = 1
    VFirst = Vector2F(1,0)
    VLast = Vector2F(1,0)

# ####### Loop for each segment within the Polyline #########
    while seg is not None:

      V1 = seg.VNormal1.Normal().Normal().Normal()
      V2 = seg.VNormal2.Normal().Normal().Normal()
      SName = seg.GetType().Name
      app.log("Segment        ="+SegNum.ToString())
      app.log("Name           ="+SName.ToString())
      if SName == "XPolySegLine":
         cir = Circle2F(seg.P1,2)
         cir1 = Circle(seg.P1,2) 
         MyLine = Line2F(seg.P1, seg.P2)
         XSect = cir.LineIntersect(MyLine)
         app.log("P1    = "+seg.P1.ToString())
         app.log("iSect = "+XSect.ToString())

      if SName == "XPolySegArc":
         Blg = Math.Tan(seg.Sweep / 4)
         MyArc = Arc2F(seg.Center, seg.P1, seg.P2, seg.Direction)
         cir = Circle2F(seg.P1,2)
         cir1 = Circle(seg.P1,2)   
         XSect = MyArc.CircleIntersect(cir)
         app.log("P1    = "+seg.P1.ToString())
         app.log("iSect = "+XSect.ToString())
      SegNum += 1
      seg = seg.NextSegment
      doc.Add(cir1)
 


* PointWalk.jpg (212.11 KB, 418x906 - viewed 347 times.)
Logged
billt
Droid
**
Offline Offline

Posts: 90


View Profile
« Reply #23 on: May 01, 2014, 02:25:07 am »

Dragonfly -

The Line2F object does have point properties, but they are p1,p2 and not P1,P2.
It is a pain to figure these out since they are case sensitive and are not standardized.
These can be found by compiling a script of: print help(Line2F)

I added two lines to both of your loops.
         app.log("iSect.p1 = "+XSect.ToString())
         app.log("iSect.p2 = "+XSect.ToString())

I made a similar polyline and ran the script.
The resulting message window results in something similar to:

Logged
billt
Droid
**
Offline Offline

Posts: 90


View Profile
« Reply #24 on: May 01, 2014, 02:43:23 am »

continued...

iSect = 2,0-
iSect.p1 = 2,0-
iSect.p2 = 2,0-

This result of p1=p2 can be explained by the fact that your "MyLine" used for the intercept always starts at the center of the circle, so there is only one intercept point.  I cannot fully explain the "-" that shows up after the "0" but it is probably related to the fact that the line has a zero length - maybe because the direction cannot be determined?

Your approach of finding the intercept of a circle with the next segment will work if the next segment is always a line, however if the next segment is an arc the intercept should be instead with the tangent line at P1 of the next segment.  My script does use this correct tangent method for arcs.  I am working on the defects that you found and should have the solution posted within a couple of days.

Cheers - BillT
Logged
billt
Droid
**
Offline Offline

Posts: 90


View Profile
« Reply #25 on: May 01, 2014, 03:50:27 am »

Dragonfly -
You will find part of the API documented at:
http://www.cambam.info/doc/api/

I just posted a text file which lists the doc() of the primary namespaces CamBamUI, Geom, CAD, and CAM.
This file identifies all objects including those that are missing from the online api documentation.
For example XPolyline.
See the post: http://www.cambam.co.uk/forum/index.php?topic=3057.0

Cheers - BillT
Logged
Dragonfly
CNC Jedi
*****
Offline Offline

Posts: 2154



View Profile
« Reply #26 on: May 01, 2014, 11:34:59 am »

Bill,
I am using already both sources thanks to your cooperation.
My main difficulty is proper comprehension of what I read there because, as I already pointed, I haven't been hands on programming for a very very long time. Some knowledge is slowly surfacing from deep in my memory, other things I have to learn again or are totally new for me. But this is a kind of challenge and I'll do some more digging today. Smiley
Thanks again for the help.

Ivan

BTW, has anyone found a way to get the contents of the message window to a text file?
« Last Edit: May 01, 2014, 11:36:43 am by Dragonfly » Logged
Dragonfly
CNC Jedi
*****
Offline Offline

Posts: 2154



View Profile
« Reply #27 on: May 03, 2014, 22:17:06 pm »

Does anyone know how to terminate Python script execution from within the script?

exit() does it by causing an error  Grin

I have a definite advance with my version of the script but want to put some means of stopping it under conditions with geometry which is too fine for the actual knife offset.

Best check for NaN results I found so far:
Code:
def IsNaN(num):
    return str(num).lower().find('nan')>=0
« Last Edit: May 03, 2014, 22:19:23 pm by Dragonfly » Logged
lloydsp
CNC Jedi
*****
Offline Offline

Posts: 7987



View Profile
« Reply #28 on: May 03, 2014, 23:08:56 pm »

exit() can only properly exit main.   Invocation in inner loops sends an exception up-hill that may not be handled well.


According to all the usual suspects,

import sys
.
.
.
sys.exit(none) or sys.exit(0) should exit gracefully, raising an exception with a "normal termination" value set, and letting all the various 'trys' and other loops to clean up.

Lloyd
Logged

"Pyro for Fun and Profit for More Than Fifty Years"
billt
Droid
**
Offline Offline

Posts: 90


View Profile
« Reply #29 on: May 05, 2014, 04:23:50 am »

New corrected script is uploaded.
The divide by zero error is fixed - it was a mistake on my part.
I traced the NaN error back to a floating point precision issue.
Turns out that Acos() returns a NaN error if calculating anything larger than exactly 1.
To correct it, I rounded the input value to 10 decimal places.

Added a new SwivelAngle variable and logic to prevent small angles generating a swivel move (requested by Dragonfly).
The old SwivelAngle variable is now re-named RetractAngle to be more clear on it's function.
Added a RetractEnable toggle value to make it easier when it comes time for pluginizing.
I also made some updates for readability and improved the logic.

Cheers - BillT

Variable Descriptions as listed in the script:
###########################################################################
#  VARIABLES:  Set these values for your tool and material
#
#    KnifeTipOffset: knife tip distance from tool centerline
#        (typically this is 1/2 the tool diameter)
#
#    CutDepth: set to material thickness or slightly larger to assure cutting through the material
#        A positive value for CutDepth will be set as a -Z value.
#        This value would be equivalent to the Engrave Depth.
#
#    SwivelAngle: this angle is used as a precision factor
#        If the angle between segments is SMALLER than SwivelAngle, a Swivel move will NOT be produced.
#        This will make the cut smoother, but less precise to the original path.
#        Default value is 5 degrees.
#
#    RetractEnable: this is a toggle to enable the Retract Feature
#        Value of (1) enables Retract and (0) disables it
#
#    RetractAngle: this angle is used for the Retract feature
#        If the angle between segments is LARGER than RetractAngle, a Retract move will be produced.
#        For thicker material like cardboard, this prevents gouging of material during the swivel move.
#        Default value is 40 degrees
#
#    RetractDepth: a smaller retract depth used during the swivel move
#        A positive value for RetractDepth will be set as a -Z value.
#        As a suggestion, try 1/2 the value of the CutDepth.
#
###########################################################################

* drag_knife_4-May-2014.txt (8.73 KB - downloaded 219 times.)
Logged
Pages: 1 [2] 3 4 ... 7
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines

Valid XHTML 1.0! Valid CSS! Dilber MC Theme by HarzeM
Page created in 0.145 seconds with 19 queries.

Copyright © 2018 HexRay Ltd. | Sitemap