ramses76
Compagnon
Bonjour,
FreeCAD demande un effort d'apprentissage assez important et une pratique régulière pour le maîtriser. Je fais partie de ces utilisateurs occasionnels hobbyistes et j'avoue que j'ai eu souvent du mal à comprendre ce que j'avais fait quelques mois auparavant, ne prenant pas toujours soin de documenter mes projets et surtout n'ayant jamais utilisé de macros jusqu'à ce test.
J'ai donc testé la capacité de Claude à écrire une macro FreeCAD pour faire ceci ( ce sont mes prompts texto) :
1) Créer une macro FreeCAD qui crée avec Part Design un objet cubique de 4 mm d'arête centré sur le plan XY.
2) Ajouter un trou traversant fileté M2 x 0,5, centré en (X=0, Y=0) et perpendiculaire au plan XY.
Puis pour tester une demande de modification:
1) Remplacer la base carrée de la pièce par une forme hexagonale de 2 mm de côté
2) Arrondir les 6 arêtes supérieures de la pièce : congé de rayon 0,3 mm.
Me mettant dans la peau d'un utilisateur débutant qui ne veut pas se casser la tête, j'ai systématiquement copié/collé à Claude les messages d'erreur de la console FreeCAD sans chercher à comprendre ses explications. Bref , j'ai travaillé comme un paresseux peu curieux.
Le dialogue avec Claude et le recyclage de ses erreurs à pris du temps mais c'est très instructif et c'est de loin la meilleure méthode et le meilleur instructeur à mon avis pour se former sur un nouveau logiciel.
Approche efficace: quand Claude s'est trompé sur les attributs d'un élément, il propose à l'utilisateur une macro qui les liste avec leurs valeurs admissibles, ce qui est très instructif. Il est important de préciser d'emblée la version de FreeCAD qu'il m'a demandée lui-même assez rapidement.
J'ai mis en annexe la macro, qui pourrait probablement être simplifiée, surtout la séquence de recherche des arêtes que j'ai qualifiées de "supérieures". Claude ne remet pas en question les questions imprécises de son maître et s'exécute.. Elle fonctionne avec FreeCAD 1.0.2.
Voilà..
La macro générée par Claude après quelques recyclage d'erreurs :
# -*- coding: utf-8 -*-
"""
Macro FreeCAD 1.0.2 - Hexagone 2mm de côté, hauteur 4mm, centré sur XY
+ trou fileté M2x0,5 traversant centré en (0,0)
+ congé R0,3mm sur les 6 arêtes supérieures
Utilise PartDesign : Body, Sketch, Pad, Hole, Fillet
"""
import FreeCAD
import FreeCADGui
import Part
import Sketcher
import PartDesign
import math
# --- Paramètres ---
COTE = 2.0
HAUT = 4.0
DEMI_H = HAUT / 2.0
R_M2 = 0.8
R_HEX = COTE
R_CONG = 0.3
# --- Document ---
doc = FreeCAD.newDocument("Hex_M2")
body = doc.addObject("PartDesign::Body", "Body")
# ---------------------------------------------------------------
# 1. SKETCH hexagone régulier centré sur XY
# ---------------------------------------------------------------
sketch = body.newObject("Sketcher::SketchObject", "Sketch")
sketch.AttachmentSupport = (doc.getObject("XY_Plane"), [""])
sketch.MapMode = "FlatFace"
pts = []
for i in range(6):
angle = math.radians(90 + i * 60)
pts.append(FreeCAD.Vector(R_HEX * math.cos(angle), R_HEX * math.sin(angle), 0))
for i in range(6):
sketch.addGeometry(Part.LineSegment(pts, pts[(i+1) % 6]), False)
for i in range(6):
sketch.addConstraint(Sketcher.Constraint("Coincident", i, 2, (i+1) % 6, 1))
for i in range(1, 6):
sketch.addConstraint(Sketcher.Constraint("Equal", 0, i))
sketch.addConstraint(Sketcher.Constraint("Distance", 0, COTE))
sketch.AttachmentOffset = FreeCAD.Placement(
FreeCAD.Vector(0, 0, -DEMI_H), FreeCAD.Rotation(0, 0, 0, 1))
doc.recompute()
# ---------------------------------------------------------------
# 2. PAD 4mm
# ---------------------------------------------------------------
pad = body.newObject("PartDesign:
ad", "Pad")
pad.Profile = sketch
pad.Length = HAUT
pad.Reversed = False
doc.recompute()
# ---------------------------------------------------------------
# 3. SKETCH cercle Ø1,6mm (face sup)
# ---------------------------------------------------------------
sketch_hole = body.newObject("Sketcher::SketchObject", "Sketch_Hole")
sketch_hole.AttachmentSupport = (doc.getObject("XY_Plane"), [""])
sketch_hole.MapMode = "FlatFace"
sketch_hole.AttachmentOffset = FreeCAD.Placement(
FreeCAD.Vector(0, 0, DEMI_H), FreeCAD.Rotation(0, 0, 0, 1))
sketch_hole.addGeometry(
Part.Circle(FreeCAD.Vector(0,0,0), FreeCAD.Vector(0,0,1), R_M2), False)
sketch_hole.addConstraint(Sketcher.Constraint("Coincident", 0, 3, -1, 1))
sketch_hole.addConstraint(Sketcher.Constraint("Radius", 0, R_M2))
doc.recompute()
# ---------------------------------------------------------------
# 4. TROU FILETÉ M2x0,5 traversant
# ---------------------------------------------------------------
hole = body.newObject("PartDesign::Hole", "Hole_M2")
hole.Profile = sketch_hole
hole.DepthType = "ThroughAll"
hole.DrillPoint = "Flat"
hole.DrillForDepth = False
hole.Reversed = False
hole.HoleCutType = "None"
hole.Threaded = True
hole.ThreadType = "ISOMetricProfile"
doc.recompute()
hole.ThreadSize = "M2"
hole.ThreadFit = "Standard"
hole.ThreadDirection = "Right"
hole.ThreadDepthType = "Hole Depth"
hole.ModelThread = True
doc.recompute()
# ---------------------------------------------------------------
# 5. CONGÉ R0,3mm sur les 6 arêtes supérieures de l'hexagone
# Critères : Z = +DEMI_H ET arête rectiligne (Line) ET longueur ≈ COTE
# ---------------------------------------------------------------
shape = hole.Shape
top_edges = []
for i, edge in enumerate(shape.Edges):
zvals = [v.Z for v in edge.Vertexes]
# Arête à la face supérieure
if not (len(zvals) > 0 and all(abs(z - DEMI_H) < 0.05 for z in zvals)):
continue
# Arête rectiligne uniquement (pas les arcs du filetage)
if edge.Curve.TypeId != "Part::GeomLine":
continue
# Longueur ≈ côté de l'hexagone
if abs(edge.Length - COTE) > 0.05:
continue
top_edges.append("Edge{}".format(i + 1))
FreeCAD.Console.PrintMessage("Aretes superieures hexagone : {}\n".format(top_edges))
fillet = body.newObject("PartDesign::Fillet", "Fillet_sup")
fillet.Base = (hole, top_edges)
fillet.Radius = R_CONG # attribut correct FreeCAD 1.0.2
doc.recompute()
# ---------------------------------------------------------------
# 6. AFFICHAGE
# ---------------------------------------------------------------
FreeCADGui.ActiveDocument.ActiveView.fitAll()
FreeCAD.Console.PrintMessage(
"✓ Hexagone cote={}mm, hauteur={}mm, centre sur XY\n"
"✓ Trou filete M2x0,5 traversant centre en (0,0)\n"
"✓ Conge R{}mm sur {} aretes superieures\n"
.format(COTE, HAUT, R_CONG, len(top_edges))
)
FreeCAD demande un effort d'apprentissage assez important et une pratique régulière pour le maîtriser. Je fais partie de ces utilisateurs occasionnels hobbyistes et j'avoue que j'ai eu souvent du mal à comprendre ce que j'avais fait quelques mois auparavant, ne prenant pas toujours soin de documenter mes projets et surtout n'ayant jamais utilisé de macros jusqu'à ce test.
J'ai donc testé la capacité de Claude à écrire une macro FreeCAD pour faire ceci ( ce sont mes prompts texto) :
1) Créer une macro FreeCAD qui crée avec Part Design un objet cubique de 4 mm d'arête centré sur le plan XY.
2) Ajouter un trou traversant fileté M2 x 0,5, centré en (X=0, Y=0) et perpendiculaire au plan XY.
Puis pour tester une demande de modification:
1) Remplacer la base carrée de la pièce par une forme hexagonale de 2 mm de côté
2) Arrondir les 6 arêtes supérieures de la pièce : congé de rayon 0,3 mm.
Me mettant dans la peau d'un utilisateur débutant qui ne veut pas se casser la tête, j'ai systématiquement copié/collé à Claude les messages d'erreur de la console FreeCAD sans chercher à comprendre ses explications. Bref , j'ai travaillé comme un paresseux peu curieux.
Le dialogue avec Claude et le recyclage de ses erreurs à pris du temps mais c'est très instructif et c'est de loin la meilleure méthode et le meilleur instructeur à mon avis pour se former sur un nouveau logiciel.
Approche efficace: quand Claude s'est trompé sur les attributs d'un élément, il propose à l'utilisateur une macro qui les liste avec leurs valeurs admissibles, ce qui est très instructif. Il est important de préciser d'emblée la version de FreeCAD qu'il m'a demandée lui-même assez rapidement.
J'ai mis en annexe la macro, qui pourrait probablement être simplifiée, surtout la séquence de recherche des arêtes que j'ai qualifiées de "supérieures". Claude ne remet pas en question les questions imprécises de son maître et s'exécute.. Elle fonctionne avec FreeCAD 1.0.2.
Voilà..
La macro générée par Claude après quelques recyclage d'erreurs :
# -*- coding: utf-8 -*-
"""
Macro FreeCAD 1.0.2 - Hexagone 2mm de côté, hauteur 4mm, centré sur XY
+ trou fileté M2x0,5 traversant centré en (0,0)
+ congé R0,3mm sur les 6 arêtes supérieures
Utilise PartDesign : Body, Sketch, Pad, Hole, Fillet
"""
import FreeCAD
import FreeCADGui
import Part
import Sketcher
import PartDesign
import math
# --- Paramètres ---
COTE = 2.0
HAUT = 4.0
DEMI_H = HAUT / 2.0
R_M2 = 0.8
R_HEX = COTE
R_CONG = 0.3
# --- Document ---
doc = FreeCAD.newDocument("Hex_M2")
body = doc.addObject("PartDesign::Body", "Body")
# ---------------------------------------------------------------
# 1. SKETCH hexagone régulier centré sur XY
# ---------------------------------------------------------------
sketch = body.newObject("Sketcher::SketchObject", "Sketch")
sketch.AttachmentSupport = (doc.getObject("XY_Plane"), [""])
sketch.MapMode = "FlatFace"
pts = []
for i in range(6):
angle = math.radians(90 + i * 60)
pts.append(FreeCAD.Vector(R_HEX * math.cos(angle), R_HEX * math.sin(angle), 0))
for i in range(6):
sketch.addGeometry(Part.LineSegment(pts, pts[(i+1) % 6]), False)
for i in range(6):
sketch.addConstraint(Sketcher.Constraint("Coincident", i, 2, (i+1) % 6, 1))
for i in range(1, 6):
sketch.addConstraint(Sketcher.Constraint("Equal", 0, i))
sketch.addConstraint(Sketcher.Constraint("Distance", 0, COTE))
sketch.AttachmentOffset = FreeCAD.Placement(
FreeCAD.Vector(0, 0, -DEMI_H), FreeCAD.Rotation(0, 0, 0, 1))
doc.recompute()
# ---------------------------------------------------------------
# 2. PAD 4mm
# ---------------------------------------------------------------
pad = body.newObject("PartDesign:
pad.Profile = sketch
pad.Length = HAUT
pad.Reversed = False
doc.recompute()
# ---------------------------------------------------------------
# 3. SKETCH cercle Ø1,6mm (face sup)
# ---------------------------------------------------------------
sketch_hole = body.newObject("Sketcher::SketchObject", "Sketch_Hole")
sketch_hole.AttachmentSupport = (doc.getObject("XY_Plane"), [""])
sketch_hole.MapMode = "FlatFace"
sketch_hole.AttachmentOffset = FreeCAD.Placement(
FreeCAD.Vector(0, 0, DEMI_H), FreeCAD.Rotation(0, 0, 0, 1))
sketch_hole.addGeometry(
Part.Circle(FreeCAD.Vector(0,0,0), FreeCAD.Vector(0,0,1), R_M2), False)
sketch_hole.addConstraint(Sketcher.Constraint("Coincident", 0, 3, -1, 1))
sketch_hole.addConstraint(Sketcher.Constraint("Radius", 0, R_M2))
doc.recompute()
# ---------------------------------------------------------------
# 4. TROU FILETÉ M2x0,5 traversant
# ---------------------------------------------------------------
hole = body.newObject("PartDesign::Hole", "Hole_M2")
hole.Profile = sketch_hole
hole.DepthType = "ThroughAll"
hole.DrillPoint = "Flat"
hole.DrillForDepth = False
hole.Reversed = False
hole.HoleCutType = "None"
hole.Threaded = True
hole.ThreadType = "ISOMetricProfile"
doc.recompute()
hole.ThreadSize = "M2"
hole.ThreadFit = "Standard"
hole.ThreadDirection = "Right"
hole.ThreadDepthType = "Hole Depth"
hole.ModelThread = True
doc.recompute()
# ---------------------------------------------------------------
# 5. CONGÉ R0,3mm sur les 6 arêtes supérieures de l'hexagone
# Critères : Z = +DEMI_H ET arête rectiligne (Line) ET longueur ≈ COTE
# ---------------------------------------------------------------
shape = hole.Shape
top_edges = []
for i, edge in enumerate(shape.Edges):
zvals = [v.Z for v in edge.Vertexes]
# Arête à la face supérieure
if not (len(zvals) > 0 and all(abs(z - DEMI_H) < 0.05 for z in zvals)):
continue
# Arête rectiligne uniquement (pas les arcs du filetage)
if edge.Curve.TypeId != "Part::GeomLine":
continue
# Longueur ≈ côté de l'hexagone
if abs(edge.Length - COTE) > 0.05:
continue
top_edges.append("Edge{}".format(i + 1))
FreeCAD.Console.PrintMessage("Aretes superieures hexagone : {}\n".format(top_edges))
fillet = body.newObject("PartDesign::Fillet", "Fillet_sup")
fillet.Base = (hole, top_edges)
fillet.Radius = R_CONG # attribut correct FreeCAD 1.0.2
doc.recompute()
# ---------------------------------------------------------------
# 6. AFFICHAGE
# ---------------------------------------------------------------
FreeCADGui.ActiveDocument.ActiveView.fitAll()
FreeCAD.Console.PrintMessage(
"✓ Hexagone cote={}mm, hauteur={}mm, centre sur XY\n"
"✓ Trou filete M2x0,5 traversant centre en (0,0)\n"
"✓ Conge R{}mm sur {} aretes superieures\n"
.format(COTE, HAUT, R_CONG, len(top_edges))
)
Dernière édition: