@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 :

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.