PathScript improvements.

Here's the place for discussion related to CAM/CNC and the development of the Path module.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
onekk
Veteran
Posts: 6097
Joined: Sat Jan 17, 2015 7:48 am
Contact:

PathScript improvements.

Post by onekk »

This post is mainly to open a discussion on how to improve PathScript code.

So like an absolute beginner (I have gave an eye to the code, but I can't guess the exact work) I ask developers to explain some more about, how code is working?

Hoping this will start a constructive discussion that lead to some improvements, on Path in general and a better "Path scriptability".

TIA and Regards.

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
sliptonic
Veteran
Posts: 3453
Joined: Tue Oct 25, 2011 10:46 pm
Location: Columbia, Missouri
Contact:

Re: PathScript improvements.

Post by sliptonic »

Just to clarify, 'PathScripts' is a directory where most of the existing python code for the path workbench lives. This topic is about improving the script-ability of the Path workbench as a whole.

There are a couple concepts that it might be worth discussing, like what exactly is meant by "script-ability".

FreeCAD has the ability to run headless in a server environment without loading the GUI at all. When mlampert did the big refactor and cleanup a couple years ago, there was a lot of effort given to separating the path logic from the gui logic so that path functions could be managed in this mode. There were two reasons for doing this:
First, being able to run FreeCAD headless is competitive advantage over closed source alternatives. Using closed source CAM in a custom toolchain is dangerous because the vendor can change terms or code and pull the rug out from under you. Open-source has an advantage here.
Second, besides leading to cleaner and more modular code, it also leads to more 'FreeCADish' code.

But a lot of people mean something different when talking about scripting. They mean the ability to script the GUI and streamline workflow with macros or other custom tools. Much less effort has been spent on this. That might be my fault. In my opinion, it's still too early to worry about that level of optimization. For the same reason we haven't spent much effort on other kinds of 'wizards' to speed up tasks. That kind of UI sugar is good but it usually follows after the core UI concepts have stabilized.

I think improving this kind of scriptability is a good goal, but I'll balk if we start putting in things that limit how we can change the UI. If people build elaborate workflows to work around bad UI design, then I think we're better served by changing the UI. Also, I don't want to try maintaining backward compatibility because some part of the user base got comfortable with their scripts.

Does that make sense?
User avatar
onekk
Veteran
Posts: 6097
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: PathScript improvements.

Post by onekk »

sliptonic wrote: Fri Nov 26, 2021 8:46 pm Does that make sense?
Yes and No.

Yes for the part on not to Script mimicking GUI with scripting.

No for the part that underlying the Gui there will be real Python methods that could be called by a Script, without trying to mimic the Gui.

Same that as been done by Russel Johnson when I've posed the problem of the Gui firing up when I scripted a new Job.

He had made a Job.Create() method that is scriptable and permit to create Job and assign operation to this job.

obviously I have to assign properties properly, but this is not a problem, only some lines that could be be managed by writing some helper methods, how much long are not a problem.

When you call the method from the Gui you have to pass the proper parameters too.

But for every operation there should be a way to be scriptable.

A little example:

I wanto to script a dressup operation to make holding tabs.

I should have a method to alter tab positions and to make so I should have maybe some ways of determine this position from the original shape.

if you expose tabs as coordinates, they are not surviving a recompute or a tool change as they are related to the ToolPath that depends on tool diameter and maybe roughing and finishing things (maybe i want a material allowance on roughing and a more precise tolerance when finishing).

if you expose them as function of the original shape, say i want tabs at 0.33, 0.66, 0.99 of the perimeter of the original shape, it will survive to a toll change or even in some form a shape modification (in the most easy case when i alter a regular shape, i.e an hexagon and I don't want the tabs are in the corners).

As usual I've in mind my plywood cutting work, so this approach could make no sense for other cases, but i thing that plywood cutting (or similar sheet cutting task) is not too exotic to be a "rare used" case.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
onekk
Veteran
Posts: 6097
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: PathScript improvements.

Post by onekk »

To start some discussion:

From PathScripts Job sources:

Code: Select all

def Create(name, base, templateFile=None):
    """Create(name, base, templateFile=None) ... creates a new job and all it's resources.
    If a template file is specified the new job is initialized with the values from the template."""
....
    return obj

Some MWE to test Job Creation.
NOTE ON MWE: my MWE are complete, in other word could be simply copied in a file with a .py as extension and loaded into FreeCAD directly.

It will fire up the "Macro Editor" and here you could launch it, many part of the code is "wasted" in some service jobs, like create and delete things in a determined document named according to "DOC_NAME" variable.

This way incremental modification will not pollute FreeCAD with many files named name1, name2, name3 and so on.

If anoyone know a better way, please feel free to provide an alternative example. (TIA if there will some code contributed for this scope)

Code: Select all

"""test_path.py

   This code was written as an sample code 
     
   Author: Carlo Dormeletti
   Copyright: 2021
   Licence: CC BY-NC-ND 4.0 IT 
"""

import os
import os.path

import FreeCAD
from FreeCAD import Base, Rotation, Vector
import Part
import Path
import Draft

from PathScripts import PathJob
from PathScripts import PathJobGui


DOC_NAME = "job_example"
gcodePath = os.path.expanduser('~/test-job.ngc')
    
DOC = FreeCAD.activeDocument()


def clear_doc():
    """
    Clear the active document deleting all the objects
    """
    for obj in DOC.Objects:
        try:
            DOC.removeObject(obj.Name)
        except Exception:
            pass

def create_doc(doc_name):
    obj = FreeCAD.newDocument(doc_name)
    return obj.Name

def setview():
    """Rearrange View"""
    DOC.recompute()
    VIEW.viewAxometric()
    VIEW.setAxisCross(True)
    VIEW.fitAll()

print(DOC)

if DOC is None:
    obj = create_doc(DOC_NAME)
    FreeCAD.setActiveDocument(obj)
    DOC = FreeCAD.activeDocument()
    VIEW = FreeCAD.Gui.ActiveDocument.ActiveView

else:
    if DOC.Name != DOC_NAME:
        obj = create_doc(DOC_NAME)
        FreeCAD.setActiveDocument(obj)
        DOC = FreeCAD.activeDocument()
        VIEW = FreeCAD.Gui.ActiveDocument.ActiveView
    else:
        DOC = FreeCAD.activeDocument()
        clear_doc()


EPS = 0.10
EPS_C = EPS * -0.5

VZOR = Vector(0,0,0)
RZO = Rotation(0, 0, 0)

box0 = DOC.addObject('Part::Box', 'Box')
box0.Width = 1
box0.Length = 1
box0.Height = 1

DOC.recompute()

job = PathJob.Create('Job', [box0], None)
job.ViewObject.Proxy = PathJobGui.ViewProvider(job.ViewObject)

job.recompute()

job.PostProcessorOutputFile = gcodePath
job.PostProcessor = 'grbl'
job.PostProcessorArgs = '--no-show-editor'

# set some common data
job.SetupSheet.Label = "Custom SS"
job.SetupSheet.HorizRapid = '10 mm/s'
job.SetupSheet.VertRapid = '1 mm/s'

job.recompute()

DOC.recompute()

print("--- done ---")
This is only to see how scriptability work, and maybe where are the "critical point".

Maybe if @sliptonic could explain for what base "model" is used for?

I have done many of my script work setting it simply as a cube of 1,1,1 dims and everything has worked fine.

(Sorry @sliptonic, it can't get in my mind, maybe here, as a forum message, that could maybe became a future wiki page, explanation is more "persistent")

From what I could remember, model was used to determine "model orientation" and maybe something related to "tolerance". But I don't count too much on my memory.


Best Regards and TIA to @sliptonic for explanation and help.

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
sliptonic
Veteran
Posts: 3453
Joined: Tue Oct 25, 2011 10:46 pm
Location: Columbia, Missouri
Contact:

Re: PathScript improvements.

Post by sliptonic »

onekk wrote: Tue Dec 07, 2021 10:37 am Some MWE to test Job Creation.
What is 'MWE' ?
Maryland Worforce Exchange?
Megawatt Electrical?
Modeled Wage Estimates?

Please don't use unusual terminology and especially acronyms without defining.
This is only to see how scriptability work, and maybe where are the "critical point".
Remember that your code is communication to other developers. The computer only cares about the byte code from compilation. So use descriptive variable names. Variable like EPS, EPS_C, VZOR, RZO are hard to interpret. Use pep8 styling for python. All caps implies globals.
Maybe if @sliptonic could explain for what base "model" is used for?
Do you bean the base model in the Job?

The job models are the solid models that the job will work on. They are clones of the original solids. Their orientation relative to the global coordinate system (and each other) is the layout that all coordinates will be calculated from. The individual operations store base geometry that references these models.
User avatar
onekk
Veteran
Posts: 6097
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: PathScript improvements.

Post by onekk »

sliptonic wrote: Tue Dec 07, 2021 5:00 pm What is 'MWE' ?

Please don't use unusual terminology and especially acronyms without defining.
MWE is usually interpreted as Minimal Working Example, is almost universally know in many forums, like Tex and similar to be a minimal code that show the behaviour when talking about errors or examples.

Although is not very minimal, due to some "helpers methods" that permit a better handling of experimentation when using the code, like the clear_doc() and setview() methods added to show things (setview is not used here, an error.)
sliptonic wrote: Tue Dec 07, 2021 5:00 pm Remember that your code is communication to other developers. The computer only cares about the byte code from compilation. So use descriptive
variable names. Variable like EPS, EPS_C, VZOR, RZO are hard to interpret. Use pep8 styling for python. All caps implies globals.

Yes this is a mere way to show (conventional lengths) like a VZOR as a zero vector (Vector(0, 0, 0) and ROT0 as Rotation(0,0,0), they are used many times in code (or I use them many times) so I have used some "shortcuts" for "predefined lengths", not exactly global costants, but they are used as a similar concept (They are the same in every use).

EPS and EPS_C are simply a tolerance to give an intersection when fusing, EPS, and when cutting for holes EPS_C is half of EPS in negative to make proper cuts.

I admit they are not very PEP8, Sorry!
sliptonic wrote: Tue Dec 07, 2021 5:00 pm Do you bean the base model in the Job?

The job models are the solid models that the job will work on. They are clones of the original solids. Their orientation relative to the global coordinate system (and each other) is the layout that all coordinates will be calculated from. The individual operations store base geometry that references these models.
Thanks, but as I set them as a little Box oriented to the "usual way" (again not a precise term, only a shortcut) it will be used only to determine the orientation.

Let me try to figure out model use: if I have a solid say a cube and I want to mill one of the side faces, if I gave the face to be milled as model, all the coordinates will be rotated to have the side face up, to permit to cut them on a 3 axis CNC with the usual orientation?

Again sorry for rudeness, only to have a more clear idea, as I hope this will became maybe something different like a wiki page for beginner when scripting Path (in a not so near future).

Thanks

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
sliptonic
Veteran
Posts: 3453
Joined: Tue Oct 25, 2011 10:46 pm
Location: Columbia, Missouri
Contact:

Re: PathScript improvements.

Post by sliptonic »

onekk wrote: Tue Dec 07, 2021 5:20 pm
Thanks, but as I set them as a little Box oriented to the "usual way" (again not a precise term, only a shortcut) it will be used only to determine the orientation.

Let me try to figure out model use: if I have a solid say a cube and I want to mill one of the side faces, if I gave the face to be milled as model, all the coordinates will be rotated to have the side face up, to permit to cut them on a 3 axis CNC with the usual orientation?
You cannot give the face as a model. The whole cube is a model. The cube's orientation is its orientation on the machine. That is to say the +Z axis in FreeCAD is going to map to the +Z axis on your machine.

So if you want to mill the 'front' of a cube on a 3 axis machine, you must rotate the model. Then select the individual face as a base geometry in the operation.

How the operations access geometry sub-elements will need to change for 3+2 milling but the initial position of the model will still establish its position relative to the machine coordinate system.
Again sorry for rudeness, only to have a more clear idea, as I hope this will became maybe something different like a wiki page for beginner when scripting Path (in a not so near future).
No apology necessary. No rudeness detected.
User avatar
onekk
Veteran
Posts: 6097
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: PathScript improvements.

Post by onekk »

sliptonic wrote: Tue Dec 07, 2021 5:34 pm No apology necessary. No rudeness detected.
"rudeness" of explication, meaning "not very polished way" as usual English is not my mother language, so explaining complex concepts having in mind a specific language very different in syntax will be challenging for me and for other readers.

Thanks for the explication about the model.

A part for the orientation, model is used for other scopes, as when I'm dealing with Path, I usually put a simple "minimal length cube" as model, and then pass the real faces as "arguments" of "job operations".

Is this "brute" approach very wrong, and could lead to "big errors"?

I have in mind simple "woodworking scenarios" with plywood cutting with a 3 axis hobby machine, as I have no mean to experiments with other "more professional" machines, and all "my writings" about CNC, programs and example included, will be limited to those "limited scenario".

TIA and Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
sliptonic
Veteran
Posts: 3453
Joined: Tue Oct 25, 2011 10:46 pm
Location: Columbia, Missouri
Contact:

Re: PathScript improvements.

Post by sliptonic »

onekk wrote: Tue Dec 07, 2021 5:44 pm
A part for the orientation, model is used for other scopes, as when I'm dealing with Path, I usually put a simple "minimal length cube" as model, and then pass the real faces as "arguments" of "job operations".

Is this "brute" approach very wrong, and could lead to "big errors"?
No, this is fine. At least if I understand correctly.

Imagine you're building a box from plywood. The sides of the box are individual solids. Their orientation in the document is how they would be oriented relative to each other to make the box.

However, their orientation in the job is how they would be placed to be cut. They would all be laid flat and moved around to minimize stock usage. We don't want to disturb the original orientation so we make clones of the shapes and move those in the job to establish the setup.

Maybe only some of the pieces have holes for drilling. Just the faces from those parts would need to be passed to the drilling operation while all of the shapes might need to be passed to the profile operation for cutout.

So base geometry at the job level is whole solids.

Base geometry at the operation level is stored usually as a list of tuples [(solid1, ["Face2"])] for example. That's a list where each element is a tuple of solid object and a list of sub-elements.
User avatar
onekk
Veteran
Posts: 6097
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: PathScript improvements.

Post by onekk »

In fact I have in mind this sort of final arrangement:
paths.png
paths.png (35.89 KiB) Viewed 2052 times
Objects are simply wires and or better a "zero height faces" as wire are not accepted as solids and final height (depth in this case) are "assigned" in proper places.

It's a "bad" illustration for a future "path scripting guide" I have in mind.

Many Thanks and Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Post Reply