Waterline milling update
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
Waterline milling update
I've refined an approach to this that seems largely workable. The algo is quite similar to prior approaches I've looked at, with some refinements.
In broad brushstrokes:
1. Bound the part of the face available to mill from top, and creating a 2d stock-top closed wire based on that shape.
2. This allows any toolpath pattern to be generated on the stock-top, and then projected down onto the surface.
3. The projected wires are then discretized and new wires offset according to tool geometry are generated.
4. Use Path FromShape to generate actual tool paths.
There are specifics to make this work dependent on how well existing FreeCAD functions perform. For example, in theory, the tool pattern wires could be truly projected onto the surfaces, but in practice, this doesn't perform reliably for all wire sections, so I have shifted to extruding the pattern through the Face. There again, in theory, Common, Slice, and Section should all work well to determine the 3d surface wires, but in practice, common is unreliable, and Slice and Section both work well.
Also, there are details in the settings of the FromShape that are critical to ensuring the results do not violate the model.
I have this working for external/convex Sphere/Cylinder/Cone/Plane shape and am about to implement Torus. Essentially any tool tip geometry can be used by offset is generated along normal or XY portion of normal...
At moment, it is much slower (30-40 seconds to handle several faces) than it can be. It is slow because I don't know how to calculate the BSpline myself and am now using the Draft.makeBSpline which draws each tool-wire sequentially. I need to ask Yorik how he does this--I've looked at his code but not fully understanding it yet.
There is much to do, but I think this is promising. Note that it does not yet account for collet/shank/tool-length violations or face/face violations. Much of that should be relatively straight-forward as much can be done on the stock-top 2d level. Also, output results are all G1 due to BSplines, but the someedge.Cuve.toBiArcs() could fix this at some point.
Best,
Josh
In broad brushstrokes:
1. Bound the part of the face available to mill from top, and creating a 2d stock-top closed wire based on that shape.
2. This allows any toolpath pattern to be generated on the stock-top, and then projected down onto the surface.
3. The projected wires are then discretized and new wires offset according to tool geometry are generated.
4. Use Path FromShape to generate actual tool paths.
There are specifics to make this work dependent on how well existing FreeCAD functions perform. For example, in theory, the tool pattern wires could be truly projected onto the surfaces, but in practice, this doesn't perform reliably for all wire sections, so I have shifted to extruding the pattern through the Face. There again, in theory, Common, Slice, and Section should all work well to determine the 3d surface wires, but in practice, common is unreliable, and Slice and Section both work well.
Also, there are details in the settings of the FromShape that are critical to ensuring the results do not violate the model.
I have this working for external/convex Sphere/Cylinder/Cone/Plane shape and am about to implement Torus. Essentially any tool tip geometry can be used by offset is generated along normal or XY portion of normal...
At moment, it is much slower (30-40 seconds to handle several faces) than it can be. It is slow because I don't know how to calculate the BSpline myself and am now using the Draft.makeBSpline which draws each tool-wire sequentially. I need to ask Yorik how he does this--I've looked at his code but not fully understanding it yet.
There is much to do, but I think this is promising. Note that it does not yet account for collet/shank/tool-length violations or face/face violations. Much of that should be relatively straight-forward as much can be done on the stock-top 2d level. Also, output results are all G1 due to BSplines, but the someedge.Cuve.toBiArcs() could fix this at some point.
Best,
Josh
- Attachments
-
- Top3dMilling.FCMACRO
- (47.09 KiB) Downloaded 111 times
Re: Waterline milling update
Here's an example, in pictures:
The Job is a sphere cut by a cylinder: Only the top hemisphere is able to be milled: The outline is "projected" onto the stock-top height as a 2d closed wire: A Toolpath "Pattern" seed is generated--here, a zig-zag.
The Job is a sphere cut by a cylinder: Only the top hemisphere is able to be milled: The outline is "projected" onto the stock-top height as a 2d closed wire: A Toolpath "Pattern" seed is generated--here, a zig-zag.
Re: Waterline milling update
Here, the Toolpath Pattern is Extruded through the upper Solid of the Sliced Job model. This works reliably where parallel projecting of edges fails in some instances. It also works on Plane-objects, across all cases, where directly generating planar toolpatterns on the surface fails as in some instances, the surfaces deviate from the XY plane, mis-aligning the results with the Job Model.
The intersection of the Extrusion and the Face. Slicing and Sectioning both work well. Common fails often. This is the "Seed Pattern" used to generate the Toolpath wires.
Here, the Path FromShape generates the Tool Paths. I had to play around with the default settings for some variables to ensure the toolpaths do not violate the Job model in any case. Specifically, the .Retraction, is set to move to the stock-top height. Also, the .SortMode is set to "3d". And, very important is that the .MinDistance is raised from 0.0000000 to 1e-5.
Re: Waterline milling update
At the moment, because of the BSpline draw time, the operation is fairly slow, so while playing with it, I have set the Step-Over at 50% of the tool-radius.
Here's a Large Cone, and we see the good and the unfinished. Note the two plane-object faces due to the partial cone. The one facing "downward" is ignored--correctly. The one facing "upward" is incorrectly included, despite being shadowed by the Cone body.
Here's a Large Cone, and we see the good and the unfinished. Note the two plane-object faces due to the partial cone. The one facing "downward" is ignored--correctly. The one facing "upward" is incorrectly included, despite being shadowed by the Cone body.
Re: Waterline milling update
Here's an example of what I alluded to when I mention that Plane Objects can get skewed in some cases. Here, I selected the edges of a planar side wall and the result is misaligned. Interesting, as the Edges generated by this are correct...
Note that if I grab the Face itself, instead of the outer edges of the Face, the result is correct.
Re: Waterline milling update
Preliminary Toroid Object looks promising. Here's an example of it in 50% step-over:
and at 25% step-over:
Re: Waterline milling update
I fixed a few things--toroid basis was one. I'm very pleased how this is looking. Here's a more complex shape--a toroid at an angle, cut by sphere, cone, and cylinder.
Here it is with 25% step-over: And here with 12.5% step-over. The process times were 121 and 234 seconds, but I hope to drop that by learning BSpllne definition.
Happy New Year!
Here it is with 25% step-over: And here with 12.5% step-over. The process times were 121 and 234 seconds, but I hope to drop that by learning BSpllne definition.
Happy New Year!
- Attachments
-
- PlaneToolPaths_13.png (237.34 KiB) Viewed 3712 times
Re: Waterline milling update
And here's another example, of a relatively complex ramped shape with a 5mm square mill at 12.5%.
- Attachments
-
- Top3dMilling.FCMACRO
- (48.54 KiB) Downloaded 90 times
Re: Waterline milling update
All this looks very interesting. I'm eager to get my mill fixed - that's one of the big tasks of this year.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
-
- Posts: 74
- Joined: Tue Oct 23, 2018 3:35 pm
Re: Waterline milling update
Amazing what can be done in Python. Almost don't need the C++ for most of the complicated things.
This script didn't work in my version 0.18.15481.
I had to change line 626 from:
self.JobModel = self.JobSelected.Base
to:
self.JobModel = self.JobSelected.Model.Group[0]
Is this a recent change which allows path to operate on sets of models instead of just a single model?
There are a lot of components in this huge macro that could be useful if broken out, such as helping to make a Python version of the Area::toPath() function in src/Mod/Path/App/Area.cpp so it's easier to control what it is doing.
What you have implemented seems to be Single Surface Machining. It works by finding a path in the parametric face of the model and then projecting out by the normals to find the tool position.
The problem with it is that the projected tool positions from one surface can end up gouging into one of the other surfaces. Programmers of the day made numerous attempts to fix this with things like Gouge Protection (trimming out the parts of the surface that intersected the other surfaces), and then stitching together the toolpaths from each surface. There are insurmountable difficulties with any sharp corners because there are long section of toolpath corresponding to a single point in the surface.
But none of this worked out robustly until we wrote systems that simply converted all the surfaces into triangles to a tolerance and formed machining toolpaths against those by projecting the points of the 2D shapes in the Drive Surface down in Z to the where a tool at each position was first in contact with any triangles.
This script didn't work in my version 0.18.15481.
I had to change line 626 from:
self.JobModel = self.JobSelected.Base
to:
self.JobModel = self.JobSelected.Model.Group[0]
Is this a recent change which allows path to operate on sets of models instead of just a single model?
There are a lot of components in this huge macro that could be useful if broken out, such as helping to make a Python version of the Area::toPath() function in src/Mod/Path/App/Area.cpp so it's easier to control what it is doing.
What you have implemented seems to be Single Surface Machining. It works by finding a path in the parametric face of the model and then projecting out by the normals to find the tool position.
The problem with it is that the projected tool positions from one surface can end up gouging into one of the other surfaces. Programmers of the day made numerous attempts to fix this with things like Gouge Protection (trimming out the parts of the surface that intersected the other surfaces), and then stitching together the toolpaths from each surface. There are insurmountable difficulties with any sharp corners because there are long section of toolpath corresponding to a single point in the surface.
But none of this worked out robustly until we wrote systems that simply converted all the surfaces into triangles to a tolerance and formed machining toolpaths against those by projecting the points of the 2D shapes in the Drive Surface down in Z to the where a tool at each position was first in contact with any triangles.