problem with the finish pass in pocket when milling a b-spline or ellipse

Here's the place for discussion related to CAM/CNC and the development of the Path module.
eddyverl
Posts: 9
Joined: Wed Oct 30, 2019 10:17 am
Location: Belgium

problem with the finish pass in pocket when milling a b-spline or ellipse

Postby eddyverl » Sat Dec 21, 2019 1:25 pm

Hello,

I think there is a problem with the pocket function when milling special curves like ellipse, b-spline, ....

(With ordinary shapes with straight lines and arcs the function works fine)


The problem occurs with the final cut:
- with a finish debt > 0 the finish operation is simply not carried out
- and when the finish depth is set to zero, the last 'normal' cut does not happen

Here an image of een pocket operation with an additional profile cut. The profile cut is deeper.
Image


I have supplied 3 freecad files with a simple B-spline
 - 1 mm finish -> problem
 - 0 mm finish -> problem
 - 0.01 mm finish -> problem remains but the result is usable
And one of an ellipse with a 1mm finish

And pictures of the simulation
And the gcode files in which you can see that z = 8.00 mm is not reached in the pocket operation

you can download then here
================================================
 
EXTRA INFO:
 The gcode can only be viewed with 'inspect'
 
 Saving the gcode is impossible due to the following error:

Running the Python command 'Path_Post' failed:
Traceback (most recent call last):
File "/usr/share/freecad-daily/Mod/Path/PathScripts/PathPost.py", line 390, in Activated
(fail, rc) = self.exportObjectsWith(finalpostlist, job)
File "/usr/share/freecad-daily/Mod/Path/PathScripts/PathPost.py", line 212, in exportObjectsWith
gcode = processor.export(objs, filename, postArgs)
File "/usr/share/freecad-daily/Mod/Path/PathScripts/PathPostProcessor.py", line 102, in export
return self.script.export(obj, filename, args)
File "/usr/lib/freecad-daily/Mod/Path/PathScripts/post/linuxcnc_post.py", line 189, in export
job = PathUtils.findParentJob(obj)
File "/usr/share/freecad-daily/Mod/Path/PathScripts/PathUtils.py", line 402, in findParentJob
if hasattr(i, 'Proxy') and isinstance(i.Proxy, PathScripts.PathJob.ObjectJob):

Cannot access attribute 'Proxy' of deleted object

=================================================



OS: Linux Mint 19 (X-Cinnamon/cinnamon)
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19. (daily release date 2019/12/20 15:07:31)
Build type: Release
Python version: 3.6.9
Qt version: 5.9.5
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: Dutch/Belgium (nl_BE)
eddyverl
Posts: 9
Joined: Wed Oct 30, 2019 10:17 am
Location: Belgium

Re: problem with the finish pass in pocket when milling a b-spline or ellipse

Postby eddyverl » Wed Dec 25, 2019 6:44 pm

After more testing ...

Forget about the extra info: that error must have another cause.

The main problem stays.
The program is perfectly capable of building the toolpaths during the pre-cutting operation and yet it does not perform the finishing operation.
And this error only happens with certain curves such as b-spline and ellipse.
chrisb
Posts: 22532
Joined: Tue Mar 17, 2015 9:14 am

Re: problem with the finish pass in pocket when milling a b-spline or ellipse

Postby chrisb » Wed Dec 25, 2019 11:43 pm

We have seen similar issues with B-splines recently. You will have to wait until mlampert finds the time to look at it.
eddyverl
Posts: 9
Joined: Wed Oct 30, 2019 10:17 am
Location: Belgium

Re: problem with the finish pass in pocket when milling a b-spline or ellipse

Postby eddyverl » Tue Jan 21, 2020 4:54 pm

The short story:
I have a proposal.

In the freecad source /src/Mod/Path/App/Area.cpp:

Line 1406:
double zNew = zMin + myParams.SectionTolerance;

Change it to:
double zNew = zMin + myParams.SectionTolerance + 0.00001;

