More is less

16/05/2016

Fer pour FreeCAD

Cet article fait partie d'un projet d'atelier menuiserie pour FreeCAD.

Dans cet article on modélise des pièces dont la section comporte des segments de droite et des arcs de cercle.

Objectif

On veut faire faire à FreeCAD des pièces comme sur la copie d'écran ci-dessus, c'est à dire comportant sur sa section des segments de droite et des arcs de cercle. On veut aussi utiliser une syntaxe très dépouillée :

f = Fer(nom, hauteur, (x0, y0), (x, y)|(a, x, y), ...)

nom est le nom de la pièce. Ex. "F096"

(x0, y0) est l'origine du tracé. Ex. (0, 0)

hauteur est un entier qui mesure la hauteur de la pièce. Ex. 24

Suivent alors des tuples. Un couple pour un segment et un triplet pour un arc.

Classe Fer

def __init__(self, label, h, *args):
	self.n = 0 # count of edges
	self.edges = [] # edges of the shape
	arg = args[0] # start point
	self.x, self.y = arg[0], arg[1] # current point of the drawing
	for arg in args[1:]:
		if len(arg) == 2: # line
			self.lineTo(*arg) 
		else: # arc
			self.arcTo(*arg)
	w = Part.Wire(self.edges) 
	face = Part.Face(w) 
	fer = face.extrude(fv(0, 0, h))
	fobj = doc.addObject("Part::Feature", label)
	fobj.Shape = fer

Segment de droite

La classe Fer mémorise les coordonnées du point courant (sef.x, self.y)

La fonction lineTo trace un segment de droite vers le nouveau point en utilisant la fonction Part.makeLine du module Part. (voir documentation API FreeCAD)

def lineTo(self, x, y):
	""" Draw a line from the current point to (x, y)
	update the current point """
	x0, y0  = self.x, self.y
	self.x, self.y = x, y
	e = Part.makeLine((x0, y0, 0), (x, y, 0))
	self.addEdge(e)

Arc de cercle

Pour dessiner un arc de cercle du point courant au suivant, c'est un peu plus compliqué. Il faut d'abord déterminer le centre du cercle et d'autre part tenir compte de l'orientation de l'espace. Un document expose le calcul mathématique : Math2Fer

def arcTo(self, alpha, x, y):
	""" a is the start angle of the arc from the current point
	(x, y) is the end point
	draw an arc from the current point to (x, y)
	update the current point
	"""
	a = radians(alpha)
	x0, y0 = self.x, self.y # start point
	self.x, self.y = x, y # update current start point
	p = x*x + y*y - x0*x0 - y0*y0
	q = x0*cos(a) + y0*sin(a)
	d = (x - x0)*sin(a) - (y - y0)*cos(a)
	X = (.5*sin(a)*p - (y-y0)*q) / d # center of arc
	Y = ((x-x0)*q -.5*cos(a)*p) / d
	r = hypot(X - x, Y - y)
	g = (y - y0)*cos(a) - (x - x0)*sin(a)
	a = degrees(copysign(acos((x0 - X)/r), y0 - Y))
	b = degrees(copysign(acos((x - X)/r), y - Y))
	if g > 0:
		e = Part.makeCircle(r, fv(X, Y, 0), fv(0, 0, 1), a, b)
	else: 
		e = Part.makeCircle(r, fv(X, Y, 0), fv(0, 0, 1), b, a)
	self.addEdge(e)

Fichier python complet

Le fichier python est à télécharger ici fer.py.

Pour le faire exécuter par FreeCAD :


Réalisé avec Qlam - LGPL