Creating a standalone Python program to create a complex collection of objects

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
RobertPHeller
Posts: 38
Joined: Sat May 30, 2020 7:22 pm
Location: Wendell, MA USA
Contact:

Creating a standalone Python program to create a complex collection of objects

Post by RobertPHeller »

OK, I am new to FreeCAD and Python. I have writted a Tcl program (with some 27 Tcl files) that generate a datafile for gCAD3d. It works, BUT gCAD3d is flakey (or at least the version I have, which is probably old). I would like to change everything over to FreeCAD (which seems not to be flakey), but that means translating the Tcl code to Python (which I guess I can manage). I have main question: do I have to run the program inside FreeCAD or is it possible to create a standalone Python program that I can run from the Linux command line? I am also having a hard time dealing with the FreeCAD GUI, so I would like to avoid having to deal with as much as possible.
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
heller@deepsoft.com -- Webhosting Services
User avatar
PrzemoF
Veteran
Posts: 3520
Joined: Fri Jul 25, 2014 4:52 pm
Contact:

Re: Creating a standalone Python program to create a complex collection of objects

Post by PrzemoF »

Welcome to the forum!

Start here: https://wiki.freecadweb.org/Python and here https://wiki.freecadweb.org/Power_users_hub
You can run macros from command line or you can import FreeCAD into python. Possibilities are endless ;) but not everything is accessible from python. If you find something that is not - it's worth to ask for it, maybe someone can add it quickly.
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Creating a standalone Python program to create a complex collection of objects

Post by vocx »

RobertPHeller wrote: Sat May 30, 2020 7:58 pm ... that generate a datafile for gCAD3d....
What exact type of information do you have in this data file? Is it just text? Is it just geometrical data? Does it include specific code that is meant to interact with the gCAD3d software? So you'd need the equivalent code for FreeCAD?

You can use FreeCAD as a library, meaning that you don't need to use FreeCAD's interface at all.

Code: Select all

# my_file.py
import FreeCAD as App

doc = App.newDocument()
...
You can then run the script using the freecad executable as a Python interpreter.

Code: Select all

freecad my_file.py
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
RobertPHeller
Posts: 38
Joined: Sat May 30, 2020 7:22 pm
Location: Wendell, MA USA
Contact:

Re: Creating a standalone Python program to create a complex collection of objects

Post by RobertPHeller »

The Tcl files contain SNIT types (like Python classes) that are used to generate a gCAD3D data file (contains gCAD3D commands to create 3D objects), and also other things like SVG and PostScript files giving cut and drill patterns, and a CSV file containing a BOM of pieces of wood.

Being able to run the program standalone will be necessary, since Python does not have a way to unload code that was "imported" except by termination of the Python interpreter. While I am in the process of recoding it, it is a terrible pain to have to shutdown and restart FreeCAD's Gui.
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
heller@deepsoft.com -- Webhosting Services
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Creating a standalone Python program to create a complex collection of objects

Post by vocx »

RobertPHeller wrote: Sun May 31, 2020 4:30 am ...
since Python does not have a way to unload code that was "imported" except by termination of the Python interpreter. ...
I'm not sure I'm understanding you. Python can of course reload imported modules (see importlib.reload), if you wish to test your code while you do modifications. It's not very common but it can be done. But those modules shouldn't be connected to the graphical interface, because that is trickier. But simple modules that define functions and classes, sure they can be reloaded.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
onekk
Veteran
Posts: 6222
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Creating a standalone Python program to create a complex collection of objects

Post by onekk »

importlib has some quirks, if you are developing a complex objects, it doesn't update correctly the library.

Let me explain:

If you ave a single python file containing the library, using importlib reload works, it reloads the single file if it is modified outside freecad (generally i develop using and IDE and open only the "part build file", in freecad to launch the script to make the complex solid)

If you split the library in many file, so the main file that import some methods from other files (in my case in the same library directory), the importlib will reload only the "main file" the modification you do in the children files are not taken in account.

THe only way I've found is to place in the main file:

Code: Select all

import importlib

...

importlib.invalidate_caches() # maybe is not needed

import mudule1
importlib.reload(module1)
import module2
importlib.reload(module2)
import module3
importlib.reload(module3)

from module1 import *
from module2 import *
from module3 import *

...
For making the thing working you have to use a similar code in the imported "modules"

Code: Select all

## ##

__all__ = [<list of exportable methods>]

def method1:
...

def method2:
...

def method3:
...
i.e if you have

Code: Select all

__all__ = ["method1", "method2"]
Note the strings with the methods names.

only method1 and method2 are visible when doing

from your_ext_module import *

It is slightly involute but in this manner you can split the library in many different "and smaller" files, and when using "importlib reload" it will work.

At least with FC 0.19 that use python 3.8.

Many things are evolving in the import methods and in the importlib "Python library" some thing have been deprecated and some other things have a slightly modified the "standard" behaviour.

Hope it helps

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