(There are similar lines of code (1370, 1376, 1411) but I've not experienced problems with them.)


The long story:
I had already found that with a finish of 0.0001 it was possible to actually obtain a path at 0.0001 mm from the bottom.
So the problem would not be caused by the calculation of the curve.
I then studied the source code. It seems, from the comments, that there have been problems with the vertical tolerances in the past.
A workaround has been made and that solves the problem for the classic paths, but apparently not for curves.
In the existing workaround the bottom path is elevated by the tolerance (value 1e-06) about 0.0025 mm. (so from z=0 to z = 1e-06)
Now I have found that the same workaround also works with curves when you increase the existing correction value by at least 0.00001 mm.
A negligible difference.

I also can imagine that, for someone with more knowledge of this software, this can be a hint towards another solution.

Eddy

OS: Linux Mint 19 (X-Cinnamon/cinnamon)
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19. from source 2020-01-21
Build type: Unknown
Python version: 3.6.9
Qt version: 5.9.5
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: Dutch/Belgium (nl_BE)
User avatar
freman
Posts: 939
Joined: Tue Nov 27, 2018 10:30 pm

Re: problem with the finish pass in pocket when milling a b-spline or ellipse

Postby freman » Wed Jan 22, 2020 6:11 pm

Here an image of [a] pocket operation with an additional profile cut. The profile cut is deeper.
I found this profiling an ellipse last week and thought it was me or machine inaccuracy ! Good catch.

How about trying with a circle? A circle seems to get broken up anyway. An ellipse is just a set or arcs so maybe the presence of just one non-arc is needed.

Code: Select all

Change it to:
double zNew = zMin + myParams.SectionTolerance + 0.00001;
I'd guess that when this is converted to Gcode, as similar test is being done but with <= in place of < .
eddyverl
Posts: 9
Joined: Wed Oct 30, 2019 10:17 am
Location: Belgium

Re: problem with the finish pass in pocket when milling a b-spline or ellipse

Postby eddyverl » Sat Jan 25, 2020 1:19 am

@ Freman

Hello

Thank you.
I didn't have problems with parts based on basic lines and arcs or circles.
Additionally I've made a new testmodel with circles and I didn't notice any problems.
Tested with FreeCAD 0.19 and 0.17

Please post the drawing that is causing the problems and I will have a look at it.

Greetings
eddyverl
Posts: 9
Joined: Wed Oct 30, 2019 10:17 am
Location: Belgium

Re: problem with the finish pass in pocket when milling a b-spline or ellipse

Postby eddyverl » Sun Jan 26, 2020 11:19 am

@ freman

Code: Select all

I'd guess that when this is converted to Gcode, as similar test is being done but with <= in place of <
Yes, a difference of 0.0001 usually means just that.

The difference however occurs IMHO before the generation of the Gcode.
I would point in the direction of line 1501 : wires = section.slice(-d);
This related to CrossSection.cpp and further to OpenCascade.
And there it ends for humble me.

Anyway, the main problem is the need for the workaround.
The workaround creates a usable path but it's a bit elevated above the bottom.
Fine by me, but theoretically it might be better that the resulting wire would be transformed to the correct height.


Note: the Area.cpp has been altered recently. The first mentioned line 1406 has thereby been shifted to 1434.

I'll wait a few day's and if there is no reaction I'll report it to the bug-tracker.
User avatar
freman
Posts: 939
Joined: Tue Nov 27, 2018 10:30 pm

Re: problem with the finish pass in pocket when milling a b-spline or ellipse

Postby freman » Sun Jan 26, 2020 2:22 pm

Thanks.

How does this 0.0001 relate to Job geometry tolerance ? I think this tiny offset should use or be related to a named constant, not the rather arbitrary small value you tested.

Does the workaround still work if the user has increased the tolerance?
Could this tweak value be the std "very small number" ( 1e-9 ?? ) constant? That would probably mean that the arithmetic avoids the issue without producing a detectable height difference.

If the bottom line is a difference with OCC and there is an understandable reticence to diving down that rabbit hole, would it be possible to align FC comparison operator with the one used in OCC ( which I guess can be inferred from testing without plunging into the source )? If both used the same comparison it would truly resolve the issue rather than needing a work around.

I hope those comments make sense in context of the code.

Thanks for shedding some light on what is happening here.
eddyverl
Posts: 9
Joined: Wed Oct 30, 2019 10:17 am
Location: Belgium

Re: problem with the finish pass in pocket when milling a b-spline or ellipse

Postby eddyverl » Wed Jan 29, 2020 1:57 pm

@freman

To be clear. I'm just a user who has stumbled over that problem.
I was testing shapes based an SVG drawing. And there it turned out that the finishing cut (or the final cut) was NOT carried out on splines and ellipses.
I do have a programming experience but only a limited knowledge of Python and absolutely no experience in C / C++.
For me pointing out the problem and suggesting something that could help, was enough.

Chrisb answerred that this was probably related to general problems with B-splines. And that this had to wait.

But obviously the calculation of the B-splines of the sides of the pocket was no problem.
And the bottom has the same curve, only with another z-value.
So I started exploring for another cause. And so I ended up in file Area.cpp.


#====================== Some info about the code in Area.cpp ===================

This code is written with 3D in mind. It builds the wires of a section - like a waterline.

In 2.5D you calculate only one wire and you translate that to the z-value of each step.
In 3D you have to calculate a wire for each single step.

In a pocket FreeCAD has apparently no problem to calculate the wires (splines) along the sides.
The curves are simply discretized into linear segments, not to biarcs. (line 440)

But when FreeCAD reaches a place where faces have been stitched, then there seem to be troubles.
In case of a pocket that is the bottom. (And maybe the top in case of inside turning)

These problems are known. See remarks at line 337, 851,

#====================== The existing workaround ===============================

In Area.cpp there is already a "workaround" for the know problems, and also a retry-section.

Without this workaround the error of no final cut ALSO occurs with 'normal' machine operations (with straight lines, arcs and circles).

This is it:

Code: Select all

            if(z-zMin<myParams.SectionTolerance) {
                if(hitMin) continue;
                hitMin = true;
                double zNew = zMin+myParams.SectionTolerance;   # HERE for the bottom!
                AREA_WARN("hit bottom " <<z<<','<<zMin<<','<<zNew);
                z = zNew;
            }else if (zMax-z<myParams.SectionTolerance) {
                if(hitMax) continue;
                double zNew = zMax-myParams.SectionTolerance;
                AREA_WARN("hit top " <<z<<','<<zMax<<','<<zNew);
                z = zNew;
            }
MyParams.SectionTolerance is the supplied parameter with as default value of 1e-06. See here in log:

Code: Select all

Msg: PathAreaOp.DEBUG: Area with params: {'Tolerance': 1e-07, 'FitArcs': True, 'Simplify': False, 'CleanDistance': 0.0, 'Accuracy': 0.01, 'Unit': 1.0, 'MinArcPoints': 4, 'MaxArcPoints': 100, 'ClipperScale': 10000000.0, 'Fill': 0, 'Coplanar': 0, 'Reorient': True, 'Outline': False, 'Explode': False, 'OpenMode': 0, 'Deflection': 0.01, 'SubjectFill': 0, 'ClipFill': 0, 'Offset': 0.0, 'ExtraPass': 0, 'Stepover': 0.0, 'LastStepover': 0.0, 'JoinType': 0, 'EndType': 0, 'MiterLimit': 2.0, 'RoundPrecision': 0.0, 'PocketMode': 1, 'ToolRadius': 2.5, 'PocketExtraOffset': 0.0, 'PocketStepover': 5.0, 'PocketLastStepover': 0.0, 'FromCenter': True, 'Angle': 45.0, 'AngleShift': 0.0, 'Shift': 0.0, 'Thicken': False, 'SectionCount': -1, 'Stepdown': 1.0, 'SectionOffset': 0.0, 'SectionTolerance': 1e-06, 'SectionMode': 2, 'Project': False}

This existing workaround does NOT help with splines and ellipses.
It does however work if with a much increased value.
Hence my initial hint to add 0.00001 mm in the workaround. Which is 10 times the value of MyParams.SectionTolerance
But even bigger values will be made possible in my final proposal.

#======================= the retry section =====================================

There is also a retry section in the code: (at line 1561)

Code: Select all

            if(retried) {
                AREA_WARN("Discard empty section");
                break;
            }else{
                AREA_TRACE("retry section " <<z<<"->"<<z+tolerance);
                z += tolerance;
                retried = true;
            }
I suppose this was an attempt to solve the remaining problems.
Only this doesn't work because the correction-value is to small,
and also - due to an oversight - the var "tolerance" stays at the initial zero.


#======================= final proposal ========================================

I now propose to change this existing retry-section code

with as following result:
- shapes that caused NO problems in the past, will have exactly the same result.
- the first retry will be comparable with the existing retry (tolerance in heights.empty() * 2)
- only after that there CAN be extra retries with more 'brutal' augmenting z-values

The z-tolerance - tests
The normal z-deviation for a curve is 0.000012 at retry=2.
The z-deviation was 0.001112 mm at retry = 4 for a curve bigger than 2m by 1m

#==============================================================================
For those who have problems with these z-deviations (only with splines)...
I suppose it's possible:
- to correct the z-deviation when generating the gcode of the last cut
- or to translate the resulting wires to the correct z-value.
And anyway, the current error - no last cut - is far much worse.

@ freman
Due to your remarks about "why the value 0.00001" and the influence of tolerances, I've decided to use 'MyParams.SectionTolerance' as base-value.



#===============================================================================
I'll report my patch to the bugtracker. And here this ends for me.
This is it :

line 1463 :

Code: Select all

  	bool can_retry = fabs(tolerance)>Precision::Confusion();
replace with:

Code: Select all

	// bool can_retry = fabs(tolerance)>Precision::Confusion();
line 1468 :

Code: Select all

		bool retried = !can_retry;
replace with:

Code: Select all

		int retried = 0;
		double addedz = myParams.SectionTolerance / 10;
finally replace the above mentioned retry-setion at line 1561 by:

Code: Select all

            if(retried==5) {
                AREA_WARN("Discard empty section");
                break;
            }else{
                retried++;
                AREA_TRACE("retry section " <<z<<"->"<<z+addedz*10);
                addedz = addedz * 10;    
                z = z + addedz;                
            }
 
Note that I haven't touched the var tolerance.
User avatar
freman
Posts: 939
Joined: Tue Nov 27, 2018 10:30 pm

Re: problem with the finish pass in pocket when milling a b-spline or ellipse

Postby freman » Fri Jan 31, 2020 4:49 pm

thanks for the input to this problem. I've got distracted in the python code at the moment. I'll have a look at this when I have some more free time. If it fixes your case it's an improvement. That's great.