CAM Skripten
Einführung
Der Arbeitsbereichen CAM bietet Werkzeuge zum Importieren, Erstellen, Ändern und Exportieren von Bearbeitungs-Werkzeugbahnen in FreeCAD. Mit ihnen kann der Anwender bestehende G-code-Programme importieren, visualisieren und modifizieren, Werkzeugbahnen aus 3D-Formen erstellen und diese Werkzeugbahnen in G-code exportieren.
Der Arbeitsbereich CAM befindet sich derzeit in einer frühen Entwicklungsphase und bietet nicht alle erweiterten Funktionen, die in einigen kommerziellen Alternativen zu finden sind. Die Python-Skript-Schnittstelle macht es jedoch einfach, Werkzeuge zu modifizieren oder leistungsfähigere zu entwickeln.
Schnellstart
Die Pfadobjekte von FreeCAD bestehen aus einer Folge von Bewegungsbefehlen. Eine typische Anwendung ist diese:
>>> import Path
>>> c1 = Path.Command("g1x1")
>>> c2 = Path.Command("g1y4")
>>> c3 = Path.Command("g1 x2 y2") # spaces end newlines are ignored
>>> p = Path.Path([c1,c2,c3])
>>> o = App.ActiveDocument.addObject("Path::Feature","mypath")
>>> o.Path = p
>>> print (p.toGCode())
FreeCADs internes G-Code-Format
Es ist wichtig, ein vorläufiges Konzept zu verstehen. Der Großteil der folgenden Implementierung stützt sich stark auf Bewegungsbefehle, die dieselben Namen wie G-Code-Befehle haben, jedoch nicht auf die Implementierung eines bestimmten Controllers ausgerichtet sind. Namen wie 'G0' für 'Schnellbewegung' oder 'G1' für 'Vorschubbewegung' wurden aus Gründen der Leistungsfähigkeit (effizientes Speichern von Dateien) und zur Minimierung des Aufwands für die Übersetzung in andere G-Code-Formate gewählt. Da es in der CNC-Welt Tausende von G-Code-Dialekten gibt, wurde eine stark vereinfachte Untergruppe davon ausgewählt. Man könnte das G-Code-Format von FreeCAD als eine "maschinenunabhängige" Form des G-Codes beschreiben.
Innerhalb von .FCStd-Dateien werden Pfaddaten direkt in diesem G-Code-Format gespeichert.
Alle Übersetzungen von/in Dialekte zu FreeCAD-G-Code erfolgen über Vor- und Nachbearbeitungsskripte. Das bedeutet, dass man, wenn man mit einer Maschine arbeiten möchte, die einen bestimmten LinuxCNC-, Fanuc-, Mitusubishi- oder HAAS-Controller usw. verwendet, einen Nachbearbeitungsprozessor für diesen bestimmten Controller verwendet (oder erstellt, falls nicht vorhanden) muss (siehe Abschnitt "Importieren und Exportieren von G-Code" weiter unten).
G-Code-Referenz
Die folgenden Regeln und Richtlinien definieren den G-Code-Befehlssatz, den FreeCAD intern benutzt:
- G-Code-Daten innerhalb von FreeCAD-Pfadobjekten sind in "Befehle" unterteilt. Ein Befehl wird durch einen Befehlsnamen definiert, der mit G oder M beginnen muss, und (optional) durch Argumente, die aus einem Buchstaben und einer Fließkommazahl bestehen, zum Beispiel X 0.02 oder Y 3.5 oder F 300. Dies sind Beispiele für typische G-Code-Befehle in FreeCAD:
G0 X2.5 Y0 (Der Befehlsname ist G0, die Argumente sind X=2.5 und Y=0)
G1 X30 (Der Befehlsname ist G1, das einzige Argument its X=30)
G90 (Der Befehlsname ist G90, es gibt keine weiteren Argumente)
- Für den numerischen Teil eines G- oder M-Befehls werden sowohl die Form "G1" als auch "G01" unterstützt.
- Derzeit werden nur Befehle unterstützt, die mit G oder M beginnen.
- Derzeit werden nur Millimeter akzeptiert. G20/G21 werden ignoriert.
- Argumente werden immer alphabetisch sortiert. Das bedeutet, wenn man einen Befehl mit "G1 X2 Y4 F300" erstellt, wird dieser als "G1 F300 X2 Y4" gespeichert.
- Argumente können innerhalb eines Befehls nicht wiederholt werden. Beispielsweise funktioniert "G1 X1 Y2 X2 Y3" nicht. Man muss ihn in zwei Befehle aufteilen, zum Beispiel: "G1 X1 Y2, G1 X2 Y3".
- Die Argumente X, Y, Z, A, B, C sind je nach aktuellem G90/G91-Modus absolut oder relativ. Die Standardeinstellung (sofern nicht anders angegeben) ist absolut.
- I, J, K sind immer relativ zum letzten Punkt. K kann weggelassen werden.
- X, Y oder Z (und A, B, C) können weggelassen werden. In diesem Fall werden die vorherigen X-, Y- oder Z-Koordinaten beibehalten.
- Andere G-Code-Befehle als die in der folgenden Tabelle aufgeführten werden unterstützt, d. h. sie werden in den Pfaddaten gespeichert (sofern sie natürlich den oben genannten Regeln entsprechen), aber sie erzeugen einfach kein sichtbares Ergebnis auf dem Bildschirm. Es könnte beispielsweise einen G81-Befehl hinzugefügt werden, der gespeichert, aber nicht angezeigt wird.
Liste der aktuell unterstützten G-Code Befehle
| Befehl | Beschreibung | Unterstützte Argumente | Angezeigt |
|---|---|---|---|
| G0 | schnelle Bewegung | X,Y,Z,A,B,C | Rot |
| G1 | normale Bewegung | X,Y,Z,A,B,C | Grün |
| G2 | Bogen im Uhrzeigersinn | X,Y,Z,A,B,C,I,J,K | Grün |
| G3 | Bogen gegen den Uhrzeigersinn | X,Y,Z,A,B,C,I,J,K | Grün |
| G81, G82, G83 | Bohren | X,Y,Z,R,Q | Rot/Grün |
| G38.2 | Gerade Sondenbewegung (verwendet im Sondenmodus) | Z,F | Gelb |
| G90 | absolute Koordinaten | ||
| G91 | relative Koordinaten | ||
| (Nachricht) | Kommentar |
Das Befehlsobjekt
Das Command-Objekt repräsentiert einen G-Code-Befehl. Es hat drei Attribute: Name, Parameters (Parameter) und Placement (Positionierung) sowie zwei Methoden: toGCode() und setFromGCode(). Intern enthält es nur einen Namen und ein Wörterbuch mit Parametern. Der Rest (Positionierung und G-Code) wird anhand dieser Daten berechnet.
>>> import Path
>>> c=Path.Command()
>>> c
Command ( )
>>> c.Name = "G1"
>>> c
Command G1 ( )
>>> c.Parameters= {"X":1,"Y":0}
>>> c
Command G1 ( X:1 Y:0 )
>>> c.Parameters
{'Y': 0.0, 'X': 1.0}
>>> c.Parameters= {"X":1,"Y":0.5}
>>> c
Command G1 ( X:1 Y:0.5 )
>>> c.toGCode()
'G1X1Y0.5'
>>> c2=Path.Command("G2")
>>> c2
Command G2 ( )
>>> c3=Path.Command("G1",{"X":34,"Y":1.2})
>>> c3
Command G1 ( X:34 Y:1.2 )
>>> c3.Placement
Placement [Pos=(34,1.2,0), Yaw-Pitch-Roll=(0,0,0)]
>>> c3.toGCode()
'G1X34Y1.2'
>>> c3.setFromGCode("G1X1Y0")
>>> c3
Command G1 [ X:1 Y:0 ]
>>> c4 = Path.Command("G1X4Y5")
>>> c4
Command G1 [ X:4 Y:5 ]
>>> p1 = App.Placement()
>>> p1.Base = App.Vector(3,2,1)
>>> p1
Placement [Pos=(3,2,1), Yaw-Pitch-Roll=(0,0,0)]
>>> c5=Path.Command("g1",p1)
>>> c5
Command G1 [ X:3 Y:2 Z:1 ]
>>> p2=App.Placement()
>>> p2.Base = App.Vector(5,0,0)
>>> c5
Command G1 [ X:3 Y:2 Z:1 ]
>>> c5.Placement=p2
>>> c5
Command G1 [ X:5 ]
>>> c5.x
5.0
>>> c5.x=10
>>> c5
Command G1 [ X:10 ]
>>> c5.y=2
>>> c5
Command G1 [ X:10 Y:2 ]
Das Bahnobjekt
Das Pfad-Objekt enthält eine Liste von Befehlen
>>> import Path
>>> c1=Path.Command("g1",{"x":1,"y":0})
>>> c2=Path.Command("g1",{"x":0,"y":2})
>>> p=Path.Path([c1,c2])
>>> p
Path [ size:2 length:3 ]
>>> p.Commands
[Command G1 [ X:1 Y:0 ], Command G1 [ X:0 Y:2 ]]
>>> p.Length
3.0
>>> p.addCommands(c1)
Path [ size:3 length:4 ]
>>> p.toGCode()
'G1X1G1Y2G1X1'
lines = """
G0X-0.5905Y-0.3937S3000M03
G0Z0.125
G1Z-0.004F3
G1X0.9842Y-0.3937F14.17
G1X0.9842Y0.433
G1X-0.5905Y0.433
G1X-0.5905Y-0.3937
G0Z0.5
"""
slines = lines.split('\n')
p = Path.Path()
for line in slines:
p.addCommands(Path.Command(line))
o = App.ActiveDocument.addObject("Path::Feature","mypath")
o.Path = p
# but you can also create a path directly form a piece of G-code.
# The commands will be created automatically:
p = Path.Path()
p.setFromGCode(lines)
Als Abkürzung kann ein Pfadobjekt auch direkt aus einer vollständigen G-Code-Sequenz erstellt werden. Es wird automatisch in eine Folge von Befehlen unterteilt.
>>> p = Path.Path("G0 X2 Y2 G1 X0 Y2")
>>> p
Path [ size:2 length:2 ]
Die Bahn Funktion
Die Pfadfunktion ist ein FreeCAD-Dokumentobjekt, das einen Pfad enthält und diesen in der 3D-Ansicht darstellt.
>>> pf = App.ActiveDocument.addObject("Path::Feature","mypath")
>>> pf
<Document object>
>>> pf.Path = p
>>> pf.Path
Path [ size:2 length:2 ]
Die Pfad Funktion besitzt auch eine Eigenschaft Positionierung. Ändern des Wertes dieser Positionierung , ändert die Position der Funktion in der 3D Ansicht, obwohl die Pfadinformationen selbst nicht verändert werden. Die Transformation ist rein visuell. Auf diese Weise kann zum Beispiel ein Pfad um eine Fläche herum erstellt werden, die eine bestimmte Ausrichtung auf dem Modell hat, die nicht die gleiche Ausrichtung ist, die das Schneidmaterial auf der CNC Maschine haben wird.
Pfadverbünde können jedoch die Positionierung ihrer Unterelemente nutzen (siehe unten).
Die Werkzeug- und Werkzeugtabellen-Objekte
HINWEIS: Diese Art der Werkzeug-Verwendung ist seit der offiziellen Version 0.19 veraltet. In 0.19 wurde das neue Werkzeugbit-Werkzeug-System implementiert, um dieses ältere, veraltete System zu ersetzen. Daher hat sich die Codierung gegenüber der unten dargestellten geändert. Weitere Informationen findet man auf der Seite CAM Werkzeuge.
Skripten <= 0.18
Das Tool-Objekt enthält die Definitionen eines CNC-Werkzeugs. Das Tooltable-Objekt enthält eine geordnete Liste von Werkzeugen. Werkzeugtabellen werden als Eigenschaft an Path Project-Features angehängt und können auch über die grafische Benutzeroberfläche bearbeitet werden, indem man in der Baumansicht auf ein Projekt doppelklickt und in der sich öffnenden Aufgabenansicht auf die Schaltfläche "Werkzeugtabelle bearbeiten" klickt.
Über diesen Dialog können Werkzeugtabellen aus den Formaten .xml von FreeCAD und .tooltable von HeeksCad importiert und in das Format .xml von FreeCAD exportiert werden.
>>> import Path
>>> t1=Path.Tool()
>>> t1
Tool Default tool
>>> t1.Name = "12.7mm Drill Bit"
>>> t1
Tool 12.7mm Drill Bit
>>> t1.ToolType
'Undefined'
>>> t1.ToolType = "Drill"
>>> t1.Diameter= 12.7
>>> t1.LengthOffset = 127
>>> t1.CuttingEdgeAngle = 59
>>> t1.CuttingEdgeHeight = 50.8
>>> t2 = Path.Tool("my other tool",tooltype="EndMill",diameter=10)
>>> t2
Tool my other tool
>>> t2.Diameter
10.0
>>> table = Path.Tooltable()
>>> table
Tooltable containing 0 tools
>>> table.addTools(t1)
Tooltable containing 1 tools
>>> table.addTools(t2)
Tooltable containing 2 tools
>>> table.Tools
{1: Tool 12.7mm Drill Bit, 2: Tool my other tool}
>>>
Funktionen
Die Pfad Verbund Funktion
Das Ziel dieser Funktion ist es, einen oder mehrere Werkzeugwege zu sammeln und sie mit einer Werkzeugtabelle zu verknüpfen. Die Funktion "Verbund" verhält sich auch wie eine Standard-FreeCAD-Gruppe, sodass man Objekte direkt aus der Baumansicht hinzufügen oder entfernen kann. Es können Elemente auch neu angeordnet werden, indem man in der Baumansicht auf das Verbund-Objekt doppelklickt und dessen Elemente in der sich öffnenden Aufgabenansicht neu anordnet.
>>> import Path
>>> p1 = Path.Path("G1X1")
>>> o1 = App.ActiveDocument.addObject("Path::Feature","path1")
>>> o1.Path=p1
>>> p2 = Path.Path("G1Y1")
>>> o2 = App.ActiveDocument.addObject("Path::Feature","path2")
>>> o2.Path=p2
>>> o3 = App.ActiveDocument.addObject("Path::FeatureCompound","compound")
>>> o3.Group=[o1,o2]
Eine wichtige Funktion von Pfadkomponenten ist die Möglichkeit, die Platzierung ihrer untergeordneten Pfade zu berücksichtigen oder nicht, indem ihre UsePlacements-Eigenschaft auf True oder False gesetzt wird. Wenn nicht, werden die Pfaddaten ihrer untergeordneten Elemente einfach sequenziell hinzugefügt. Wenn True, wird jeder Befehl der untergeordneten Pfade, sofern er Positionsinformationen (G0, G1 usw.) enthält, zunächst durch die Positionierung transformiert, bevor er hinzugefügt wird.
Durch das Erstellen einer Verbindung mit nur einem untergeordneten Pfad kann man daher die Positionierung des untergeordneten Pfads "real" machen (sie wirkt sich auf die Pfaddaten aus).
Die Pfad Projekt Funktion
Das Path-Projekt ist eine erweiterte Form von Verbund, die über einige zusätzliche maschinenbezogene Eigenschaften wie beispielsweise eine Werkzeugtabelle verfügt. Es ist in erster Linie als Hauptobjekttyp gedacht, den man nach Fertigstellung der gesamten Pfadkonfiguration in G-Code exportieren möchten. Das Projekt-Objekt ist nun in Python programmiert, sodass sich sein Erstellungsmechanismus etwas unterscheidet:
>>> from PathScripts import PathProject
>>> o4 = App.ActiveDocument.addObject("Path::FeatureCompoundPython","prj")
>>> PathProject.ObjectPathProject(o4)
>>> o4.Group = [o3]
>>> o4.Tooltable
Tooltable containing 0 tools
Das Path-Modul verfügt außerdem über einen GUI-Werkzeugtabellen-Editor, der aus Python heraus aufgerufen werden kann und ihm ein Objekt mit einer ToolTable-Eigenschaft zur Verfügung stellt:
>>> from PathScripts import TooltableEditor
>>> TooltableEditor.edit(o4)
Pfad aus Form holen
Die Form des Linienzugteils einem normalen Pfadobjekt zuweisen, indem man die Skriptfunktion Path.fromShape() (oder die leistungsstärkere Path.fromShapes()) verwendet. Wenn man ein Linienzugteilobjekt als Parameter angibt, wird dessen Pfad automatisch aus der Form berechnet. Es muss beachtet werden, dass in diesem Fall die Platzierung automatisch auf den ersten Punkt des Linienzugs gesetzt wird und das Objekt daher nicht mehr durch Ändern seiner Positionierung verschoben werden kann. Um es zu verschieben, muss die zugrunde liegende Form selbst verschoben werden.
>>> import Part
>>> import Path
>>> v1 = FreeCAD.Vector(0,0,0)
>>> v2 = FreeCAD.Vector(0,2,0)
>>> v3 = FreeCAD.Vector(2,2,0)
>>> v4 = FreeCAD.Vector(3,3,0)
>>> wire = Part.makePolygon([v1,v2,v3,v4])
>>> o = FreeCAD.ActiveDocument.addObject("Path::Feature","myPath2")
>>> o.Path = Path.fromShape(wire)
>>> FreeCAD.ActiveDocument.recompute()
>>> p = o.Path
>>> print(p.toGCode())
Python Funktionen
Sowohl Path::Feature als auch Path::FeatureShape verfügen über eine Python-Version mit den Namen Path::FeaturePython bzw. Path::FeatureShapePython, die in Python-Code verwendet werden kann, um daraus abgeleitete, komplexere parametrische Objekte zu erstellen.
G-Code importieren und exportieren
Ursprungsformat
G-Code-Dateien können über die GUI direkt importiert und exportiert werden, indem man die Menüpunkte "Öffnen", "Einfügen" oder "Exportieren" verwendet. Nachdem der Dateiname abgerufen wurde, erscheint ein Dialogfeld, in dem man gefragt wird, welches Verarbeitungsskript verwendet werden soll. Dies kann auch über Python erfolgen:
Pfadinformationen werden in Pfadobjekten unter Verwendung einer Teilmenge des G-Codes gespeichert, die im Abschnitt "FreeCADs internes G-Code-Format" oben beschrieben ist. Diese Teilmenge kann "unverändert" importiert oder exportiert oder in eine für Ihre Maschine geeignete Version des G-Codes konvertiert werden.
Wenn man ein sehr einfaches und standardmäßiges G-Code-Programm hat, das den im Abschnitt "FreeCADs internes G-Code-Format" oben beschriebenen Regeln entspricht, beispielsweise der Bumerang aus cnccookbook, kann es ohne Übersetzung direkt in ein Pfadobjekt importiert werden (dies entspricht der Verwendung der Option "Keine" im GUI-Dialogfeld):
import Path
f = open("/path/to/boomerangv4.ncc")
s = f.read()
p = Path.Path(s)
o = App.ActiveDocument.addObject("Path::Feature","boomerang")
o.Path = p
Auf dieselbe Weise kann man die Pfadinformationen als "agnostischen" G-Code abrufen und manuell in einer Datei speichern:
text = o.Path.toGCode()
print text
myfile = open("/path/to/newfile.ngc")
myfile.write(text)
myfile.close()
Wenn man jedoch eine andere Ausgabe benötigt, muss man diesen agnostischen G-Code in ein für die Maschine geeignetes Format konvertieren. Das ist die Aufgabe von Nachbearbeitungsskripten.
Verwendung von Vor- und Nachbearbeitungsskripten
Wenn man eine G-Code-Datei für eine bestimmte Maschine hat, die nicht den internen Regeln von FreeCAD entspricht, die im Abschnitt "FreeCADs internes G-Code-Format" oben beschrieben sind, kann es sein, dass sie nicht richtig importiert und/oder in der 3D-Ansicht gerendert wird. Um dies zu beheben, muss ein Vorverarbeitungsskript verwendet werden, das das maschinenspezifisches Format in das FreeCAD-Format konvertiert.
Wenn der Name des zu verwendenden Vorverarbeitungsskripts bekannt ist, kann die Datei damit aus der Python-Konsole wie folgt importiert werden:
import example_pre
example_pre.insert("/path/to/myfile.ncc","DocumentName")
Auf dieselbe Weise kann ein Path-Objekt mit einem Postprozessor-Skript wie diesem in G-Code ausgeben werden:
import example_post
example_post.export (myObjectName,"/path/to/outputFile.ncc")
Schreiben von Verarbeitungsskripten
Vor- und Nachbearbeitungsskripte verhalten sich wie andere gängige FreeCAD-Importe/Exporte. Wenn man im Dialogfeld ein Vor-/Nachbearbeitungsskript auswählt, wird der Import-/Exportvorgang an das angegebene Skript weitergeleitet. Vorbearbeitungsskripte müssen mindestens die folgenden Methoden enthalten: open(filename) und insert(filename,docname). Nachbearbeitungsskripte müssen export(objectslist,filename) implementieren.
Skripte werden entweder im Ordner Mod/Path/Path/Post/scripts oder im Makro-Pfadverzeichnis des Benutzers abgelegt. Man kann ihnen einen beliebigen Namen geben, aber gemäß der Konvention und damit sie vom GUI-Dialog ausgewählt werden können, müssen die Namen von Vorverarbeitungsskripten mit „_pre“ und die von Nachverarbeitungsskripten mit „_post“ enden (unbedingt den Unterstrich und keinen Bindestrich verwenden, da Python sie sonst nicht importieren kann). Dies ist ein Beispiel für einen sehr, sehr einfachen Präprozessor. Komplexere Beispiele findet man im Ordner Mod/Path/Path/Post/scripts:
def open(filename):
gfile = __builtins__.open(filename)
inputstring = gfile.read()
# the whole gcode program will come in as one string,
# for example: "G0 X1 Y1\nG1 X2 Y2"
output = ""
# we add a comment
output += "(This is my first parsed output!)\n"
# we split the input string by lines
lines = inputstring.split("\n")
for line in lines:
output += line
# we must insert the "end of line" character again
# because the split removed it
output += "\n"
# another comment
output += "(End of program)"
import Path
p = Path.Path(output)
myPath = FreeCAD.ActiveDocument.addObject("Path::Feature","Import")
myPath.Path = p
FreeCAD.ActiveDocument.recompute()
Vor- und Nachprozessoren funktionieren genau gleich. Sie machen nur das Gegenteil: Die Vorskripte konvertieren von spezifischem G-Code in den "agnostischen" G-Code von FreeCAD, während Nachskripte vom "agnostischen" G-Code von FreeCAD in maschinenspezifischen G-Code konvertieren.
Hinzufügen aller Flächen eines Textform zur Liste der BasisFunktionen einer ProfilVonFlächen Operation
Dieses Beispiel basiert auf einer Diskussion im deutschsprachigen Forum.
Voraussetzungen
- Mit Textform als Ausschnitt einen Volumenkörper erstellen.
- Einen Auftrag erstellen, der diesen Volumenkörper als Basisobjekt verwendet.
- Eine Bearbeitung ProfileFromFaces mit dem Namen "Profile_Faces" und einer leeren Basisgeometrie erstellen.
Der Code
Der folgende Code fügt dann alle Flächen aus Textform hinzu und erstellt die Pfade:
doc = App.ActiveDocument
list_of_all_element_faces = []
for i, face in enumerate(doc.ShapeString.Shape.Faces):
list_of_all_element_faces.append('Face' + str(i + 1))
doc.Profile_Faces.Base = [(doc.ShapeString, tuple(list_of_all_element_faces))]
doc.recompute()
- Project Commands: New Job, Post Process, Sanity Check, Export Template
- Tool Commands: Inspect Toolpath, Legacy CAM Simulator, CAM Simulator, Finish Selecting Loop, Toggle Operation, ToolBit Library Manager, Add toolbit…
- Basic Operations: Profile, Pocket Shape, Face, Helix, Adaptive, Slot, Drilling, Tapping, Engrave, Deburr, Vcarve
- 3D Operations: 3D Pocket, 3D Surface, Waterline
- CAM Dressup: Array, Axis Map, Boundary, Dogbone, Drag Knife, Lead In/Out, Ramp Entry, Tag, Z Depth Correction
- Supplemental Commands: Comment, Stop, Custom, Probe, Path From Shape TC
- CAM Modification: Copy oOperation, Array, Simple Copy
- Specialty Operations: Thread Milling
- Miscellaneous: Area, Area Workplane
- ToolBit architecture: Tools, ToolShape, ToolBit, ToolBit Library, ToolController
- Additional: Preferences, Scripting
- FreeCAD scripting: Python, Introduction to Python, Python scripting tutorial, FreeCAD Scripting Basics
- Modules: Builtin modules, Units, Quantity
- Workbenches: Workbench creation, Gui Commands, Commands, Installing more workbenches
- Meshes and Parts: Mesh Scripting, Topological data scripting, Mesh to Part, PythonOCC
- Parametric objects: Scripted objects, Viewproviders (Custom icon in tree view)
- Scenegraph: Coin (Inventor) scenegraph, Pivy
- Graphical interface: Interface creation, Interface creation completely in Python (1, 2, 3, 4, 5), PySide, PySide examples beginner, intermediate, advanced
- Macros: Macros, How to install macros
- Embedding: Embedding FreeCAD, Embedding FreeCADGui
- Other: Expressions, Code snippets, Line drawing function, FreeCAD vector math library (deprecated)
- Hubs: User hub, Power users hub, Developer hub