Manual02/fr

From FreeCAD Documentation
Jump to: navigation, search




Manuel



de



FreeCAD





Splash013.jpg






Ceci est le Manuel de FreeCAD. Il comprend les parties essentielles de la Page de garde de la documentation wiki.
Cette page est spécialement destinée à l'impression, comme un gros document, donc, si vous lisez ceci en ligne, vous pourrez préférer aller directement à la version Aide en ligne, qui est plus facile à parcourir.


Scripts et macros

Macros

Next: Introduction à Python Arrow-right.svg

Introduction

Une macro est un moyen pratique et facile d'automatiser une série de commandes dans FreeCad.

Il suffit d'enregistrer une série de commandes que vous faites, puis de les sauvagarder sous un nom. Une fois cet enregistrement (macro) sauvé, vous pourrez l'exécuter autant de fois que vous le voulez.

Ces macros sont en réalité une liste de commandes écrites en langage Python que vous pouvez également modifier pour créer des scripts très complexes.

Alors que les scripts Python ont normalement pour extension .py, les macros FreeCAD doivent avoir comme extension .FCMacro. Une collection de macros écrites par des utilisateurs expérimentés se trouve dans la page Macros.

Voir Introduction au langage Python pour en savoir plus sur le langage de programmation Python, puis sur Tutoriel sur les scripts Python et sur Débuter avec les scripts pour en savoir plus sur l'écriture de macros.

Fonctionnement

Dans le menu Édition → Préférences → Général → Macro → Montrer les commandes du script dans la console Python, vous verrez dans la fenêtre " Console Python " que chaque action que vous exécutez s'affiche, par exemple en appuyant sur " Afficher la vue de face ", il s'affiche dans la console Gui.activeDocument().activeView().viewFront() qui est le code python correspondant.

Toutes ces commandes peuvent être enregistrées dans une macro.

Ces commandes, qui servent à faire les macros, se trouvent sur la barre d'outils des macros : Macros toolbar.jpg.
Sur la barre d'outils, il y a 4 boutons: Enregistrement, Arrêt de l'enregistrement, Édition de la macro et Exécuter la macro.

Il est extrêmement facile d'utiliser ces commandes : dès que vous appuyez sur le bouton d'enregistrement, il vous est demandé de donner un nom à la macro, éventuellement, donnez l'emplacement où placer le fichier. Une fois que la macro est terminée, cliquez sur le bouton Stop et toutes les actions que vous avez effectuées sont enregistrée. Pour exécuter la macro, cliquer sur le bouton d'édition et la boîte de dialogue Lancer la macro s'affiche.

Macros.png

Interface listant les macros disponibles dans le système


Ici vous pouvez gérer les macros enregistrées: lancer, créer, supprimer ou éditer une macro. L'édition ou la création d'une macro ouvre une nouvelle fenêtre dans FreeCad et vous pouvez ainsi créer ou modifier le code de la macro éditée. De nouvelles macros peuvent être installées à l’aide du bouton Addons ... qui renvoie au Gestionnaire d'extensions.

Exemple

Cliquez sur le bouton d'Enregistrement, donnez un nom à la macro par exemple "cylinder 10x10" puis dans l'atelier Part, créez un cylindre de rayon = 10 et hauteur = 10. Puis cliquer sur le bouton "Stop" pour arrêter la macro. Dans la fenêtre d'édition de la macro vous pouvez voir le code en langage python qui a été enregistré et si vous le désirez, en modifier le code. Exécutez votre macro simplement en cliquant sur le bouton "Exécuter la macro dans l'éditeur". La macro éditée ou la nouvelle macro est toujours sauvegardée lors de l'exécution, de manière à ne pas perdre les modifications apportées, les macros créées sont toujours accessibles à chaque nouvelle ouverture de FreeCad.

Personnalisation

Bien sûr, il n'est pas pratique de charger une macro dans l'éditeur en vue de l'exécuter. FreeCad fournit d'autres moyens pour exécuter votre macro, vous pouvez assigner un raccourci clavier à chaque macro ou créer un bouton de lancement sur la barre de menus. Une fois votre macro créée, ces raccourcis peuvent être crées par Outils → personnaliser → Macros

Macros config.jpg

L'outil Comment créer une barre d'outils. Vous pouvez faire de vos macros de véritables outils tout comme les outils disponibles dans FreeCad. Cette possibilité permet d'ajouter facilement vos propres outils dans l'interface de FreeCad et d'augmenter ainsi la bibliothèque de scripts déjà implantés dans FreeCad. Pour plus d'informations sur les scripts Python rendez vous sur la page Documentation pour utilisateurs avancés.

Création de macros sans enregistrement

Comment installer une macro Il est aussi possible d’insérer le code Python d'une macro avec copier/coller sans enregistrement d'actions dans l'interface graphique. Créer simplement le code python de la macro, éditez-le, copiez-le et collez votre code directement dans l'éditeur de macros de FreeCAD. Puis vous pouvez la réutiliser comme bon vous semble et la retrouver dans le répertoire réservé aux macros en passant par Macro → Macros.

Les dépôts de Macros

Visitez la page Macros pour charger des macros et les ajouter à votre installation FreeCad.

Liens

Installer des ateliers supplémentaires

Tutoriels

Comment installer plus d'ateliers

Arrow-left.svg Page précédente: Standard Menu
FreeCAD.png

Introduction à Python

(Janvier 2020) FreeCAD a été initialement conçu pour fonctionner avec Python 2. Étant donné que Python 2 est en fin de vie, son développement futur se fera exclusivement avec Python 3, et la compatibilité avec les versions antérieures ne sera pas prise en charge. Les informations décrites ici décrivent Python 2 mais la majorité du code devrait fonctionner de la même manière que Python 3. En particulier, la fonction print() est préférée à l’ancienne instruction print.


Ceci est un petit tutoriel créé pour ceux qui veulent débuter en programmation Python, qui est un langage de programmation open-source et multiplate-forme. Python a de nombreuses fonctionnalités qui le différencie des autre langages de programmation, et est facilement accessible à celui qui veut se lancer dans la programmation.

  • Il a été conçu spécialement pour être facile à lire par les êtres humains, il est ainsi facile à apprendre et à comprendre
  • Il est interprété. C'est-à-dire que contrairement aux langages compilés comme le C, votre programme n'a pas besoin d'être compilé pour être exécuté. Le code que vous écrivez peut être directement exécuté, une ligne après l'autre si vous le souhaitez. Cela permet de l'apprendre et de trouver les erreurs dans votre code facilement, parce que vous avancez lentement, une étape après l'autre.
  • Il peut être intégré dans d'autres programmes comme langage de script. FreeCAD possède un interpréteur Python intégré, vous pouvez ainsi y écrire du code Python. Cela permet de manipuler des éléments de FreeCAD, par exemple de créer des objets géométriques. Il s'agit d'une fonction extrêmement puissante, parce qu'au lieu de se contenter de cliquer sur un bouton appelé "Créer une sphère", qu'un programmeur aurait placé là pour vous, vous avez la possibilité de créer simplement vos propres outils pour générer exactement les objets géométriques que vous souhaitez.
  • Il est extensible; vous pouvez simplement installer de nouveaux modules Python et étendre ses fonctionnalités. Par exemple, il existe un module qui permet à Python de lire et d'écrire des images jpg, de communiquer avec twitter, de planifier des tâches exécutées pour votre système d'exploitation, etc...

Nous vous encourageons vivement à entrer les extraits de code ci-dessous dans un interpréteur Python. Pour beaucoup de nos exemples, le point important est la ligne après l'exécution du code, le résultat. Et maintenant au travail ! Soyez conscient que ce qui suit est une introduction simplifiée, et en aucun cas un tutoriel complet. Mais nous espérons qu'après cette lecture vous aurez acquis les bases nécessaires pour connaître et exploiter plus profondément les mécanismes de FreeCad.

L’interpréteur

Habituellement, lors de l'écriture d'un programme informatique, il suffit d'ouvrir votre environnement de programmation préféré qui, est dans la plupart des cas, un éditeur de texte avec plusieurs outils autour de lui, écrire votre programme, puis le compiler et l'exécuter. Lorsque vous avez fait des erreurs pendant l'écriture, votre programme ne fonctionnera pas! et vous obtiendrez un message d'erreur vous indiquant ce qu'il s'est passé. Ensuite, vous revenez à votre éditeur de texte, corrigez les erreurs, exécutez à nouveau, et ainsi de suite jusqu'à ce que votre programme fonctionne parfaitement.

En Python, tout ce processus, peut être exécuté de manière transparente dans l'interpréteur Python. L’interpréteur Python est une fenêtre avec une invite de commande, vous pouvez simplement y taper votre code Python. Si vous installez Python sur votre ordinateur (téléchargez le depuis le site web Python si vous êtes sous Windows ou Mac, installez le à partir des gestionnaire de paquets, si vous êtes sous GNU / Linux), vous aurez l'interpréteur Python dans votre menu de démarrage. Mais FreeCAD dispose également d'un interpréteur Python intégré, vous n'êtes donc pas obligé de l'installer, cet interpréteur est visible dans la fenêtre inférieure (Si vous ne voyez pas cette fenêtre, cliquez sur Affichage->Vues->Console Python). Tous ces exemples ont été relu à partir de l'interpréteur disponible dans FreeCad.

Screenshot pythoninterpreter.jpg

(SI vous ne l'avez pas, cliquez sur le menu Affichage --> Panneaux --> Console Python).

L’interpréteur affiche la version de Python installée, puis le symbole >>>, qui est l'invite de commande pour entrer votre code Python. L'écriture du code dans l'interpréteur est très simple: une ligne, est une instruction. Lorsque vous appuyez sur ENTREE, votre ligne de code est exécuté (après avoir été instantanément compilé et cela de manière transparente pour vous).

Par exemple, écrivez ce code:

print "hello"

Ici print est une commande spéciale de Python qui signifie: affiche ce que je te demande. Lorsque vous pressez ENTREE, l'opération s’exécute et le message hello s'affiche à l'écran. Si vous effectuez une erreur, par exemple, écrivez:

print hello

Python vous dira qu'il ne sait pas ce qu'est hello. Les caractères " (guillemets) spécifient que le contenu est une chaîne de caractères qui doit être affichée. Sans les " (guillemets), la commande d'affichage de hello n'est pas reconnue comme du texte, mais comme un mot-réservé spécial de Python. L'important est, que vous obtenez immédiatement une notification d'erreur. En appuyant sur la flèche Haut (ou, dans l'interpréteur FreeCAD, CTRL + flèche Haut), vous pouvez revenir à la dernière commande que vous avez écrite et la corriger.

L'interpréteur Python dispose également d'un système d'aide intégré. Essayez :

help

ou, par exemple, imaginons que nous n'avons pas compris ce qui n'allait pas avec notre commande d'affichage "help" ci-dessus, nous allons demander des informations spécifiques sur la commande "print". Tapez :

help("print")

Nous voilà devant une longue description sur la commande "print".

Maintenant que nous dominons totalement notre interpréteur, et nous pouvons commencer à travailler sérieusement.

Les Variables

Bien sûr, vous vous dites que l'affichage de hello n'est pas très intéressant. Il peut y avoir alors des choses plus intéressantes comme par exemple, l'affichage de choses que vous ne savez pas, et laisser Python trouver ces choses pour vous. C'est là que le concept de "variable" entre en jeu. Une variable est tout simplement une valeur que vous stockez en mémoire avec un nom identificateur. Par exemple, tapez ceci:

a = "hello"
print a

Je suppose que vous avez compris ce qui s'est passé ? Nous avons «sauvé» en mémoire la chaîne "hello" dans la variable qui porte le nom de a. Maintenant, a n'est plus un nom inconnu ! Nous pouvons maintenant l'utiliser n'importe où, comme par exemple dans la commande d'affichage à l'écran print. Nous pouvons dans Python utiliser n'importe quel nom que nous voulons, tout en respectant de simples règles, par exemple, ne pas utiliser d'espaces ou de signes de ponctuation. Par exemple, nous pouvons écrire:

hello = "my own version of hello"
print hello

Avez vous compris ? Maintenant hello n'est plus un mot inconnu. Que faire alors si, par inattention ou par méprise nous choisissons un nom qui existe dans Python? Admettons que nous voulons stocker notre chaîne sous le nom de "print":

print = "hello"

Python se rend compte immédiatement de l'erreur et vous signale qu'il est impossible de donner ce nom à votre variable. Il y a quelques restrictions dans Python, les mots "réservés" ne peuvent pas être modifiés! Mais, nos propres variables peuvent être modifiées à tout moment, c'est exactement pour cela qu'elles sont appelées variables, le contenu de la variable peut varier. Par exemple:

myVariable = "hello"
print myVariable
myVariable = "good bye"
print myVariable

Nous venons de changer la valeur de myVariable. Nous pouvons également copier des variables:

var1 = "hello"
var2 = var1
print var2

Notez qu'il est judicieux de donner des noms descriptifs à vos variables, lorsque vous écrivez un long programme, vous ne saurez plus à quoi sert votre variable "a". Mais, si vous la nommez, par exemple MonMessageDeBienvenue, vous vous souviendrez facilement a quoi vous l'aviez destinée quand vous la verrez.

Plus de renseignements sur les variables Python

La casse est très importante. Par exemple maVariable n'est pas identique à mavariable, la différence se situe dans la lettre majuscule/minuscule "v". Si vous saisissiez "print mavariable", vous aurez en retour une erreur de type : NameError: name is not defined.

Les Nombres

Vous savez qu'un programme informatique est utilisé pour traiter toutes sortes de données, non seulement du texte mais aussi et surtout des nombres. Une des choses les plus importantes dans Python, est que Python doit savoir quel type de données seront traitées. Nous avons vu dans notre exemple d'affichage "bonjour" que la commande d'affichage print a reconnu «bonjour» comme une chaîne. C'est grâce au " " " (guillemets), que la commande d'affichage print sait qu'il va traiter une chaîne de caractères alphabétiques (du texte).

Le type de donnée contenu dans une variable peut être connu à n'importe quel moment grâce à la commande spéciale de Python type():

myVar = "hello"
type(myVar)

Dans cet exemple, il s'affiche dans la console Python <type 'str'> dans le langage informatique on dit qu'il est de type "string" (chaîne de caractères alphabétiques). Il y a d'autres types de données, par exemple: les nombres entier (integer) , les nombres à virgule flottante (float) . . .:

firstNumber = 10
secondNumber = 20
print firstNumber + secondNumber
type(firstNumber)

C'est déjà plus intéressant, n'est-ce pas? Maintenant nous avons une puissante calculatrice! Voyons maintenant comment elle fonctionne. Python sait que 10 et 20 sont des nombres entiers. Donc, ils sont stockés en mémoire sous forme "int" (integer), et Python peut travailler avec eux comme il peut le faire avec des nombres entiers. Regardez les résultats de ce code:

firstNumber = "10"
secondNumber = "20"
print firstNumber + secondNumber

Nous avons forcé Python à considérer nos deux variables non pas comme de simples nombres, mais comme des parties de texte. Python peut concaténer deux parties de texte, mais il ne cherchera pas à trouver leur somme. Nous avons parlé de nombres entiers, il y a aussi des nombres à virgule flottante. La différence est, que les nombres entiers n'ont pas de partie décimale, alors que les nombres à virgule flottante peuvent avoir une partie décimale:

var1 = 13
var2 = 15.65
print "var1 is of type ", type(var1)
print "var2 is of type ", type(var2)

Les types entier et à virgule flottante, Int et Float peuvent être mélangés sans problème:

total = var1 + var2
print total
print type(total)

Naturellement, la somme comporte des décimales, n'est-ce pas ? Pendant l'opération, Python automatiquement a décidé que le résultat serait un type Float (virgule flottante). Dans certains cas comme celui-ci, Python détermine automatiquement quel type doit être choisi pour un résultat. Dans d'autres cas il déclanchera une erreur. Par exemple:

varA = "hello 123"
varB = 456
print varA + varB

Dans cet exemple , varA est une chaîne et varB est un int, Python ne mélange pas les types différents et nous donnera une erreur. Mais, nous pouvons forcer Python a mélanger des types différents grâce à la conversion:

varA = "hello"
varB = 123
print varA + str(varB)

Maintenant, l'opération fonctionne, pourquoi ! Vous avez noté, que nous avons converti varB en "string" au moment de l'affichage avec la commande str(), mais nous n'avons pas modifié le type de varB qui reste un int. Si nous voulons convertir varB de façon permanente en une chaîne de caractères pour les besoins futur du programme, nous aurons besoin de faire:

varB = str(varB)

Nous pouvons également utiliser les commandes int() et float() pour convertir une chaîne de caractères str en un int ou float Pour la conversion, il faut faire:

varA = "123"
print int(varA)
print float(varA)

Note au sujet des commandes Python

Vous avez sûrement remarqué que dans cette partie du tutoriel, nous avons utilisé la commande d'affichage print de plusieurs manières. Nous avons affiché des variables, des opérations, des chaînes séparées par des virgules et même le résultat de la commande Python type(). Peut-être avez vous également remarqué qu'en faisant ces deux commandes,

type(varA)
print type(varA)

nous obtenons le même résultat.

Tout s'affiche automatiquement à l'écran parce que nous sommes dans l'interpréteur. Lorsque nous allons écrire des programmes plus complexes qui s'exécuteront hors de l’interpréteur, ils ne seront pas affichés à l'écran, pour les afficher nous aurons besoin d'utiliser la commande print. Mais maintenant, nous allons cesser de l'utiliser pour augmenter la vitesse d'exécution.

Donc, nous allons simplement écrire:

myVar = "hello friends"
myVar

Attention, Python est sensible à la casse, myVar est différent de myvar !!!
Vous avez remarqué que la plupart des commandes Python (ou mots-réservés) que nous connaissons ont des parenthèses, qui sont utilisées pour dire avec quoi la commande doit travailler: type(), int(), str(). . . etc. La seule exception est la commande print, qui en vérité ne l'est pas car, elle peut fonctionner aussi bien avec ou sans parenthèses.
Exemple:

print ("bonjour")
print "bonjour"

Les Listes (Tableaux)

Un autre type de données intéressant, est le type list. Le type list est simplement une collection de données. De la même manière que nous définissons une chaîne de texte en utilisant " " (guillemets), nous définirons des listes en utilisant [ ] (crochets):

myList = [1,2,3]
type(myList)
myOtherList = ["Bart", "Frank", "Bob"]
myMixedList = ["hello", 345, 34.567]

Vous voyez qu'une liste peut contenir n'importe quel type de données. Les listes sont très utiles car vous pouvez grouper des variables ou des données ensembles. Vous pouvez alors faire toutes sortes de choses au sein de ces groupes, par exemple, les compter avec len():

len(myOtherList)

ou récupérer un objet de cette liste:

myName = myOtherList[0]
myFriendsName = myOtherList[1]

Vous voyez que la commande len() renvoie le nombre d'éléments dans une liste, la «position» d'un objet dans la liste commence à 0. Le premier élément dans une liste est toujours à la position 0, donc dans notre myOtherList, "Bob" est a la deuxième position. Nous pouvons faire beaucoup plus de choses avec les listes tel que le tri du contenu, la suppression ou l'ajout d'éléments vous pouvez les lire ici .

Une chaîne de texte est très semblable à une liste et chaque caractère peut être adressé séparément! Essayez ce code:

myvar = "hello"
len(myvar)
myvar[2]

Pratiquement, ce que vous faites avec les listes peut également être fait avec les chaînes de caractères. En fait, les listes et les chaînes de caractères sont des séquences que Python voit en interne de la même manière.

Outre les chaînes de caractères "String", les entiers "Integer", les nombres à virgule flottante "float" et les listes "list", il y a beaucoup de type de données, plus de renseignements sur les dictionnaires. Vous pouvez même créer vos propres types de données avec des classes.

L'Indentation

Une manière pratique et élégante d'afficher chaque élément de la liste, est de naviguer à l’intérieur de cette liste.
Entrez ce code dans la console:

alldaltons = ["Joe", "William", "Jack", "Averell"]
for dalton in alldaltons:
   print dalton + " Dalton"

Nous venons de faire une "itération" (encore un nouveau mot de programmeur!) grâce à notre boucle " for ... in ... : " nous avons scruté chaque "champ" de la variable alldaltons. Notez la syntaxe particulière de la boucle, la commande se termine avec un " : " ce qui indique à Python que la suite sera un bloc d'une ou plusieurs commandes ou instructions.

Après avoir frappé ENTREE derrière le " : ", l'invite de commande va changer en " ... " ce qui indique à Python que la suite sera une partie de celui-ci.

Alors comment savoir, combien de ligne(s) sera ou seront exécutées par Python à l'intérieur de la boucle ? Pour créer un bloc, Python utilise l'indentation. Les prochaines lignes ne commenceront pas au prompt " >>> " mais elles commenceront par un ou plusieurs espaces vides, ou, une ou plusieurs tabulations. Les langages de programmation utilisent leurs propres méthodes , comme, la mise entre parenthèses du bloc, entre un BEGIN ... END etc.

Tant que vous écrirez vos lignes avec la même indentation, elles seront considérées comme faisant partie du bloc. Si vous commencez une ligne avec 2 espaces et la prochaine avec 4 espaces, il y aura une erreur. Lorsque vous avez terminé votre bloc, il suffit d'écrire la suite du programme sans indentation, ou appuyez simplement sur ​​Entrée.

L'indentation permet aussi d'éclaircir la lisibilité du programme. Si vous utilisez de grandes indentations (par exemple, utilisez des tabulations plutôt que des espaces car elles sont plus grandes), lorsque vous écrivez un gros programme, vous aurez une vue claire de ce qui est exécuté à l'intérieur de quoi. Nous verrons que les commandes autres que for-in peuvent aussi avoir des blocs de code en retrait.

La commande " for ... in ... : " peut être utilisée pour de nombreuses procédures qui doivent être effectuées plus d'une fois (en boucle). Elle peut aussi par exemple être combinée avec la commande range():

serie = range(1,11)
total = 0
print "sum"
for number in serie:
   print number
   total = total + number
print "----"
print total

(Si vous avez exécuté les exemples de code dans un interpréteur en copier/coller, vous constaterez que le bloc de texte précédent génère une erreur. Au lieu de cela, copiez à la fin du bloc en retrait, c'est-à-dire la fin de la ligne " = total + nombre " puis collez-le dans l'interpréteur. Dans l'interpréteur, frappez sur la touche Enter jusqu'à ce que l'invite à trois points disparaisse et que le code s'exécute. Copiez ensuite les deux dernières lignes dans l'interpréteur suivi d'une ou plusieurs frappes sur la touche Enter la réponse finale devrait apparaître.)

Si vous tapez dans l'interprèteur help(range) vous allez voir:

range(...)
    range(stop) -> list of integers
    range(start, stop[, step]) -> list of integers

Ici, les crochets indiquent un paramètre facultatif. Cependant, tous sont censés être des entiers. Ci-dessous, nous forcerons les paramètres de la plage à être un entier en utilisant int()

decimales = 1000                     # for 3 decimales 
#decimales = 10000                   # for 4 decimales ...
for i in range(int(0 * decimales),int(180 * decimales),int(0.5 * decimales)):
    print float(i) / decimales

Ou des choses plus complexes comme ceci:

alldaltons = ["Joe", "William", "Jack", "Averell"]
for n in range(4):
   print alldaltons[n], " is Dalton number ", n

Vous voyez que la commande range() a également la particularité de commencer à 0 (si vous ne spécifiez pas un nombre de départ) et que son dernier nombre sera le nombre que vous aurez spécifié moins un . Bien sûr, cette commande fonctionne parfaitement avec les autres commandes Python.

Par exemple:

alldaltons = ["Joe", "William", "Jack", "Averell"]
total = len(alldaltons)
for n in range(total):
   print alldaltons[n]

Une autre fonction intéressante utilisée dans un bloc indenté est la commande de condition if (si). Avec " if " la suite de la procédure sera exécutée uniquement si la condition est remplie.

alldaltons = ["Joe", "William", "Jack", "Averell"]
if "Joe" in alldaltons:
   print "We found that Dalton!!!"

C'est bien, ce code affiche "OK il c'est bien un Dalton !!!" car la condition est exacte. Mais maintenant essayons cette ligne:

if "Lucky" in alldaltons:

Il ne c'est rien affiché car la condition n'était pas remplie. Nous pouvons alors lui demander else (si la condition n'est pas remplie alors):

alldaltons = ["Joe", "William", "Jack", "Averell"]
if "Lucky" in alldaltons:
   print "We found that Dalton!!!"
else:
   print "Such Dalton doesn't exist!"

Les Fonctions

Il n'y a pas beaucoup mots réservés dans Python, à peine une trentaine, et nous en connaissons maintenant quelques unes. Imaginons que nous voulions construire nous même une commande spéciale! Et bien, il est extrêmement facile de construire sa propre commande dans Python. Vous pouvez ajouter ces commandes dans votre installation Python de manière à en augmenter les capacités et les utiliser comme bon vous semble. Ces nouvelles commandes que vous allez créer dans Python, s'appellent des Fonctions. Elles sont faites de cette manière:

def printsqm(myValue):
   print str(myValue)+" square meters"
 
printsqm(45)

(Une autre erreur de copier-coller, copiez uniquement à la fin de la section en retrait, c'est à dire "square meters" Collez le dans l'interpréteur, et appuyez sur la touche Entrée jusqu'à ce que vous voyez l'invite de la ligne finale.)

Extrêmement simple: la commande def() définit une nouvelle fonction. Vous lui donnez un nom, et à l'intérieur de la parenthèse vous définissez les arguments que nous utiliserons dans notre fonction. Les arguments sont des données qui seront transmises à la fonction. Par exemple, regardez la commande len(). Si vous écrivez simplement len(), Python vous dira qu'il a besoin d'un argument. C'est-à-dire que tu veux len() de quelque chose, non ? Ensuite, par exemple, vous écrirez len(myList) et vous aurez la longueur de myList. Eh bien, myList est un argument que vous transmettez à la fonction len(). La fonction len() est définie de manière à savoir quoi faire avec ce qui lui est transmis. Comme nous l'avons fait ici.

Le nom de la variable "myValue" peut être n'importe quel nom, et cette variable ne sera utilisée qu'à l'intérieur de la fonction. C'est juste un nom qui représentera l'argument dans la fonction en vue de l'utiliser, mais elle sert aussi a renseigner la fonction de combien d'arguments elle disposera. Par exemple, faites ceci:

printsqm(45,34)

Cette commande affichera l'erreur "TypeError: printsqm() takes exactly 1 argument (2 given)" car la fonction "def printsqm(myValue):" ne demande qu'un seul argument, "myValue" et, nous lui en avons donné deux, 45 et 34.

Maintenant, écrivez cette fonction:

def sum(val1,val2):
   total = val1 + val2
   return total

sum(45,34)
myTotal = sum(45,34)

Nous avons créé une fonction qui demande deux arguments, les exécutes , et nous renvoie le résultat. Le retour du résultat est très utile car nous pouvons l'utiliser pour l'afficher ou le stocker dans une variable myTotal (pour notre exemple mais n'importe quel nom conviendra) ou les deux. Comme nous sommes dans l'interpréteur de Python, le résultat s'affiche en faisant:

sum(45,34)

Mais une fois le programme terminé et exécuté hors de l'interpréteur il n'y aura pas d'affichage ! Pour afficher le résultat hors de l'interpréteur Python, il faut bien sûr utiliser la commande print. Alors il faudra faire:

print sum(45,34)

Voilà c'est affiché.

Pour plus de renseignements sur les autres possibilités des fonctions.

Les Modules

Maintenant, vous avez une idée du fonctionnement de Python: mais comment faire pour travailler avec les fichiers et les modules.

Jusqu'à présent, nous avons écrit des instructions ligne par ligne pour travailler dans l'interpréteur Python, pas vrai? Lorsque vous voulez faire des choses plus complexes, il est commode d'écrire les premières lignes de code, puis de les exécuter en une seule fois. Eh bien, c'est très facile à faire, et cela permet aussi de sauver son travail. Il suffit d'ouvrir un éditeur de texte (par exemple, Le Bloc-notes Windows), et d'écrire toutes les lignes de code de Python, de la même manière qu'elles sont écrites dans l'interpréteur, avec les indentations, etc. Ensuite, enregistrez le fichier sur votre disque, de préférence avec l'extension .Py.

Voilà, maintenant vous avez un programme Python complet. Bien sûr, il y a de meilleurs éditeurs que le bloc-notes de Windows ou le terminal d'OS X comme l'excellent Notepad++ (pour Windows) qui utilise la coloration syntaxique tout comme XCode (pour OS X) et ceci démontre qu'un programme Python n'est qu'un fichier texte.

Pour exécuter un programme Python, il ya des centaines de manières. Dans Windows, cliquez simplement sur le fichier, ouvrez-le avec Python, et exécutez le. Mais vous pouvez également l'exécuter avec l'interpréteur Python. Pour ce faire, l’interpréteur doit savoir où se trouve le programme .Py. Dans FreeCAD, le plus simple est de placer les fichiers .Py dans le répertoire par défaut destiné aux programmes Python, cet endroit connu de l'interpréteur inclut dans FreeCAD est C:\Program Files\FreeCAD0.12\bin, mais d'autres endroits sont aussi connu de FreeCad C:\Program Files\FreeCAD0.12\Mod (tous les outils de FreeCad) et C:\Travail\Mes documents\. . .\FREECAD\Macro où sont répertoriés tous vos programmes créés dans l’interpréteur de FreeCad Macro → Macros. Le chemin de destination de vos modules peut être forcé à partir du menu Édition → Préférences → Macro Chemin de la macro. (Sous Linux, vous avez probablement un répertoire /home/<username>/.FreeCAD/Mod, ajoutons un sous-répertoire à ce qu'on appelle les scripts où nous placerons le fichier texte.)

Supposons que nous écrivions ce fichier programme:

def sum(a,b):
    return a + b

print "myTest.py succesfully loaded"

et, nous allons l'enregistrer en "test.py" dans . . ./FreeCAD/bin. (ou avec Linux dans /home/<username>/.FreeCAD/Mod/scripts.) Maintenant, allons dans FreeCAD, et dans la fenêtre de l'interpréteur, écrivez:

import myTest

sans l'extension .py.

Le contenu du fichier sera tout simplement exécuté, ligne par ligne, comme si nous l'avions écrit dans l'interpréteur. La fonction somme a été créée, et le message "test.py a bien été chargé" sera affiché. Il ya une grande différence: la commande import est faite non seulement pour exécuter des programmes écrits dans des fichiers comme le nôtre, mais aussi de charger des fonctions dans Python, de sorte qu'elles deviennent disponibles dans l'interpréteur. Les fichiers contenant des fonctions, comme le nôtre, sont appelés modules.

Normalement, lorsque nous écrivons une fonction sum() dans l'interpréteur, nous l'exécutons simplement comme ceci,

sum(14,45)

comme nous l'avons fait plus haut.

Mais quand nous importons un module contenant une fonction comme sum(a,b), la syntaxe est un peu différente. Nous ferons:

myTest.sum(14,45)

Autrement dit, le module est importé comme un «conteneur», et toutes ses fonctions sont à l'intérieur. Cela est extrêmement utile, parce que nous pouvons importer un grand nombre de modules, et de les organiser.
Donc, en bref, quand vous voyez quelque_chose.quelque_chose (avec un point entre les deux), signifie que quelque chose est à l'intérieur quelque chose.

Nous pouvons aussi, importer et extraire notre fonction sum() contenue dans "test.py" directement dans l’interpréteur, comme ceci:

from myTest import *
sum(12,54)

Théoriquement, tous les modules se comportent de cette manière. Vous importez un module, et vous utilisez ses fonctions de cette manière: module.fonction(argument(s)).
Les modules travaillent de cette façon: ils définissent les fonctions, les nouveaux types de données et les classes que vous pouvez utiliser dans l'interpréteur Python ou dans vos propres modules, parce que rien ne vous empêche d'importer d'autres modules à l'intérieur de votre module!

Encore une chose extrêmement utile. Comment connaître les modules disponibles ? quelles sont les fonctions contenues dans ces modules et comment les utiliser (c'est à dire quels arguments sont demandés par la fonction)? Nous avons vu que Python a une fonction d'aide().

Alors, dans l'interpréteur Python de FreeCad faisons:

help()
modules

Will give us a list of all available modules. We can now type q to get out of the interactive help, and import any of them. We can even browse their content with the dir() command

import math
dir(math)

Nous voyons maintenant toutes les fonctions contenues dans le module math, ainsi que des trucs étranges comme: __ doc__, __ FILE__, __ name__ . . . .
Le __ doc__ est extrêmement utile, il s'agit d'un texte de documentation. Dans les modules, chaque fonction de fait a une __ doc__ qui explique comment l'utiliser. Par exemple, nous voyons qu'il ya une fonction sin dans le module math.
Vous voulez savoir comment utiliser cette fonction ? alors:

print math.sin.__doc__

(Cela peut ne pas être évident, mais de chaque côté de doc sont deux caractères de soulignement.)

Et enfin, une dernier chose: Lorsque l'on travaille sur un nouveau module, nous avons besoin de le tester.

La meilleure chose a faire remplacez l'extension de la macro FreeCAD comme suit : myModule.fcmacromyModule.py.

import myModule
myModule.myTestFunction()

Mais que faire, si myTestFunction() ne fonctionne pas correctement? Nous retournons à notre éditeur et nous le corrigeons. Puis, au lieu de fermer et de rouvrir l'interpréteur python, nous allons tout simplement mettre à jour le module comme ceci:

reload(myModule)

Le problème est que Python ne connaît pas l'extension native de FreeCAD : FCMacro

Cependant, il y a deux méthodes que vous pouvez utiliser: A l'intérieur d'une macro utilisez les fonctions Python exec ou execfile.

f = open("myModule","r")
d = f.read()
exec d

ou

execfile "myModule"

Pour Python 3.xxx remplacer ce code par:

exec(open("C:/PathToMyMacro/myMacro.FCMacro").read())

Pour partager le code entre les macros, vous pouvez par exemple accéder au modules FreeCAD ou FreeCADGui (ou tout autre module Python) et leur définir un attribut. Ceci doit survivre après l'exécution de la macro.

import FreeCAD
if hasattr(FreeCAD,"macro2_executed"):
    ...
else:
    FreeCAD.macro2_executed = True # you can assign any value because we only check for the existence of the attribute
    ... execute macro2

Démarrer avec FreeCAD

Eh bien, je pense que maintenant vous devez avoir une bonne idée de la façon dont Python travaille, et vous pouvez commencer à explorer ce que FreeCAD peut nous offrir. Les fonctions Python de FreeCAD sont toutes bien organisées en différents modules. Certaines d'entre elles sont déjà chargées (importées) au démarrage de FreeCAD. Donc, il suffit de faire:

dir()

et lire Scripts de base dans FreeCad...

Bien sûr, nous n'avons vu qu'une très petite partie de l'univers Python. Il existe de nombreux concepts importants que nous n'avons pas mentionné ici.
Voici deux liens de référence de Python sur le net:

Pensez à en faire des onglets !


Arrow-left.svg Page précédente: Macros
Arrow-left.svg Page précédente: Python script tutoriel
Page suivante: Scripts pour Mesh Arrow-right.svg

Python scripting in FreeCAD

FreeCAD a été programmé dès la première ligne de code dans le but d'être totalement contrôlé par des scripts écrits en Python. Presque toutes les procédures de FreeCAD, telles que l'interface, le contenu des scènes, même la représentation du contenu des vues 3D, sont accessibles à partir de l'interpréteur Python ou de vos propres scripts.
Par conséquence, FreeCAD est probablement l'une des applications d'ingénierie la plus profondément personnalisable et évolutive disponible actuellement.

Dans son état actuel, FreeCAD a très peu de commandes de base pour interagir avec vos objets 3D, FreeCAD est encore jeune et est encore au stade de développement, de plus, la philosophie du développement de FreeCAD est orientée de manière à fournir une plate-forme CAD plutôt qu'une application d'utilisation spécifique.
Grâce aux scripts Python utilisables dans FreeCAD, nous avons un moyen très simple et rapide de voir et de tester les nouvelles fonctionnalités des modules élaborés par la communauté internationale des utilisateurs, des utilisateurs qui, généralement connaissent la programmation Python.
Python est l'un des langages interprétés les plus populaires et, généralement considéré comme très facile à apprendre, bientôt, vous pourrez aussi écrire vos scripts pour modeler "votre propre" FreeCAD.

Si vous n'êtes pas familier avec Python, nous vous recommandons de chercher des tutoriels sur internet et "jeter un œil rapide" sur sa structure. Python est un langage très facile à apprendre, en particulier parce qu'il peut être exécuté à l'intérieur de l'interpréteur, de la plus simple commande jusqu'à l'élaboration de programmes complexes, il peut être exécuté à la volée sans avoir besoin de compilateur. FreeCAD dispose de son propre interpréteur Python intégré. Si vous ne voyez pas de fenêtre intitulée Console Python comme illustré ci-dessous, vous pouvez l'activer en cliquant dans la barre d'outils Affichage → Vues → Console Python pour afficher l’interpréteur Python.

L'interpréteur Python

A partir de l’interpréteur Python, vous pouvez accéder à l'ensemble des modules Python installés, les modules originaux de FreeCAD, ainsi que tous les modules supplémentaires que vous installerez plus tard dans FreeCAD. La capture d'écran ci-dessous vous montre l'interpréteur Python:

The FreeCAD Python interpreter

A partir de l’interpréteur, vous pouvez exécuter du code Python et naviguer à travers les classes et fonctions disponibles. FreeCAD fournit un navigateur de classe très pratique pour l'exploration de votre nouvel univers qu'est FreeCAD. Lorsque vous tapez le nom d'une classe connue suivie d'un "." (point) (ce qui veut dire que vous voulez ajouter quelque chose après le point à partir de cette classe), une fenêtre s'ouvre et vous renseigne sur les options et méthodes disponibles dans cette classe. Lorsque vous sélectionnez une option, le texte d'aide qui lui est associé (s'il est disponible) est automatiquement affiché:

The FreeCAD class browser

Alors, commencez ici en tapant App. ou Gui. (Attention à la casse App est différent de app) et regardez ce qui se passe.
Une autre façon plus simple d'explorer Python le contenu des modules et des classes est d'utiliser la commande d'affichage dir().
Par exemple, en tapant dir() tous les modules actuellements répertoriés et chargés dans FreeCAD s'affichent.Si vous tapez dir(App) tout ce qu'il y a à l'intérieur du module App sera affiché , etc.

Une autre caractéristique utile de l'interprèteur est la possibilité de revenir en arrière dans l'historique des commandes et récupérer une ligne de code que vous avez tapé plus tôt. Pour naviguer dans l'historique des commandes, il suffit d'utiliser CTRL + HAUT ou CTRL + BAS.

Si vous cliquez avec le bouton droit de la souris dans la fenêtre de l'interpréteur, vous avez également les options classiques d'un traitement de texte, telles que copier tout l'histoire (utile lorsque vous voulez expérimenter votre code avant de faire votre script final), ou d'insérer un nom de fichier avec le chemin complet.

Aide Python

Dans le menu Aide de FreeCAD, vous trouverez une entrée portant la mention 'Automatic python modules documentation' qui va ouvrir une fenêtre de navigateur contenant la liste complète de la documentation de l'ensemble des modules Python à disposition de l’interpréteur FreeCAD. Ce sont les modules fournis avec Python et ceux intégrés dans FreeCAD. La documentation disponible dépend de l'effort que le développeur a mis pour documenter le code son module, les modules Python en général, ont la réputation d'être bien documentés. FreeCAD doit rester ouvert pour travailler avec ce système de documentation. L'entrée 'Aide Python' vous donnera un lien rapide vers cette section du wiki "User Hub".

Modules incorporés (Built-in)

FreeCAD étant conçu pour être exécuté sans interface graphique (GUI), la quasi-totalité de ses fonctionnalités est séparé en deux groupes: les fonctionnalités de base, nommés «App», et la fonctionnalité graphique, nommée «Gui». Donc, nos deux principaux modules dans FreeCAD sont appelés App et Gui.
Ces deux modules peuvent également être accessibles à partir des scripts, respectivement avec les noms FreeCAD et FreeCADGui. Ils sont accessibles même hors de l’interpréteur.

  • Dans l'App module, vous trouverez tout ce qui concerne l'application elle-même, comme, les procédures d'ouvrir ou fermeture de fichiers, comme l'ouverture de la feuille active ou lister le contenu de la feuille . . .
  • Dans l'Gui module, vous trouverez des outils pour accéder et gérer les éléments graphiques, comme les boutons utilisateurs et leur barres d'outils, et, plus intéressant, la représentation graphique de l'ensemble du contenu FreeCAD.

Lister tout le contenu de ces modules est un contre-productif, car ils grandissent très vite compte tenu de la progression du développement de FreeCAD.
Mais les deux outils fourni (le navigateur de classe et de l'aide de Python) vous donnerons, à tout moment, une complète documentation mise à jour sur ces modules.

Les objets "App" et "Gui"

Comme nous l'avons dit, dans FreeCAD, tout est séparé entre le noyau et la représentation du projet. Y compris les objets 3D.
Vous pouvez accéder aux propriétés des objets (appelés fonctions dans FreeCAD) via le module App, et modifier la façon dont ils sont représentés sur l'écran via le module de Gui.
Par exemple, un cube possède des propriétés qui le définissent, (comme la largeur, longueur, hauteur) qui sont stockées dans un App objet et, les propriétés de représentation (comme la couleur des faces, le mode de dessin) qui sont stockées dans un objet correspondant Gui.

Cette méthode de travail permet une multitude d'utilisations, comme des algorithmes travaillant uniquement sur la partie caractéristiques, sans avoir à se soucier de la partie visuelle, voire de réorienter le contenu du document à une partie non-graphique de l'application, tels que des listes, des tableurs, ou l'analyse d'éléments.

Pour chaque objet App dans votre document, il existe un objet correspondant Gui.
En fait le document lui-même possède à la fois des objets App et des objets Gui. Bien sûr, ceci n'est valable que lorsque vous exécutez FreeCAD dans son interface graphique. Dans la version en ligne de commande (sans interface graphique), seuls les "objets App" sont accessibles.
Notez que la partie "objet Gui" est réactualisé chaque fois qu'un "objet App" est recalculé (par exemple lorsqu'il y a un changement de paramètres), les changements que vous pourriez avoir fait directement à l'objet Gui peuvent être perdues.

Pour accéder à la partie App d'un objet, vous devez tapez:

myObject = App.ActiveDocument.getObject("ObjectName")

où "ObjectName" est le nom de votre objet.
Le même résultat est obtenu en tapant:

myObject = App.ActiveDocument.ObjectName

Pour accéder à la partie Gui d'un l'objet , vous tapez:

myViewObject = Gui.ActiveDocument.getObject("ObjectName")

où "ObjectName" est le nom de votre objet.
Le même résultat est obtenu en tapant:

myViewObject = App.ActiveDocument.ObjectName.ViewObject

Si vous n'êtes pas dans l'interface graphique (Gui) (par exemple si vous êtes en mode ligne de commande), la dernière ligne retournée sera 'None'.

Les objets dans un document

Dans FreeCAD tout votre travail est dans un "Document". Ce document contient vos formes géométriquee et peut être sauvegardé dans un fichier. Dans FreeCAD, plusieurs documents peuvent être ouverts en même temps. Le document, et les formes géométriques contenues , sont des objets App et des objets Gui. Les objets App contiennent les définitions des formes géométriques réelles, tandis que les objets Gui contiennent les différentes vues de votre document.
Vous pouvez ouvrir plusieurs fenêtres, chacune de ces fenêtres peut afficher votre projet avec un facteur de zoom différent ou des vues différentes du projet. Ces vues font toutes partie de l'objet Gui de votre document.

Pour accéder à la partie App du document ouvert (actif), tapez:

myDocument = App.ActiveDocument

Pour créer un nouveau document, tapez:

myDocument = App.newDocument("Document Name")

Pour accéder à la partie graphique (Gui) du document ouvert (actif), tapez:

myGuiDocument = Gui.ActiveDocument

Pour accéder à la vue courante, tapez:

myView = Gui.ActiveDocument.ActiveView

Modules supplémentaires

Les modules FreeCAD et FreeCADGui sont utilisés uniquement pour créer et gérer des objets dans le document FreeCAD. Ils ne sont pas utilisés pour la création ou la modification des formes géométriques.
Les formes géométriques peuvent être de plusieurs types, elles sont donc construites par des modules supplémentaires, chaque module s'occupe la gestion d'un type de forme géométrique spécifique.
Par exemple, le module "Part utilisé par le noyau OpenCascade, et donc capable de créer et manipuler des formes géométriques de type B-rep, pour lequel OpenCascade est construit.
Le module "Mesh" est capable de construire et modifier des objets Mesh (mailles). De cette façon, FreeCAD est capable de gérer une grande variété de types d'objets, qui peuvent coexister dans le même document, et de nouveaux types d'objets pourront êtres ajoutés facilement et constamment.

Création d'objets

Chaque module a sa propre manière de gérer sa forme géométrique, mais il y a une chose qu'ils peuvent tous faire, c'est de créer des objets dans le document.
Mais, le document FreeCAD connaît tous les types d'objets disponibles fournis par les modules,
tapez:

FreeCAD.ActiveDocument.supportedTypes()

FreeCAD listera tous les objets possibles que vous pouvez créer.
Par exemple, nous allons créer un objet maillage (traité par le module "Mesh") et une objet Part (traité par le module le "Part"):

myMesh = FreeCAD.ActiveDocument.addObject("Mesh::Feature","myMeshName")
myPart = FreeCAD.ActiveDocument.addObject("Part::Feature","myPartName")

Le premier argument est le type d'objet "Mesh::", le second est le nom de l'objet "myMeshName". Nos deux objets semblent identiques: Ils ne contiennent pas encore de forme géométrique, et la plupart de leurs propriétés sont les mêmes lorsque vous les inspecter avec dir(myMesh) et dir(myPart).
Sauf que, myMesh a une propriété "Mesh" (maille) et myPart a une propriété "Part" (forme géométrique).
C'est de cette manière que les données de "Mesh" (maillage) et "Part" (forme géométrique) sont stockées.
Par exemple, nous allons créer un cube (Part) et le stocker dans notre objet myPart:

import Part
cube = Part.makeBox(2,2,2)
myPart.Shape = cube

Si vous essayez de stocker le cube avec la propriété objet Mesh "myMesh", il retournera une erreur de type. Car ces propriétés sont conçues uniquement pour stocker un type d'objet bien défini.
Dans la propriété objet Mesh "myMesh", vous ne pouvez enregistrer que des objets créé avec le module Mesh.
Notez que la plupart des modules disposent également d'un raccourci pour ajouter leur formes géométriques au document:

import Part
cube = Part.makeBox(2,2,2)
Part.show(cube)

Modification d'objets

La modification d'un objet est faite de la même manière:

import Part
cube = Part.makeBox(2,2,2)
myPart.Shape = cube

Maintenant, nous allons construire un cube plus gros:

biggercube = Part.makeBox(5,5,5)
myPart.Shape = biggercube

Questionner les objets

Vous pouvez toujours connaître de quel type est un objet.
Faites ceci:

myObj = FreeCAD.ActiveDocument.getObject("myObjectName")
print myObj.TypeId

ou de savoir si un objet fait partie d'un modèle de base (Part Feature, Mesh Feature, etc):

print myObj.isDerivedFrom("Part::Feature")

Maintenant vous pouvez commencer à travailler avec FreeCAD! Pour savoir ce que vous pouvez faire avec le Part Module, lisez la page Part scripting, ou la page Script Mesh pour travailler avec le module Mesh .
Notez que, bien que les modules Part et Mesh sont les plus complets et les plus largement utilisés, les autres modules tels que le Draft Module (Projet) ont également leurs API scripts qui peuvent vous être utiles.
Pour une liste complète de chaque module et de leurs outils disponibles, visitez la section :Category:API (en).

Arrow-left.svg Page précédente: Python script tutoriel
Page suivante: Scripts pour Mesh Arrow-right.svg


Arrow-left.svg Page précédente: Débuter avec les scripts
Page suivante: Script pour les pièces Arrow-right.svg

Introduction

Avant de commencer, vous devez importer le module Mesh.
Tapez (Attention à la classe Mesh est différent de mesh):

import Mesh

Dès que vous avez importé le module de maillage de la classe Mesh, vous accéderez facilitent aux fonctions C++ Mesh-Kernel de FreeCAD.

Création et chargement

Pour créer un objet maillage vide il suffit d'utiliser la commande standard :

mesh = Mesh.Mesh()

Vous pouvez aussi créer un objet à partir d'un fichier

mesh = Mesh.Mesh('D:/temp/Something.stl')

(Une liste de fichiers compatibles avec "Mesh" (maillage) est disponible ici).

ou créer un ensemble de triangles en les décrivant par leurs sommets (Vertex) :

planarMesh = [
# triangle 1
[-0.5000,-0.5000,0.0000],[0.5000,0.5000,0.0000],[-0.5000,0.5000,0.0000],
#triangle 2
[-0.5000,-0.5000,0.0000],[0.5000,-0.5000,0.0000],[0.5000,0.5000,0.0000],
]
planarMeshObject = Mesh.Mesh(planarMesh)
Mesh.show(planarMeshObject)

Le kernel-Mesh prend soin de créer une structure correcte de données topologiques en triant les points communs et des bords coïncidents.

Plus tard, vous verrez comment tester et examiner les données de maillage.

Modélisation

Pour créer des formes géométriques régulières, vous pouvez utiliser le script Python BuildRegularGeoms.py.

import BuildRegularGeoms

Ce script fournit les méthodes pour construire des figures simples qui ont besoin d'une rotation comme des sphères, ellipsoïdes, cylindres, tores et cônes. Il existe aussi une méthode pour créer un simple cube.
Pour créer un tore, par exemple, nous ferons :

t = BuildRegularGeoms.Toroid(8.0, 2.0, 50) # list with several thousands triangles
m = Mesh.Mesh(t)

Les deux premiers paramètres définissent les rayons du tore, et le troisième paramètre est un facteur de sous-échantillonnage pour le nombre de triangles qui seront créés. Plus cette valeur est élevée plus la figure sera lisse et plus cette valeur est basse plus grossière sera la figure.
La classe Mesh offre un ensemble de fonctions booléennes qui peuvent êtres utilisées à des fins de modélisation. Il fournit l'union, l'intersection et la différence entre deux objets maillés.

m1, m2              # are the input mesh objects
m3 = Mesh.Mesh(m1)  # create a copy of m1
m3.unite(m2)        # union of m1 and m2, the result is stored in m3
m4 = Mesh.Mesh(m1)
m4.intersect(m2)    # intersection of m1 and m2
m5 = Mesh.Mesh(m1)
m5.difference(m2)   # the difference of m1 and m2
m6 = Mesh.Mesh(m2)
m6.difference(m1)   # the difference of m2 and m1, usually the result is different to m5

Et ici, un exemple complet qui calcule l'intersection entre une sphère et un cylindre qui coupe la sphère.

import Mesh, BuildRegularGeoms
sphere = Mesh.Mesh( BuildRegularGeoms.Sphere(5.0, 50) )
cylinder = Mesh.Mesh( BuildRegularGeoms.Cylinder(2.0, 10.0, True, 1.0, 50) )
diff = sphere
diff = diff.difference(cylinder)
d = FreeCAD.newDocument()
d.addObject("Mesh::Feature","Diff_Sphere_Cylinder").Mesh=diff
d.recompute()

Examens et Test

Ecrire vos propres algorithmes

Exporter

Vous pouvez même écrire votre modèle de maillage dans un module Python :

m.write("D:/Develop/Projekte/FreeCAD/FreeCAD_0.7/Mod/Mesh/SavedMesh.py")
import SavedMesh
m2 = Mesh.Mesh(SavedMesh.faces)

Relations avec Gui (Interface graphique)

Modules supplémentaires à tester

Une extension (difficile à utiliser) de scripts Mesh qui est à tester.
Dans cette compilation test, toutes les méthodes sont appelées et toutes les propriétés et attributs sont manipulés.
Donc si vous êtes assez audacieux pour le tester, allez voir cette compilation de modules "unifié".

Voir aussi Mesh API

Arrow-left.svg Page précédente: FreeCAD Scripting Basics
Arrow-left.svg Page précédente: Script pour le maillage
Page suivante: Mesh to Part Arrow-right.svg
Base ExampleCommandModel.png Tutoriel
Thème
Programming
Niveau
Intermediate
Temps d'exécution estimé
Auteur
Version de FreeCAD
Fichier(s) exemple(s)

Contents



Cette page décrit différentes méthodes pour créer et modifier des pièces avec Python.
Avant de lire cette page, si vous n'êtes pas familier avec la programmation Python, vous pouvez vous diriger sur cette page d'introduction à Python et scripts de base en Python pour FreeCAD.

Introduction

Ici nous allons vous expliquer comment contrôler la boîte à outils (Part Module) ou de n'importe quel script externe, directement à partir de l'interpréteur Python inclus dans FreeCAD, .
Assurez-vous de parcourir l'article de familiarisation et scripts de base si vous avez besoin de plus amples renseignements sur la façon dont les scripts Python fonctionnent dans FreeCAD.

Class Diagram

Ceci est un Unified Modeling Language (UML) de la classe la plus importante de Part Module:

Python classes of the Part module

Figures géométriques

Les objets géométriques sont la base de tous les objets topologiques :

  • Geom La classe de base des objets géométriques
  • Line Une ligne droite en 3D, défini par un point de départ et point d'arrivée
  • Circle Circle or circle segment défini par un point central, un point de départ et un point d'arrivée
  • ...... Et bien plus encore très rapidement

Topology

Sont aussi disponibles des données de type topologique:

  • Compound Groupe de types différents d'objets topologiques.
  • Compsolid Un groupe de solides reliés par leurs faces. C'est un concept des notions de WIRE (filaire,bord..) et SHELL (coquille,enveloppe) des solides.
  • Solid Une portion de l'espace limité par son enveloppe. Il est en 3 dimensions.
  • Shell Un groupe de faces reliés par leurs bords.Un "SHELL" peut être ouvert ou fermé.
  • Face En 2D, c'est une surface plane; en 3D, c'est une seule face du volume. Sa géométrie est coupée par des contours. Il est en deux dimensions.
  • Wire Un ensemble relié par ses VERTEX (sommets). Il peut être de contour ouvert ou fermé suivant si les sommets sont reliés ou non.
  • Edge Elément topologique correspondant à une courbe retenue. Un "Edge" est généralement limité par des sommets. Il a une dimension.
  • Vertex Elément topologiques correspondant à un point. Il n'a pas de dimension.
  • Shape Est le terme générique pour traduire tout ce qui précède.

Exemple rapide : Création topologique simple

Wire


Nous allons créer une topologie avec une géométrie toute simple.
Nous devrons veiller à ce que les sommets des pièces géométriques soient à la même position, quatre sommets, deux cercles et deux lignes.

Création de la géométrie

Nous devons d'abord créer les parties distinctes géométriques en filaire.
Nous devons veiller à ce que tous les sommets des pièces géométriques qui vont êtres raccordées soient à la même position.
Sinon, plus tard nous pourrions ne pas être en mesure de relier les pièces géométriques en une topologie!

Donc, nous créons d'abord les points:

from FreeCAD import Base
V1 = Base.Vector(0,10,0)
V2 = Base.Vector(30,10,0)
V3 = Base.Vector(30,-10,0)
V4 = Base.Vector(0,-10,0)

Arc

Circle


Pour créer un arc de cercle, nous créons un point de repère puis nous créons l'arc de cercle passant par trois points:

VC1 = Base.Vector(-10,0,0)
C1 = Part.Arc(V1,VC1,V4)
# and the second one
VC2 = Base.Vector(40,0,0)
C2 = Part.Arc(V2,VC2,V3)

Ligne

Line


La ligne segment peut être créée très simplement en dehors des points :

L1 = Part.LineSegment(V1,V2)
# and the second one
L2 = Part.LineSegment(V3,V4)

Note: dans FreeCAD 0.16 Part.Line était utilisé, depuis la version FreeCAD 0.17 Part.LineSegment est utilisé

Tout relier

La dernière étape consiste à relier les éléments géométriquement ensemble, et façonner une forme topologique:

S1 = Part.Shape([C1,L1,C2,L2])

Construire un prisme

Maintenant nous allons extruder notre forme filaire dans une direction, et créer une forme en 3 Dimensions:

W = Part.Wire(S1.Edges)
P = W.extrude(Base.Vector(0,0,10))

Affichons le tout

Part.show(P)

Création de formes simples

Vous pouvez créer facilement des formes topologiques avec "make...()" qui est une méthode du "Module Part":

b = Part.makeBox(100,100,100)
Part.show(b)

La combinaison de make...() avec d'autres methodes sont disponibles:

  • makeBox(l,w,h): Construit un cube et pointe sur p dans la direction d et de dimensions (longueur,largeur,hauteur).
  • makeCircle(radius): Construit un cercle de rayon (r).
  • makeCone(radius1,radius2,height): Construit un cône de (rayon1,rayon2,hauteur).
  • makeCylinder(radius,height): Construit un cylindre de (rayon,hauteur).
  • makeLine((x1,y1,z1),(x2,y2,z2)): Construit une ligne aux coordonnées (x1,y1,z1),(x2,y2,z2) dans l'espace 3D.
  • makePlane(length,width): Construit un rectangle de (longueur,largeur).
  • makePolygon(list): Construit un polygone (liste de points).
  • makeSphere(radius): Construit une sphère de (rayon).
  • makeTorus(radius1,radius2): Construit un tore de (rayon1,rayon2).

La liste complète des API du module est sur la page Part API.

Importer les modules nécessaires

Nous avons d'abord besoin d'importer le module Part afin que nous puissions utiliser son contenu Python.
Nous allons également importer le module Base à l'intérieur du module de FreeCAD:

import Part
from FreeCAD import Base

Création d'un Vecteur

Les Vecteurs sont l'une des informations les plus importantes lors de la construction des formes géométriques.
Ils contiennent habituellement 3 nombres (mais pas toujours) les coordonnées cartésiennes x, y et z.
Vous pouvez créez un vecteur comme ceci:

myVector = Base.Vector(3,2,0)

Nous venons de créer un vecteur de coordonnées x = 3, y = 2, z = 0.
Dans le module Part, les vecteurs sont utilisés partout.
Le module Part utilise aussi une autre façon de représenter un point, appelé Vertex, qui est simplement un conteneur pour un vecteur.
Vous pouvez accéder aux vecteurs d'un sommet comme ceci:

myVertex = myShape.Vertexes[0]
print myVertex.Point
> Vector (3, 2, 0)

Création d'une arête (edge)

Une arête (bord) n'est rien d'autre qu'une ligne avec deux Vertex (sommets):

edge = Part.makeLine((0,0,0), (10,0,0))
edge.Vertexes
> [<Vertex object at 01877430>, <Vertex object at 014888E0>]

PS: Vous pouvez aussi créer un arête en donnant deux Vecteurs:

vec1 = Base.Vector(0,0,0)
vec2 = Base.Vector(10,0,0)
line = Part.LineSegment(vec1,vec2)
edge = line.toShape()

Vous pouvez trouver la longueur et le centre d'une arête comme ceci:

edge.Length
> 10.0
edge.CenterOfMass
> Vector (5, 0, 0)

Mise en forme à l'écran

Jusqu'à présent, nous avons créé un objet a arêtes vives (bords), mais il n'est pas visible à l'écran.
C'est parce que nous n'avons manipulé que des objets en Python.
L'écran FreeCAD n'affiche uniquement que les vues 3D que vous lui demandez d'afficher.
Pour cela, nous utilisons une méthode simple:

Part.show(edge)

La fonction show crée un objet dans notre document FreeCAD et assigne notre forme "edge" à cela.
Utilisez cette commande chaque fois que vous voudrez afficher votre forme géométrique à l'écran.

Création d'un contour (Wire)

Un contour est une ligne multi-arêtes, et peut être créé dans une liste d'arêtes ou même une liste de lignes (fils):

edge1 = Part.makeLine((0,0,0), (10,0,0))
edge2 = Part.makeLine((10,0,0), (10,10,0))
wire1 = Part.Wire([edge1,edge2]) 
edge3 = Part.makeLine((10,10,0), (0,10,0))
edge4 = Part.makeLine((0,10,0), (0,0,0))
wire2 = Part.Wire([edge3,edge4])
wire3 = Part.Wire([wire1,wire2])
wire3.Edges
> [<Edge object at 016695F8>, <Edge object at 0197AED8>, <Edge object at 01828B20>, <Edge object at 0190A788>]
Part.show(wire3)

Part.show (wire3) permet d'afficher les 4 bords qui composent notre contour filaire.
D'autres informations utiles, peuvent être facilement récupérées:

wire3.Length
> 40.0
wire3.CenterOfMass
> Vector (5, 5, 0)
wire3.isClosed()
> True
wire2.isClosed()
> False

Création d'une face

Seul les faces à contour fermés seront valides.
Dans cet exemple, wire3 est un contour fermé, et Wire2 est un contour ouvert (voir ci-dessus)

face = Part.Face(wire3)
face.Area
> 99.999999999999972
face.CenterOfMass
> Vector (5, 5, 0)
face.Length
> 40.0
face.isValid()
> True
sface = Part.Face(wire2)
face.isValid()
> False

Seul les faces auront une superficie, mais les lignes et les bords (arêtes) n'en possède pas .

Création d'un cercle

Un cercle est créé simplement comme ceci:

circle = Part.makeCircle(10)
circle.Curve
> Circle (Radius : 10, Position : (0, 0, 0), Direction : (0, 0, 1))

Si vous voulez le créer à une certaine position et avec une certaine direction:

ccircle = Part.makeCircle(10, Base.Vector(10,0,0), Base.Vector(1,0,0))
ccircle.Curve
> Circle (Radius : 10, Position : (10, 0, 0), Direction : (1, 0, 0))

ccircle sera créé à une distance de 10 de l’origine x et sera face à l'extérieur le long de l'axe des x. Remarque: makeCircle accepte uniquement Base.Vector() pour la position et les paramètres normaux, pas les tuples. Vous pouvez également créer une partie du cercle en donnant un angle de début et de fin:

from math import pi
arc1 = Part.makeCircle(10, Base.Vector(0,0,0), Base.Vector(0,0,1), 0, 180)
arc2 = Part.makeCircle(10, Base.Vector(0,0,0), Base.Vector(0,0,1), 180, 360)

Si nous joignions les deux arcs arc1 et arc2 nous obtiendrons un cercle.
L'angle fourni doit être exprimé en degrés, s'il sont en radians, vous devez les convertir en degrès avec la formule: degrés = radians * 180/PI ou en utilisant le module mathématiques Python (après avoir fait import math, bien sûr):

degrees = math.degrees(radians)

Création d'un arc sur des points (repères)

Malheureusement, il n'existe pas de fonction makeArc mais nous avons la fonction Part.Arc pour créer un arc sur trois points de référence.
Fondamentalement, nous pouvons supposer un arc attaché sur un point de départ, passant sur un point central et se termine sur un point final en .
Part.Arc crée un objet arc pour lequel .ToShape() doit être appelée pour obtenir un objet ligne (edge), de cette manière nous utiliserons Part.LineSegment au lieu de Part.makeLine.

arc = Part.Arc(Base.Vector(0,0,0),Base.Vector(0,5,0),Base.Vector(5,5,0))
arc
> <Arc object>
arc_edge = arc.toShape()

Arc travaille uniquement avec Base.Vector() pour les points mais pas pour les tuples.
arc_edge est ce qui sera affiché à l'aide Part.show (arc_edge).
Vous pouvez également obtenir un arc de cercle en utilisant une partie de cercle:

from math import pi
circle = Part.Circle(Base.Vector(0,0,0),Base.Vector(0,0,1),10)
arc = Part.Arc(circle,0,pi)

Les arcs Arc sont des lignes (edges). Ils peuvent donc être utilisés aussi comme contour en filaire.

Création de polygones

Un polygone est tout simplement une ligne (wire) avec de multiples lignes droites.
La fonction makePolygon crée une liste de points et crée une ligne de points en points:

lshape_wire = Part.makePolygon([Base.Vector(0,5,0),Base.Vector(0,0,0),Base.Vector(5,0,0)])

Création de courbes de Bézier

Les courbes de Bézier sont utilisées pour modéliser des courbes lisses à l'aide d'une série de repères (points de contrôle) avec un nombre de repères représentants la précision (fluidité de la courbe) optionnel. La fonction ci-dessous fait un Part.BezierCurve avec une série de points FreeCAD.Vector. (Note : l'indice du premier repère et du nombre commencent à 1, et pas à 0.)

def makeBCurveEdge(Points):
   geomCurve = Part.BezierCurve()
   geomCurve.setPoles(Points)
   edge = Part.Edge(geomCurve)
   return(edge)

Création d'une forme plane

Une forme plane, est tout simplement une surface plane rectangulaire.
La méthode utilisée pour créer une forme plane est la suivante: makePlane(longueur, largeur, [point de départ, direction]).
Par défaut point de départ = Vecteur(0,0,0) et direction = Vecteur(0,0,1).
L'utilisation point de départ = Vecteur(0,0,1) va créer la forme sur l' axe z positif, tandis que direction = Vecteur(1,0,0) va créer la forme sur l'axe x positif:
(Pour s'y retrouver un peu sur les axes, Vecteur ( 0 , 0 , 1 ) est égal à Vecteur ( X=0 , Y=0 , Z=1 ) l'ordre des axes sera toujours ( x , y , z ))

plane = Part.makePlane(2,2)
plane
><Face object at 028AF990>
plane = Part.makePlane(2, 2, Base.Vector(3,0,0), Base.Vector(0,1,0))
plane.BoundBox
> BoundBox (3, 0, 0, 5, 0, 2)

BoundBox est un rectangle qui possède une diagonale commençant sur le plan (3,0,0) et se terminant à (5,0,2).
L'épaisseur de la boîte (Box) dans l'axe y est égal à zéro, car notre forme est totalement plane.

PS: makePlane accepte uniquement Base.Vector() pour start_pnt et dir_normal mais pas les tuples.

Création d'une ellipse

Pour créer une ellipse, il existe plusieurs façons:

Part.Ellipse()

Créez une ellipse avec un grand rayon = 2 et un petit rayon = 1 et un centre = (0,0,0).

Part.Ellipse(Ellipse)

Créez une copie des données de l'ellipse

Part.Ellipse(S1,S2,Center)

Crée une ellipse positionnée au point "Center", le plan de l'ellipse est défini par Center, S1 et S2,
le grand axe est définit par Center et S1,
son grand rayon est la distance entre Center et S1,
son petit rayon est la distance entre S2 et le grand axe.

Part.Ellipse(Center,MajorRadius,MinorRadius)

Crée une ellipse avec un grand rayon MajorRadius et un petit rayon MinorRadius et situé dans le plan défini par (0,0,1)

eli = Part.Ellipse(Base.Vector(10,0,0),Base.Vector(0,5,0),Base.Vector(0,0,0))
Part.show(eli.toShape())

Dans le code ci-dessus, nous avons passé S1 (Grand rayon), S2 (Petit rayon) et le centre (les coordonnées centrales).
De même que l'Arc, l'Ellipse crée également un objet Ellipse mais pas d'arête (bords), nous avons donc besoin de le convertir en arête à l'aide toShape() pour l'afficher.

PS: Arc accepte uniquement Base.Vector() pour les points mais pas les tuples.

eli = Part.Ellipse(Base.Vector(0,0,0),10,5)
Part.show(eli.toShape())

pour construire l'Ellipse ci-dessus, nous avons entré les coordonnées centrales, le Grand rayon et le Petit rayon.

Création d'un Tore

Nous créons un Tore en utilisant la méthode makeTorus( rayon1 , rayon2 , [ pnt , dir , angle1 , angle2 , angle ] ).
Par défaut,
Rayon1 = est le rayon du grande cercle
Rayon2 = est le rayon du petit cercle,
pnt = Vecteur(0,0,0),pnt est le centre de tore
dir = Vecteur(0,0,1), dir est la direction normale
angle1 = 0, est l'angle de début pour le petit cercle exprimé en radians
angle2 = 360 est l'angle de fin pour le petit cercle exprimé en radians
angle = 360 le dernier paramètre est la section du tore

torus = Part.makeTorus(10, 2)

Le code ci-dessus créera un tore avec un diamètre de 20 (rayon de 10) et une épaisseur de 4 (rayon du petite cercle 2)

tor=Part.makeTorus(10, 5, Base.Vector(0,0,0), Base.Vector(0,0,1), 0, 180)

Le code ci-dessus créera une portion du tore.

tor=Part.makeTorus(10, 5, Base.Vector(0,0,0), Base.Vector(0,0,1), 0, 360, 180)

Le code ci-dessus créera un demi tore; seul le dernier paramètre change à savoir l'angle et les angles restants sont prédéfinis.
En donnant un angle de 180 degrés, créez un tore de 0 à 180 degrés, c'est à dire un demi tore.

Création d'un cube ou d'un parallélépipède

Utilisez makeBox(length,width,height,[pnt,dir]).
Par défaut pnt=Vector(0,0,0) and dir=Vector(0,0,1).

box = Part.makeBox(10,10,10)
len(box.Vertexes)
> 8

Création d'une Sphère

Nous utiliserons makeSphere ( rayon , [ pnt , dir , angle1 , angle2 , angle3 ] ).
rayon = rayon de la sphère par défaut,
pnt = Vecteur (0,0,0),
dir = Vecteur (0,0,1),
angle1 = -90, verticale minimale de la sphère
angle2 = 90, verticale maximale de la sphère
angle3 = 360, le diamètre de la sphère.

sphere = Part.makeSphere(10)
hemisphere = Part.makeSphere(10,Base.Vector(0,0,0),Base.Vector(0,0,1),-90,90,180)

Création d'un Cylindre

Nous utiliserons makeCylinder(radius,height,[pnt,dir,angle]).
Par défaut,
pnt=Vector(0,0,0), dir=Vector(0,0,1) et angle=360.

cylinder = Part.makeCylinder(5,20)
partCylinder = Part.makeCylinder(5,20,Base.Vector(20,0,0),Base.Vector(0,0,1),180)

Création d'un Cône

Nous utiliserons makeCone(radius1,radius2,height,[pnt,dir,angle]).
Par défaut,
pnt=Vector(0,0,0), dir=Vector(0,0,1) et angle=360.

cone = Part.makeCone(10,0,20)
semicone = Part.makeCone(10,0,20,Base.Vector(20,0,0),Base.Vector(0,0,1),180)

Modification d'une forme

Il y a plusieurs manières de modifier des formes. Certaines sont de simples opérations de transformation telles que le déplacement ou la rotation de formes, d'autres sont plus complexes telles que fusion et soustraction d'une forme à une autre.

Opérations de Transformation

Transformer une forme

La transformation est l'action de déplacer une forme d'un endroit à un autre.
Toute forme (arête, face, cube, etc ..) peut être transformé de la même manière:

myShape = Part.makeBox(2,2,2)
myShape.translate(Base.Vector(2,0,0))

Cette commande va déplacer notre forme "myShape" de 2 unités dans la direction x.

Rotation d'une forme

Pour faire pivoter une forme, vous devez spécifier le centre de rotation, l'axe, et l'angle de rotation:

myShape.rotate(Vector(0,0,0),Vector(0,0,1),180)

Cette opération va faire pivoter notre forme de 180 degrés sur l'axe z.

Transformations génériques avec matrices

Une matrice est un moyen très simple de mémoriser les transformations dans le mode 3D. Dans une seule matrice, vous pouvez définir les valeurs de transformation, rotation et mise à l'échelle à appliquer à un objet.
Par exemple:

myMat = Base.Matrix()
myMat.move(Base.Vector(2,0,0))
myMat.rotateZ(math.pi/2)

PS: les matrices de FreeCAD travaillent en radians. En outre presque toutes les opérations matricielles qui travaillent avec un vecteur peut aussi avoir 3 nombres de sorte que ces 2 lignes effectuent le même travail:

myMat.move(2,0,0)
myMat.move(Base.Vector(2,0,0))

Lorsque notre matrice est paramétrée, nous pouvons l'appliquer à notre forme. FreeCAD fournit nous fournit 2 méthodes: transformShape() et transformGeometry().
La différence est que, avec la première, vous ne verez pas de différence (voir "mise à l'échelle d'une forme" ci-dessous).
Donc, nous pouvons opérer notre transformation comme ceci:

myShape.transformShape(myMat)

ou

myShape.transformGeometry(myMat)

Echelle du dessin (forme)

Changer l'échelle d'une forme est une opération plus dangereuse, car, contrairement à la translation ou à la rotation, le changement d'échelle non uniforme (avec des valeurs différentes pour x, y et z) peut modifier la structure de la forme!
Par exemple, le redimensionnement d'un cercle avec une valeur plus élevée horizontalement que verticalement le transformera en une ellipse, qui mathématiquement très différent.
Pour modifier l'échelle, nous ne pouvons pas utiliser le transformShape, nous devons utiliser transformGeometry():

myMat = Base.Matrix()
myMat.scale(2,1,1)
myShape=myShape.transformGeometry(myMat)

Opérations Booléennes

Soustraction

Soustraire une forme d'une autre est appelé, dans le jargon OCC/FreeCAD "cut" (coupe) et,
se fait de cette manière:

cylinder = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0))
sphere = Part.makeSphere(5,Base.Vector(5,0,0))
diff = cylinder.cut(sphere)

Intersection

De la même manière, l'intersection entre 2 formes est appelé "common" et se fait de cette manière:

cylinder1 = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0))
cylinder2 = Part.makeCylinder(3,10,Base.Vector(5,0,-5),Base.Vector(0,0,1))
common = cylinder1.common(cylinder2)

Fusion

La fusion "fuse", fonctionne de la même manière:

cylinder1 = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0))
cylinder2 = Part.makeCylinder(3,10,Base.Vector(5,0,-5),Base.Vector(0,0,1))
fuse = cylinder1.fuse(cylinder2)

Section

Une section, est l'intersection entre une forme solide et une forme plane.
Elle retournera une courbe d'intersection et sera composée de bords (edges, arêtes).

cylinder1 = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0))
cylinder2 = Part.makeCylinder(3,10,Base.Vector(5,0,-5),Base.Vector(0,0,1))
section = cylinder1.section(cylinder2)
section.Wires
> []
section.Edges
> [<Edge object at 0D87CFE8>, <Edge object at 019564F8>, <Edge object at 0D998458>, 
 <Edge  object at 0D86DE18>, <Edge object at 0D9B8E80>, <Edge object at 012A3640>, 
 <Edge object at 0D8F4BB0>]

Extrusion

L'extrusion est une action de "pousser" une forme plane dans une certaine direction et résultant en un corps solide.
Par exemple, pousser sur un cercle pour le transformer en tube:

circle = Part.makeCircle(10)
tube = circle.extrude(Base.Vector(0,0,2))

Si votre cercle est vide, vous obtiendrez un tube vide.
Mais si votre cercle est un disque avec une face pleine, vous obtiendrez un cylindre solide:

wire = Part.Wire(circle)
disc = Part.Face(wire)
cylinder = disc.extrude(Base.Vector(0,0,2))

Exploration de la forme (shape)

Vous pouvez facilement explorer la structure de ses données topologique:

import Part
b = Part.makeBox(100,100,100)
b.Wires
w = b.Wires[0]
w
w.Wires
w.Vertexes
Part.show(w)
w.Edges
e = w.Edges[0]
e.Vertexes
v = e.Vertexes[0]
v.Point

En tapant ce code dans l'interpréteur Python, vous aurez une bonne compréhension de la structure de Part objets.
Ici, notre commande makebox() créé une forme solide. Ce solide, comme tous les solides Part, contiennent des faces. Une face est constituée de lignes, qui sont un ensemble de bords, arêtes qui délimitent la face. Chaque face a au moins un contour fermé (il peut en avoir plus si la face comporte un ou plusieurs trou). Dans une ligne, nous pouvons voir chaque côté séparément, et nous pouvons voir les sommets (Vertex) de chaque bord ou arête. Lignes et arêtes n'ont que deux sommets, évidemment.

Analyse des arêtes (Edge)

Dans le cas d'un bord (ou arête), qui est une courbe arbitraire, il est fort probable que vous voulez faire une discrétisation. Dans FreeCAD, les bords sont paramétrés par leurs longueurs.
Cela signifie, que vous pouvez suivre une arête/courbe par sa longueur:

import Part
box = Part.makeBox(100,100,100)
anEdge = box.Edges[0]
print anEdge.Length

Maintenant, vous pouvez accéder à un grand nombre de propriétés de l'arête en utilisant sa longueur comme une position.
C'est à dire que, si l'arête(ou bord) a une longueur de 100 mm la position de départ est 0 et sa position extrème est 100.

anEdge.tangentAt(0.0)      # tangent direction at the beginning
anEdge.valueAt(0.0)        # Point at the beginning
anEdge.valueAt(100.0)      # Point at the end of the edge
anEdge.derivative1At(50.0) # first derivative of the curve in the middle
anEdge.derivative2At(50.0) # second derivative of the curve in the middle
anEdge.derivative3At(50.0) # third derivative of the curve in the middle
anEdge.centerOfCurvatureAt(50) # center of the curvature for that position
anEdge.curvatureAt(50.0)   # the curvature
anEdge.normalAt(50)        # normal vector at that position (if defined)

Utilisation de la sélection

Ici, nous allons voir comment nous pouvons utiliser la fonction de sélection, quand l'utilisateur a fait une sélection dans la visionneuse.
Tout d'abord, nous créons une boîte (box) et nous l'affichons dans la fen^etre de vue.

import Part
Part.show(Part.makeBox(100,100,100))
Gui.SendMsgToActiveView("ViewFit")

Sélectionnez maintenant des faces ou arêtes.
Avec ce script, vous pouvez parcourir tous les objets sélectionnés et visionner leurs sous-éléments:

for o in Gui.Selection.getSelectionEx():
	print o.ObjectName
	for s in o.SubElementNames:
		print "name: ",s
	for s in o.SubObjects:
		print "object: ",s

Sélectionnez quelques bords et ce script va calculer la longueur:

length = 0.0
for o in Gui.Selection.getSelectionEx():
	for s in o.SubObjects:
		length += s.Length
print "Length of the selected edges:" ,length

Exemple Complet: "The OCC bottle"

L'exemple OpenCasCade Technology Tutorial vous montre comment faire une bouteille.

C’est un bon exercice pour FreeCAD. Si vous suivez notre exemple ci-dessous et la page OCC simultanément, vous verre comment les structures OCC sont implémentées dans FreeCAD. Le script complet ci-dessous est également inclus dans l’installation de FreeCAD (dans le dossier Mod / Part) et peut être appelé à partir de l'interpréteur Python en tapant:

import Part
import MakeBottle
bottle = MakeBottle.makeBottle()
Part.show(bottle)

Le script complet

Ici, le script complet de MakeBottle.py (extension .py):

import Part, FreeCAD, math
from FreeCAD import Base

def makeBottle(myWidth=50.0, myHeight=70.0, myThickness=30.0):
   aPnt1=Base.Vector(-myWidth/2.,0,0)
   aPnt2=Base.Vector(-myWidth/2.,-myThickness/4.,0)
   aPnt3=Base.Vector(0,-myThickness/2.,0)
   aPnt4=Base.Vector(myWidth/2.,-myThickness/4.,0)
   aPnt5=Base.Vector(myWidth/2.,0,0)
   
   aArcOfCircle = Part.Arc(aPnt2,aPnt3,aPnt4)
   aSegment1=Part.LineSegment(aPnt1,aPnt2)
   aSegment2=Part.LineSegment(aPnt4,aPnt5)
   aEdge1=aSegment1.toShape()
   aEdge2=aArcOfCircle.toShape()
   aEdge3=aSegment2.toShape()
   aWire=Part.Wire([aEdge1,aEdge2,aEdge3])
   
   aTrsf=Base.Matrix()
   aTrsf.rotateZ(math.pi) # rotate around the z-axis
   
   aMirroredWire=aWire.transformGeometry(aTrsf)
   myWireProfile=Part.Wire([aWire,aMirroredWire])
   myFaceProfile=Part.Face(myWireProfile)
   aPrismVec=Base.Vector(0,0,myHeight)
   myBody=myFaceProfile.extrude(aPrismVec)
   myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges)
   neckLocation=Base.Vector(0,0,myHeight)
   neckNormal=Base.Vector(0,0,1)
   myNeckRadius = myThickness / 4.
   myNeckHeight = myHeight / 10
   myNeck = Part.makeCylinder(myNeckRadius,myNeckHeight,neckLocation,neckNormal)	
   myBody = myBody.fuse(myNeck)
   
   faceToRemove = 0
   zMax = -1.0
   
   for xp in myBody.Faces:
       try:
           surf = xp.Surface
           if type(surf) == Part.Plane:
               z = surf.Position.z
               if z > zMax:
                   zMax = z
                   faceToRemove = xp
       except:
           continue
   
   myBody = myBody.makeFillet(myThickness/12.0,myBody.Edges)
   
   return myBody

el = makeBottle()
Part.show(el)

Détail et déroulement MakeBottle.py

import Part, FreeCAD, math
from FreeCAD import Base

Nous aurons besoin bien sûr du module Part mais aussi du module FreeCAD.Basequi contient les structures de base de FreeCAD comme les vectors et matrixes.

def makeBottle(myWidth=50.0, myHeight=70.0, myThickness=30.0):
   aPnt1=Base.Vector(-myWidth/2.,0,0)
   aPnt2=Base.Vector(-myWidth/2.,-myThickness/4.,0)
   aPnt3=Base.Vector(0,-myThickness/2.,0)
   aPnt4=Base.Vector(myWidth/2.,-myThickness/4.,0)
   aPnt5=Base.Vector(myWidth/2.,0,0)

Ici, nous définissons notre fonction MakeBottle.
Cette fonction peut être appelée sans argument, comme nous l'avons fait ci-dessus, les valeurs par défaut, de largeur, hauteur et épaisseur seront utilisés.
Ensuite, nous définissons une paire de points qui seront utilisés pour la construction de notre profil de base.

aArcOfCircle = Part.Arc(aPnt2,aPnt3,aPnt4)
   aSegment1=Part.LineSegment(aPnt1,aPnt2)
   aSegment2=Part.LineSegment(aPnt4,aPnt5)

C'est ici que nous définissons les formes géométriques: un arc composé de 3 points et deux segments de ligne de 2 points chacun.

aEdge1=aSegment1.toShape()
   aEdge2=aArcOfCircle.toShape()
   aEdge3=aSegment2.toShape()
   aWire=Part.Wire([aEdge1,aEdge2,aEdge3])

Vous vous souvenez de la différence entre la géométrie et les formes? Nous allons construire les formes de notre forme géométrique. Trois bords (bords ou arêtes peuvent être des segments de droites ou des courbes) puis nous raccordons tous les sommets.

aTrsf=Base.Matrix()
   aTrsf.rotateZ(math.pi) # rotate around the z-axis
   aMirroredWire=aWire.transformGeometry(aTrsf)
   myWireProfile=Part.Wire([aWire,aMirroredWire])

Jusqu'à présent, nous n'avons construit qu'un demi profil. Au lieu de construire le profil entier de la même manière, nous pouvons simplement reproduire ce que nous avons fait et coller les deux moitiés ensemble. Nous créons d'abord une matrice. Une matrice est un moyen très courant d'appliquer des transformations à des objets du monde 3D car elle peut contenir dans une structure toutes les transformations de base que peuvent subir les objets 3D (déplacement, rotation et mise à l'échelle). Après avoir créé la matrice, nous en faisons une symétrie puis nous créons une copie de notre fil avec cette matrice de transformation qui lui est appliquée. Nous avons maintenant deux fils et nous pouvons en faire un troisième, les fils étant en réalité des listes de bords.

myFaceProfile=Part.Face(myWireProfile)
   aPrismVec=Base.Vector(0,0,myHeight)
   myBody=myFaceProfile.extrude(aPrismVec)
   myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges)

Maintenant, nous avons un contour fermé, il peut être transformé en une face. Une fois que nous avons une face, nous pouvons l'extruder.
Une fois fait, nous avons un solide. Puis, nous appliquons un filet à notre objet car nous voulons lui donner un aspect "design", n'est-ce pas?

neckLocation=Base.Vector(0,0,myHeight)
   neckNormal=Base.Vector(0,0,1)
   myNeckRadius = myThickness / 4.
   myNeckHeight = myHeight / 10
   myNeck = Part.makeCylinder(myNeckRadius,myNeckHeight,neckLocation,neckNormal)

À ce stade, le corps de notre bouteille est fabriqué mais nous devons encore créer un goulot. On fait un nouveau solide avec un cylindre.

myBody = myBody.fuse(myNeck)

L'opération de fusion, qui dans d'autres applications est parfois appelé union, est très puissante.
Cette opération prendra soin de coller ce qui doit être collé et enlever ce qui doit être enlevé.

return myBody

Puis, nous revenons à notre bouteille (Part solid), qui est le résultat de notre fonction.

el = makeBottle()
Part.show(el)

Enfin, nous appelons la fonction pour créer la pièce puis la rendons visible.

Cube percé

Ici un exemple complet de construction d'un cube percé.

La construction se fait face par face et quand le cube est terminé, il est évidé d'un cylindre traversant.

import Draft, Part, FreeCAD, math, PartGui, FreeCADGui, PyQt4
from math import sqrt, pi, sin, cos, asin
from FreeCAD import Base

size = 10
poly = Part.makePolygon( [ (0,0,0), (size, 0, 0), (size, 0, size), (0, 0, size), (0, 0, 0)])

face1 = Part.Face(poly)
face2 = Part.Face(poly)
face3 = Part.Face(poly)
face4 = Part.Face(poly)
face5 = Part.Face(poly)
face6 = Part.Face(poly)
     
myMat = FreeCAD.Matrix()
myMat.rotateZ(math.pi/2)
face2.transformShape(myMat)
face2.translate(FreeCAD.Vector(size, 0, 0))

myMat.rotateZ(math.pi/2)
face3.transformShape(myMat)
face3.translate(FreeCAD.Vector(size, size, 0))

myMat.rotateZ(math.pi/2)
face4.transformShape(myMat)
face4.translate(FreeCAD.Vector(0, size, 0))

myMat = FreeCAD.Matrix()
myMat.rotateX(-math.pi/2)
face5.transformShape(myMat)

face6.transformShape(myMat)               
face6.translate(FreeCAD.Vector(0,0,size))

myShell = Part.makeShell([face1,face2,face3,face4,face5,face6])   

mySolid = Part.makeSolid(myShell)
mySolidRev = mySolid.copy()
mySolidRev.reverse()

myCyl = Part.makeCylinder(2,20)
myCyl.translate(FreeCAD.Vector(size/2, size/2, 0))

cut_part = mySolidRev.cut(myCyl)

Part.show(cut_part)

Chargement et sauvegarde

Il ya plusieurs façons de sauver votre travail dans le Part Module . Vous pouvez bien sûr sauvegarder votre document au format FreeCAD, mais vous pouvez également enregistrer les objets directement dans un format courant de CAO, tels que BREP, IGS, STEP et STL.

L'enregistrement d'une forme (un projet) dans un fichier est facile, il y a les fonctions exportBrep(), exportIges(), exportStl() et exportStep() qui sont des méthodes disponibles pour toutes les formes d'objets.
Donc, en faisant:

import Part
s = Part.makeBox(0,0,0,10,10,10)
s.exportStep("test.stp")

Ceci sauve votre box (cube) dans le format .STP. Pour charger un fichier BREP, IGES ou STEP:

import Part
s = Part.Shape()
s.read("test.stp")

Pour convertir un fichier .stp en .igs:

import Part
 s = Part.Shape()
 s.read("file.stp")       # incoming file igs, stp, stl, brep
 s.exportIges("file.igs") # outbound file igs

Notez que l'importation ou l'ouverture de fichiers BREP, IGES ou STEP peut également être effectuée directement à partir du Menu Fichier → Ouvrir, Menu Fichier → Importer ou l'icone "Ouvrir un document ou importer des fichiers" et pour l'exportation d'un fichier par Menu Fichier → Exporter


Conversion d'objets Pièces en Maillages

La conversion des objets de haut niveau tels que les objets (formes) en objets simples comme les maillages (Mesh) est une opération facile, où, toutes les faces d'un Objet Part deviennent une composition de triangles (exemple sur le site de coin3d un des moteurs de FreeCAD).
Le résultat de cette triangulation (tessellation) est ensuite utilisé pour construire un maillage (Mesh):

#let's assume our document contains one part object
import Mesh
faces = []
shape = FreeCAD.ActiveDocument.ActiveObject.Shape
triangles = shape.tessellate(1) # the number represents the precision of the tessellation)
for tri in triangles[1]:
    face = []
    for i in range(3):
        vindex = tri[i]
        face.append(triangles[0][vindex])
    faces.append(face)
m = Mesh.Mesh(faces)
Mesh.show(m)

Parfois, la triangulation de certaines faces offertes par OpenCascade sont assez laid. Si une face a un forme rectangulaire et ne contient pas de trous ou n'est pas limité par des courbes, vous pouvez également créer un maillage sur cette forme:

import Mesh
def makeMeshFromFace(u,v,face):
	(a,b,c,d)=face.ParameterRange
	pts=[]
	for j in range(v):
		for i in range(u):
			s=1.0/(u-1)*(i*b+(u-1-i)*a)
			t=1.0/(v-1)*(j*d+(v-1-j)*c)
			pts.append(face.valueAt(s,t))

	mesh=Mesh.Mesh()
	for j in range(v-1):
		for i in range(u-1):
			mesh.addFacet(pts[u*j+i],pts[u*j+i+1],pts[u*(j+1)+i])
			mesh.addFacet(pts[u*(j+1)+i],pts[u*j+i+1],pts[u*(j+1)+i+1])

	return mesh

Conversion de Mailles en Part objects

La conversion des mailles en Part objets est une opération extrêmement importante en CAO, car, très souvent vous recevrez des données 3D au format Mesh (maillage) à partir d'autres utilisateurs ou émis par d'autres applications de CAO. Les Mailles sont très pratiques pour représenter les formes géométriques libres et de grandes scènes visuelles, car il est très léger, mais pour la CAO nous préférons généralement des objets de niveau supérieur qui portent beaucoup plus d'informations comme, l'idée de solides, ou faces sont faites de courbes au lieu de triangles.

La conversion des mailles en un de ces objets de niveau supérieur (gérée par le Part Module dans FreeCAD) n'est pas une opération facile. Les Mailles peuvent êtres faites de milliers de triangles (par exemple lorsqu'ils sont générés par un scanner 3D), et des solides faits du même nombre de faces serait extrêmement lourd à manipuler. Donc, vous voudrez généralement voir l'objet optimisé lors de la conversion.

FreeCAD propose actuellement deux méthodes pour convertir des Parts objets en mailles. La première méthode est simple, la conversion directe, sans aucune optimisation:

import Mesh,Part
mesh = Mesh.createTorus()
shape = Part.Shape()
shape.makeShapeFromMesh(mesh.Topology,0.05) # the second arg is the tolerance for sewing
solid = Part.makeSolid(shape)
Part.show(solid)

La seconde méthode, offre la possibilité d'examiner les aspects de mailles coplanaires, lorsque l'angle entre eux est sous une certaine valeur. Cela permet de construire des formes beaucoup plus simples:

# let's assume our document contains one Mesh object
import Mesh,Part,MeshPart
faces = []
mesh = App.ActiveDocument.ActiveObject.Mesh
segments = mesh.getPlanes(0.00001) # use rather strict tolerance here
 
for i in segments:
  if len(i) > 0:
     # a segment can have inner holes
     wires = MeshPart.wireFromSegment(mesh, i)
     # we assume that the exterior boundary is that one with the biggest bounding box
     if len(wires) > 0:
        ext=None
        max_length=0
        for i in wires:
           if i.BoundBox.DiagonalLength > max_length:
              max_length = i.BoundBox.DiagonalLength
              ext = i

        wires.remove(ext)
        # all interior wires mark a hole and must reverse their orientation, otherwise Part.Face fails
        for i in wires:
           i.reverse()

        # make sure that the exterior wires comes as first in the list
        wires.insert(0, ext)
        faces.append(Part.Face(wires))

shell=Part.Compound(faces)
Part.show(shell)
#solid = Part.Solid(Part.Shell(faces))
#Part.show(solid)
Arrow-left.svg Page précédente: Topological data scripting
Page suivante: Scenegraph Arrow-right.svg
Arrow-left.svg Page précédente: Mesh to Part
Page suivante: Pivy Arrow-right.svg

Les formes géométriques qui apparaissent dans les vues 3D de FreeCAD sont des rendus obtenus par la bibliothèque Coin3D (Coin3D est une application de OpenInventor standard).

Le logiciel openCascade fournit les même fonctionnalités que coin3D, mais, dans les débuts de FreeCAD, il a été décidé de ne pas utiliser le moteur d'OpenCascade et de se tourner plutôt vers le logiciel coin3D plus performant. Une bonne façon de se renseigner sur cette bibliothèque est de lire le livre Open Inventor Mentor.

Actuellement OpenInventor est un langage de description de scènes en 3 dimensions. La scène décrite dans OpenInventor est restituée en OpenGL sur votre moniteur.
Coin3D prend en charge toutes ces procédures, de telle sorte que le programmeur n'a pas besoin de traiter les appels complexes d'OpenGL, il lui suffit simplement de fournir le code OpenInventor adéquat.

Le gros avantage d'OpenInventor est, qu'il est une norme fort bien connue et très bien documentée.
Le gros travail que FreeCAD fait pour vous, consiste essentiellement à traduire les informations sur les formes géométriques OpenCascade en langage OpenInventor.

OpenInventor décrit une scène 3D sous la forme d'une scène graphique , comme le montre l'exemple ci dessous:

Scenegraph.gif image from Inventor mentor

OpenInventor scenegraph, décrit tout ce qui fait partie d'une scène 3D, comme les formes géométriques, les couleurs, les matériaux, les lumières etc., et structure toutes les données d'une manière claire et précise.
Cette structure peut être groupée en sous-structures vous permettant d'organiser le contenu de votre scène de la manière qui vous conviens le mieux.
Voici un exemple d'un fichier OpenInventor:

#Inventor V2.0 ascii
 
Separator { 
    RotationXYZ {	
       axis Z
       angle 0
    }
    Transform {
       translation 0 0 0.5
    }
    Separator {	
       Material {
          diffuseColor 0.05 0.05 0.05
       }
       Transform {
          rotation 1 0 0 1.5708
          scaleFactor 0.2 0.5 0.2
       }
       Cylinder {
       }
    }
}

Comme vous pouvez le voir, la structure est très simple. Vous utilisez des séparateurs (Separator) pour organiser vos blocs de données, un peu comme vous le feriez pour organiser vos fichiers dans des dossiers.
Chaque instruction influe celle qui suit, par exemple, les deux premiers articles à la racine de nos Separator sont une rotation (RotationXYZ {..}) et une transformation (Transform {..}), ils auront une incidence directe sur tous les éléments suivants (comme, si vous changez l'attribut d'un dossier, tous les sous dossiers seront affectés).
Dans un séparateur, nous définirons la matière, dans un autre, la transformation. Notre cylindre sera donc affecté par les deux transformations, celle qui lui a été appliqué directement et celle qui a été appliquée à son séparateur parent (Separator{..Separator{..}} à la manière des dossiers dans un disque dur).

Nous avons également beaucoup d'autres d'éléments pour organiser notre scène (projet), tels que des groupes, des commutateurs ou des annotations.
Nous pouvons donner à nos objets des définitions très complexes, de la couleur, des textures des modes d'ombrage et de transparence. Nous pouvons aussi définir de la lumière, des caméras et, même du mouvement.
Il est aussi possible d'intégrer des portions de scripts dans des fichiers OpenInventor et de définir des comportements plus complexes.

Si vous voulez en apprendre plus sur OpenInventor, allez tout de suite sur The Inventor Mentor: Programming Object-Oriented 3D Graphics with Open Inventor.

Normalement, dans FreeCAD, nous n'avons pas besoin d'interagir directement avec scenegraph OpenInventor.
Dans un document FreeCAD, chaque objet maillage, forme de la pièce ou toute autre chose, est automatiquement converti en code OpenInventor et est inséré dans la scène graphique que vous voyez dans la vue 3D.

Toutes modifications dans le document, ajout ou suppression d'objets, sont en permanence mises à jour dans la scène graphique. En fait, chaque objet (dans l'espace de l'Application), dispose d'un constructeur de la vue (un objet correspondant dans l'espace Gui), responsable de la création du code OpenInventor.

Mais il y a de nombreux avantages à pouvoir accéder directement à la scène graphique. Par exemple, nous pouvons modifier temporairement l'apparence d'un objet, ou nous pouvons ajouter des objets à la scène qui n'ont aucune existence réelle dans le document FreeCAD, tels que la construction de la géométrie, les aides, conseils graphiques ou des outils qui permettent des manipulations ou des informations à l'écran.

FreeCAD dispose de plusieurs outils pour voir ou modifier le code OpenInventor.

Par exemple, le code Python suivant, montre la représentation OpenInventor d'un objet sélectionné:

obj = FreeCAD.ActiveDocument.ActiveObject
viewprovider = obj.ViewObject
print viewprovider.toString()

Mais nous avons aussi un module Python qui permet un accès complet à toute chose gérée par Coin3D, comme, notre scène graphique FreeCAD.
Alors, lisez la suite sur la page de pivy.

Arrow-left.svg Page précédente: Mesh to Part
Page suivante: Pivy Arrow-right.svg
Arrow-left.svg Page précédente: Graph de scène
Page suivante: PySide Arrow-right.svg

Pivy est une bibliothèque de codes qui sert de passerelle entre Python et Coin3d, la bibliothèque 3D de rendu graphique utilisé dans FreeCAD. Lors de l'importation dans l'interpréteur Python, Pivy permet de dialoguer immédiatement avec les procédures de Coin3d, tels que les vue3D, ou même d'en créer de nouvelles.
Pivy est inclus d'origine dans l'installation FreeCAD.

La bibliothèque d'outils est divisée en plusieurs parties,

  • coin: pour manipuler formes graphiques (projet) et gérer le système graphique (GUI), tels que plusieurs fenêtres ou, dans notre cas,
  • qt  : pour les interfaces.

Ces modules sont aussi accessibles à pivy, s'ils sont présents sur le système bien sûr.
Le module coin est toujours présent, et de toute façon c'est lui que nous allons utiliser, nous n'aurons pas besoin de nous occuper de l'affichage 3D dans une interface, FreeCAD s'en occupe lui-même.
Tout ce que nous aurons à faire, c'est:

from pivy import coin

Accéder et modifier une scène graphique

Nous avons vu dans la page Scenegraph comment coin organise une scène. Tout ce qui est affiché en 3D dans FreeCAD est construit et géré par coin.
Nous avons une racine, et tous les objets sur l'écran sont ses enfants, reliés par des nodes (noeuds). Les enfants aussi peuvent avoir une descendance.

FreeCAD a un moyen facile d'accéder a la racine d'une scène 3D:

sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
print sg

La racine de la scène 3D sera:

<pivy.coin.SoSelection; proxy of <Swig Object of type 'SoSelection *' at 0x360cb60> >

Vous pouvez inspecter immédiatement les enfants (branches) de la scène 3D:

for node in sg.getChildren():
    print node

Certains de ces nodes, comme SoSeparators ou SoGroups, peuvent avoir des enfants eux-mêmes. La liste complète des coin objets disponibles peut être trouvée dans la documentation official coin documentation.

Maintenant essayons d'ajouter quelque chose à notre scène (projet).
Nous allons ajouter un beau cube rouge:

col = coin.SoBaseColor()
col.rgb=(1,0,0)
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode.addChild(col)
myCustomNode.addChild(cub)
sg.addChild(myCustomNode)

et voici notre (beau) cube rouge.
Maintenant, nous allons essayer ceci:

col.rgb=(1,1,0)

Vu ? Tout est encore accessible et modifiable à la volée.
Pas besoin de recalculer ou redessiner quoi que ce soit, coin s'occupe de tout. Vous pouvez ajouter ce que vous voulez à votre scène (projet), propriétés de changements, cacher des objets, montrer des objets temporairement, faire n'importe quoi.
Bien sûr, cela ne concerne que l'affichage de la vue 3D. L'affichage du document ouvert est recalculé par FreeCAD, et recalcule un objet quand il a besoin de l'être.
Donc, si vous changez l'aspect d'un objet existant dans FreeCAD, ces modifications seront perdues si l'objet est recalculé, ou lorsque vous rouvrez le fichier.

Un truc, pour travailler avec scenegraphs dans vos scripts, vous pouvez, lorsque c'est nécessaire accéder à certaines propriétés des nodes que vous avez ajoutés.
Par exemple, si nous voulions faire évoluer notre cube, nous aurions ajouté un node SoTranslation à notre node personnalisé et,
il aurait ressemblé à ceci:

col = coin.SoBaseColor()
col.rgb=(1,0,0)
trans = coin.SoTranslation()
trans.translation.setValue([0,0,0])
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode.addChild(col)
myCustomNode.addChild(trans)
myCustomNode.addChild(cub)
sg.addChild(myCustomNode)

Souvenez-vous que dans une scène graphique OpenInventor, l'ordre est très important. Un noeud affecte ce qui suit, de sorte que, si vous dites: couleur rouge, cube, couleur jaune, sphère ! vous obtiendrez un cube rouge et une sphère jaune.
Si nous traduisons maintenant notre noeud personnalisé, il vient après le cube, et ne l'affecte pas.
Si nous l'avions inséré lors de sa création, comme l'exemple ci-dessus,
nous pourrions faire maintenant:

trans.translation.setValue([2,0,0])

Et notre cube sauterait de 2 unités vers la droite.
Enfin, pour supprimer quelque chose, nous ferons:

sg.removeChild(myCustomNode)

Utilisation des mécanismes de rappel (callback)

Un mécanisme de rappel est un système qui permet à la bibliothèque que vous utilisez, comme notre bibliothèque coin de faire un rappel comme, rappeler une certaine fonction pour l'Objet Python en cours d'exécution.
Cela est extrêmement utile, car, de cette manière coin peut vous avertir si un événement particulier survient dans la scène.
Coin peut voir des choses très différentes, comme, la position de la souris, les clics sur un bouton de la souris, les touches du clavier qui sont pressées, et bien d'autres choses.

FreeCAD dispose d'un moyen facile pour utiliser ces rappels:

class ButtonTest:
  def __init__(self):
    self.view = FreeCADGui.ActiveDocument.ActiveView
    self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getMouseClick) 
  def getMouseClick(self,event_cb):
    event = event_cb.getEvent()
    if event.getState() == SoMouseButtonEvent.DOWN:
      print "Alert!!! A mouse button has been improperly clicked!!!"
      self.view.removeEventCallbackSWIG(SoMouseButtonEvent.getClassTypeId(),self.callback) 
 
ButtonTest()

Le rappel doit être initiée à partir d'un objet, et, cet objet doit toujours être actif au moment du rappel.
Voir aussi une liste complète des événements possibles et leurs paramètres (en), ou dans la documentation officielle de coin.

Documentation

Malheureusement, Pivy n’a pas sa propre documentation. Cependant, puisqu'il s'agit d'un wrapper de la bibliothèque Coin3d, vous pouvez lire la référence C++ pour plus d'informations. Dans ce cas, vous devez traduire le style de nommage de la classe C++ comme vous la liriez en Python.

En C++:

SoFile::getClassTypeId()

En Pivy

SoFile.getClassId()
Arrow-left.svg Page précédente: Graph de scène
Page suivante: PySide Arrow-right.svg
Arrow-left.svg Page précédente: Pivy
Page suivante: Objets FeaturePython Arrow-right.svg

PySide

PySide est un outil Python mutiplateforme obligatoire pour créer des GUI en Qt. FreeCAD utilise PySide pour tous les objectifs de la GUI (interface utilisateur graphique) dans Python. PySide est une alternative au paquet PyQt qui était auparavant utilisé par FreeCAD pour son interface graphique. PySide à une licence plus permissive. Voir Differences Between PySide and PyQt pour plus d'information sur ces différences.

Les utilisateurs de FreeCAD atteignent souvent les limites tout en utilisant l'interface intégrée. Mais pour les utilisateurs qui souhaitent personnaliser leurs opérations alors l'interface Python existe et est documentée dans le Didacticiel de scripts Python. L'interface Python pour FreeCAD donne une grande flexibilité et augmente la puissance de FreeCAD. Pour cette interaction, utilisateur Python et Freecad , nous utilisons PySide qui est est documenté sur cette page.

Python offre la mention "print" qui donne le code:

print 'Hello World'

Avec l'instruction Python print vous avez seulement un contrôle limité de l'apparence et du comportement. PySide fournit le contrôle manquant et gère également les environnements (tels que l'environnement de fichier macro FreeCAD) où les installations intégrées de Python ne sont pas suffisantes

Les capacités de PySide varient de:

PySideScreenSnapshot1.jpg

à

PySideScreenSnapshot2.jpg

Familiarisez-vous avec des exemples concrets de PySide

Elles divisent l'objet en 3 parties, différenciées selon le niveau de connaissance de PySide, Python et l FreeCAD. La première page est un aperçu et un documents de référence donnant une description de PySide et comment il est mis en place tandis que les deuxième et troisième pages sont pour la plupart des exemples de code à différents niveaux.

L'intention est que les pages associées fourniront du code Python simple pour exécuter PySide de sorte que l'utilisateur travaillant sur un problème peut facilement copier le code, le collez-le dansson propre travail, l'adapter si nécessaire et retourner à leur résolution de problèmes avec FreeCAD. J'espère qu'ils n' auront pas à aller fouiller à travers l'Internet à la recherche de réponses aux questions PySide. Dans le même temps cette page n' est pas destinée à remplacer les différents tutoriels PySide complets et les sites de référence disponibles sur le web.

Arrow-left.svg Page précédente: Pivy
Page suivante: Objets FeaturePython Arrow-right.svg
Arrow-left.svg Page précédente: PySide
Page suivante: Embedding FreeCAD Arrow-right.svg

Outre les types d'objets standards tels que les annotations, les mailles et les objets Parts, FreeCAD offre également la possibilité incroyable d'écrire des scripts d'objets 100% Python. Ces "objets" se comporteront exactement comme n'importe quels autres objets dans FreeCAD, et sont, sauvegardés et restaurés automatiquement dans le répertoire de chargement/sauvegarde.

Une particularité doit être comprise, ces objets sont enregistrés dans des fichiers FreeCAD FcStd' avec le module Python json . Ce module transforme un objet (code) Python en une chaîne de caractères (texte), lui permettant d'être ajouté au fichier sauvegardé. Une fois chargé, le module json utilise cette chaîne pour recréer l'objet d'origine, à condition qu'il ait accès au code source qui l'a créé. Cela signifie que si vous enregistrez un tel objet personnalisé et l'ouvrez sur une machine où le code source Python qui a créé l'objet n'est pas présent, l'objet ne sera pas recréé.
Si vous distribuez ces scripts à d'autres, vous devrez aussi distribuer l'ensemble du script Python qui l'a créé.

Les fonctionnalités de Python suivent les mêmes règles que toutes les fonctionnalités de FreeCAD: ils sont séparés en plusieurs parties celle App (application) et GUI parts (interface graphique).
La partie Object App (application), définit la forme géométrique de notre objet, tandis que la partie graphique (GUI), définit la façon dont l'objet sera affiché à l'écran.
L'outil View Provider Object (créateur de vue), comme toutes les fonctions FreeCAD, n'est disponible que lorsque vous exécutez FreeCAD dans son interface (GUI).

Il ya plusieurs manières et méthodes disponibles pour créer votre projet. Les méthodes utilisées doivent êtres une des méthodes prédéfinies que vous fourni FreeCAD, et apparaîtra dans la fenêtre Propriété, afin qu'ils puissent être modifiés par l'utilisateur (onglet Données).
De cette manière, les objets sont FeaturePython (ont toutes les propriétés de Python) et sont totalements paramétriques.
Vous pouvez paramétrer les propriétés et l'affichage ViewObject de l'objet séparément.

Astuce: dans les versions antérieures, nous avons utilisé le module Python cPickle. Cependant, ce module exécute du code arbitrairement et provoque ainsi des problèmes de sécurité. Alors, nous avons opté pour le module Python json.

Exemples de base

L'exemple suivant (portion) peut être trouvé sur la page, src/Mod/TemplatePyMod/FeaturePython.py qui inclus beaucoup d'autres exemples:

'''Examples for a feature class and its view provider.'''

import FreeCAD, FreeCADGui
from pivy import coin

class Box:
    def __init__(self, obj):
        '''Add some custom properties to our box feature'''
        obj.addProperty("App::PropertyLength","Length","Box","Length of the box").Length=1.0
        obj.addProperty("App::PropertyLength","Width","Box","Width of the box").Width=1.0
        obj.addProperty("App::PropertyLength","Height","Box", "Height of the box").Height=1.0
        obj.Proxy = self
   
    def onChanged(self, fp, prop):
        '''Do something when a property has changed'''
        FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
 
    def execute(self, fp):
        '''Do something when doing a recomputation, this method is mandatory'''
        FreeCAD.Console.PrintMessage("Recompute Python Box feature\n")

class ViewProviderBox:
    def __init__(self, obj):
        '''Set this object to the proxy object of the actual view provider'''
        obj.addProperty("App::PropertyColor","Color","Box","Color of the box").Color=(1.0,0.0,0.0)
        obj.Proxy = self
 
    def attach(self, obj):
        '''Setup the scene sub-graph of the view provider, this method is mandatory'''
        self.shaded = coin.SoGroup()
        self.wireframe = coin.SoGroup()
        self.scale = coin.SoScale()
        self.color = coin.SoBaseColor()
       
        data=coin.SoCube()
        self.shaded.addChild(self.scale)
        self.shaded.addChild(self.color)
        self.shaded.addChild(data)
        obj.addDisplayMode(self.shaded,"Shaded");
        style=coin.SoDrawStyle()
        style.style = coin.SoDrawStyle.LINES
        self.wireframe.addChild(style)
        self.wireframe.addChild(self.scale)
        self.wireframe.addChild(self.color)
        self.wireframe.addChild(data)
        obj.addDisplayMode(self.wireframe,"Wireframe");
        self.onChanged(obj,"Color")
 
    def updateData(self, fp, prop):
        '''If a property of the handled feature has changed we have the chance to handle this here'''
        # fp is the handled feature, prop is the name of the property that has changed
        l = fp.getPropertyByName("Length")
        w = fp.getPropertyByName("Width")
        h = fp.getPropertyByName("Height")
        self.scale.scaleFactor.setValue(float(l),float(w),float(h))
        pass
 
    def getDisplayModes(self,obj):
        '''Return a list of display modes.'''
        modes=[]
        modes.append("Shaded")
        modes.append("Wireframe")
        return modes
 
    def getDefaultDisplayMode(self):
        '''Return the name of the default display mode. It must be defined in getDisplayModes.'''
        return "Shaded"
 
    def setDisplayMode(self,mode):
        '''Map the display mode defined in attach with those defined in getDisplayModes.\
                Since they have the same names nothing needs to be done. This method is optional'''
        return mode
 
    def onChanged(self, vp, prop):
        '''Here we can do something when a single property got changed'''
        FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
        if prop == "Color":
            c = vp.getPropertyByName("Color")
            self.color.rgb.setValue(c[0],c[1],c[2])
 
    def getIcon(self):
        '''Return the icon in XPM format which will appear in the tree view. This method is\
                optional and if not defined a default icon is shown.'''
        return """
            /* XPM */
            static const char * ViewProviderBox_xpm[] = {
            "16 16 6 1",
            "   c None",
            ".  c #141010",
            "+  c #615BD2",
            "@  c #C39D55",
            "#  c #000000",
            "$  c #57C355",
            "        ........",
            "   ......++..+..",
            "   .@@@@.++..++.",
            "   .@@@@.++..++.",
            "   .@@  .++++++.",
            "  ..@@  .++..++.",
            "###@@@@ .++..++.",
            "##$.@@$#.++++++.",
            "#$#$.$$$........",
            "#$$#######      ",
            "#$$#$$$$$#      ",
            "#$$#$$$$$#      ",
            "#$$#$$$$$#      ",
            " #$#$$$$$#      ",
            "  ##$$$$$#      ",
            "   #######      "};
            """
 
    def __getstate__(self):
        '''When saving the document this object gets stored using Python's json module.\
                Since we have some un-serializable parts here -- the Coin stuff -- we must define this method\
                to return a tuple of all serializable objects or None.'''
        return None
 
    def __setstate__(self,state):
        '''When restoring the serialized object from document we have the chance to set some internals here.\
                Since no data were serialized nothing needs to be done here.'''
        return None


def makeBox():
    FreeCAD.newDocument()
    a=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Box")
    Box(a)
    ViewProviderBox(a.ViewObject)

makeBox()

Propriétés disponibles

Les propriétés sont les bases des FeaturePython objets. Grâce à elles, l'utilisateur est en mesure d'interagir et de modifier son objet. Après avoir créé un nouveau ObjetPython dans votre document ( obj = FreeCAD.ActiveDocument.addObject ("App :: FeaturePython", "Box") ), ses propriétés sont directement accessibles, vous pouvez obtenir la liste,
en faisant:

obj.supportedProperties()

Et voici, la liste des propriétés disponibles:

App::PropertyBool
App::PropertyBoolList
App::PropertyFloat
App::PropertyFloatList
App::PropertyFloatConstraint
App::PropertyQuantity
App::PropertyQuantityConstraint
App::PropertyAngle
App::PropertyDistance
App::PropertyLength
App::PropertySpeed
App::PropertyAcceleration
App::PropertyForce
App::PropertyPressure
App::PropertyInteger
App::PropertyIntegerConstraint
App::PropertyPercent
App::PropertyEnumeration
App::PropertyIntegerList
App::PropertyIntegerSet
App::PropertyMap
App::PropertyString
App::PropertyUUID
App::PropertyFont
App::PropertyStringList
App::PropertyLink
App::PropertyLinkSub
App::PropertyLinkList
App::PropertyLinkSubList
App::PropertyMatrix
App::PropertyVector
App::PropertyVectorList
App::PropertyPlacement
App::PropertyPlacementLink
App::PropertyPlacementList
App::PropertyColor
App::PropertyColorList
App::PropertyMaterial
App::PropertyPath
App::PropertyFile
App::PropertyFileIncluded
App::PropertyPythonObject
Part::PropertyPartShape
Part::PropertyGeometryList
Part::PropertyShapeHistory
Part::PropertyFilletEdges
Sketcher::PropertyConstraintList

Lors de l'ajout de propriétés à vos objets, prenez soin de ceci:

  • Ne pas utiliser de caractères "<" ou ">" dans les descriptions des propriétés (qui coupent des portions de code dans le fichier xml.Fcstd)
  • Les propriétés sont stockées dans un fichier texte .Fcstd.
  • Toutes les propriétés dont le nom vient après "Shape" sont triés dans l'ordre alphabétique, donc, si vous avez une forme dans vos propriétés, et comme les propriétés sont chargées après la forme, il peut y avoir des comportements inattendus!

Une liste complète des attributs de propriété est disponible dans le fichier d’en-tête PropertyStandard C++. Par exemple, si vous souhaitez autoriser l'utilisateur à saisir uniquement une plage de valeurs limitée (par exemple, à l'aide de PropertyIntegerConstraint), vous affecterez à Python un tuple contenant non seulement la valeur de la propriété, mais également les limites inférieure et supérieure, ainsi que l'incrément, comme ci-dessous :

prop = (value, lower, upper, stepsize)

Property Type

Par défaut, les propriétés peuvent être actualisées. Il est possible de rendre les propriétés en lecture seule, par exemple dans le cas ou l'on veut montrer le résultat d'une méthode. Il est également possible de cacher la propriété. Le type de propriété peut être définie à l'aide

obj.setEditorMode("MyPropertyName", mode)

Mode est un int court qui peut avoir la valeur: 0 -- mode par défaut, lecture et écriture 1 -- lecture seule 2 -- caché

Les EditorModes ne sont pas fixés dans le fichier reload de FreeCAD. Cela pourrait être fait par la fonction __setstate__. Voir http://forum.freecadweb.org/viewtopic.php?f=18&t=13460&start=10#p108072 En utilisant les propriétés de setEditorMode vous ne savez que lire dans PropertyEditor. Les propriétés pourraient encore être modifiées à partir d'une commande Python. Pour faire une lecture seul le réglage doit être transmis directement à la fonction d'ajout de propriété. Voir le topic http://forum.freecadweb.org/viewtopic.php?f=18&t=13460&start=20#p109709 pour voir un exemple.

En utilisant le paramètre direct dans la fonction addProperty, vous avez également plus de possibilités. En particulier, un point intéressant est de marquer une propriété en tant que propriété en sortie. De cette façon, FreeCAD ne marquera pas la fonctionnalité comme étant touchée lors de la modification (inutile donc de recalculer).

Exemple de sortie de property (see also https://forum.freecadweb.org/viewtopic.php?t=24928):

obj.addProperty("App::PropertyString","MyCustomProperty","","",8)

Les types de propriétés pouvant être définis au dernier paramètre de la fonction addProperty sont les suivants:

  0 - Prop_None, pas de type de propriété spécial
  1 - Prop_ReadOnly, la propriété est en lecture seule dans l'éditeur
  2 - Prop_Transient, la propriété ne sera pas sauvegardée dans un fichier
  4 - Prop_Hidden, la propriété n'apparaîtra pas dans l'éditeur
  8 - Prop_Output, modifier la propriété  ne touche pas son conteneur parent
  16 - Prop_NoRecompute, modifier la propriété ne touche pas son conteneur pour le recalcul


Vous pouvez trouver ces différents types de propriétés définis dans source code C++ header for PropertyContainer

Autres exemples plus complexes

Cet exemple utilise le module Atelier Part pour créer un octaèdre, puis crée sa représentation coin avec pivy

En premier, c'est l'objet document lui-même:

import FreeCAD, FreeCADGui, Part
import pivy
from pivy import coin

class Octahedron:
  def __init__(self, obj):
     "Add some custom properties to our box feature"
     obj.addProperty("App::PropertyLength","Length","Octahedron","Length of the octahedron").Length=1.0
     obj.addProperty("App::PropertyLength","Width","Octahedron","Width of the octahedron").Width=1.0
     obj.addProperty("App::PropertyLength","Height","Octahedron", "Height of the octahedron").Height=1.0
     obj.addProperty("Part::PropertyPartShape","Shape","Octahedron", "Shape of the octahedron")
     obj.Proxy = self

  def execute(self, fp):
     # Define six vetices for the shape
     v1 = FreeCAD.Vector(0,0,0)
     v2 = FreeCAD.Vector(fp.Length,0,0)
     v3 = FreeCAD.Vector(0,fp.Width,0)
     v4 = FreeCAD.Vector(fp.Length,fp.Width,0)
     v5 = FreeCAD.Vector(fp.Length/2,fp.Width/2,fp.Height/2)
     v6 = FreeCAD.Vector(fp.Length/2,fp.Width/2,-fp.Height/2)
     
     # Make the wires/faces
     f1 = self.make_face(v1,v2,v5)
     f2 = self.make_face(v2,v4,v5)
     f3 = self.make_face(v4,v3,v5)
     f4 = self.make_face(v3,v1,v5)
     f5 = self.make_face(v2,v1,v6)
     f6 = self.make_face(v4,v2,v6)
     f7 = self.make_face(v3,v4,v6)
     f8 = self.make_face(v1,v3,v6)
     shell=Part.makeShell([f1,f2,f3,f4,f5,f6,f7,f8])
     solid=Part.makeSolid(shell)
     fp.Shape = solid

  # helper mehod to create the faces
  def make_face(self,v1,v2,v3):
     wire = Part.makePolygon([v1,v2,v3,v1])
     face = Part.Face(wire)
     return face

Puis, nous avons view provider object, qui est responsable d'afficher l'objet dans la scène 3D (votre projet à l'écran):

class ViewProviderOctahedron:
  def __init__(self, obj):
     "Set this object to the proxy object of the actual view provider"
     obj.addProperty("App::PropertyColor","Color","Octahedron","Color of the octahedron").Color=(1.0,0.0,0.0)
     obj.Proxy = self

  def attach(self, obj):
     "Setup the scene sub-graph of the view provider, this method is mandatory"
     self.shaded = coin.SoGroup()
     self.wireframe = coin.SoGroup()
     self.scale = coin.SoScale()
     self.color = coin.SoBaseColor()

     self.data=coin.SoCoordinate3()
     self.face=coin.SoIndexedLineSet()

     self.shaded.addChild(self.scale)
     self.shaded.addChild(self.color)
     self.shaded.addChild(self.data)
     self.shaded.addChild(self.face)
     obj.addDisplayMode(self.shaded,"Shaded");
     style=coin.SoDrawStyle()
     style.style = coin.SoDrawStyle.LINES
     self.wireframe.addChild(style)
     self.wireframe.addChild(self.scale)
     self.wireframe.addChild(self.color)
     self.wireframe.addChild(self.data)
     self.wireframe.addChild(self.face)
     obj.addDisplayMode(self.wireframe,"Wireframe");
     self.onChanged(obj,"Color")

  def updateData(self, fp, prop):
     "If a property of the handled feature has changed we have the chance to handle this here"
     # fp is the handled feature, prop is the name of the property that has changed
     if prop == "Shape":
        s = fp.getPropertyByName("Shape")
        self.data.point.setNum(6)
        cnt=0
        for i in s.Vertexes:
           self.data.point.set1Value(cnt,i.X,i.Y,i.Z)
           cnt=cnt+1
        
        self.face.coordIndex.set1Value(0,0)
        self.face.coordIndex.set1Value(1,1)
        self.face.coordIndex.set1Value(2,2)
        self.face.coordIndex.set1Value(3,-1)

        self.face.coordIndex.set1Value(4,1)
        self.face.coordIndex.set1Value(5,3)
        self.face.coordIndex.set1Value(6,2)
        self.face.coordIndex.set1Value(7,-1)

        self.face.coordIndex.set1Value(8,3)
        self.face.coordIndex.set1Value(9,4)
        self.face.coordIndex.set1Value(10,2)
        self.face.coordIndex.set1Value(11,-1)

        self.face.coordIndex.set1Value(12,4)
        self.face.coordIndex.set1Value(13,0)
        self.face.coordIndex.set1Value(14,2)
        self.face.coordIndex.set1Value(15,-1)

        self.face.coordIndex.set1Value(16,1)
        self.face.coordIndex.set1Value(17,0)
        self.face.coordIndex.set1Value(18,5)
        self.face.coordIndex.set1Value(19,-1)

        self.face.coordIndex.set1Value(20,3)
        self.face.coordIndex.set1Value(21,1)
        self.face.coordIndex.set1Value(22,5)
        self.face.coordIndex.set1Value(23,-1)

        self.face.coordIndex.set1Value(24,4)
        self.face.coordIndex.set1Value(25,3)
        self.face.coordIndex.set1Value(26,5)
        self.face.coordIndex.set1Value(27,-1)

        self.face.coordIndex.set1Value(28,0)
        self.face.coordIndex.set1Value(29,4)
        self.face.coordIndex.set1Value(30,5)
        self.face.coordIndex.set1Value(31,-1)

  def getDisplayModes(self,obj):
     "Return a list of display modes."
     modes=[]
     modes.append("Shaded")
     modes.append("Wireframe")
     return modes

  def getDefaultDisplayMode(self):
     "Return the name of the default display mode. It must be defined in getDisplayModes."
     return "Shaded"

  def setDisplayMode(self,mode):
     return mode

  def onChanged(self, vp, prop):
     "Here we can do something when a single property got changed"
     FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
     if prop == "Color":
        c = vp.getPropertyByName("Color")
        self.color.rgb.setValue(c[0],c[1],c[2])

  def getIcon(self):
     return """
        /* XPM */
        static const char * ViewProviderBox_xpm[] = {
        "16 16 6 1",
        "    c None",
        ".   c #141010",
        "+   c #615BD2",
        "@   c #C39D55",
        "#   c #000000",
        "$   c #57C355",
        "        ........",
        "   ......++..+..",
        "   .@@@@.++..++.",
        "   .@@@@.++..++.",
        "   .@@  .++++++.",
        "  ..@@  .++..++.",
        "###@@@@ .++..++.",
        "##$.@@$#.++++++.",
        "#$#$.$$$........",
        "#$$#######      ",
        "#$$#$$$$$#      ",
        "#$$#$$$$$#      ",
        "#$$#$$$$$#      ",
        " #$#$$$$$#      ",
        "  ##$$$$$#      ",
        "   #######      "};
        """

  def __getstate__(self):
     return None

  def __setstate__(self,state):
     return None

Enfin, une fois que notre objet et son viewobject sont définis, nous n'avons qu'a les appeler:

FreeCAD.newDocument()
a=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Octahedron")
Octahedron(a)
ViewProviderOctahedron(a.ViewObject)

Création d'objets sélectionnables

Si vous voulez travailler sur un objet sélectionné, ou du moins une partie de celui-ci, vous cliquez sur l'objet dans la fenêtre, vous devez inclure la forme géométrique à l'intérieur d'un noeud SoFCSelection node.
Si votre objet a une représentation complexe, avec des widgets, des annotations, etc, vous pouvez n'inclure qu'une partie de celui-ci dans un SoFCSelection.
Tout ce qui est SoFCSelection est constamment "scanné" par FreeCAD pour voir s'il est sélectionné/présélectionné, il est donc logique de ne rien surcharger avec des scans inutiles.

Voici un exemple de ce que vous devrez faire pour inclure un self.face:

selectionNode = coin.SoType.fromName("SoFCSelection").createInstance()
selectionNode.documentName.setValue(FreeCAD.ActiveDocument.Name)
selectionNode.objectName.setValue(obj.Object.Name) # here obj is the ViewObject, we need its associated App Object
selectionNode.subElementName.setValue("Face")
selectNode.addChild(self.face)
...
self.shaded.addChild(selectionNode)
self.wireframe.addChild(selectionNode)

Vous créez Simplement un SoFCSelection node (noeud), puis vous lui ajoutez vos noeuds géométriques, alors seulement vous l'ajoutez à votre noeud principal, au lieu d'ajouter vos noeuds géométriques directement.

Travailler avec des formes simples

Si votre objet paramétrique renvoie simplement une forme, vous n'avez pas besoin d'utiliser un objet créateur de vue (view provider object).
La forme sera affichée à l'aide du module standard de représentation des formes de FreeCAD:

import FreeCAD as App
import FreeCADGui
import FreeCAD
import Part
class Line:
    def __init__(self, obj):
        '''"App two point properties" '''
        obj.addProperty("App::PropertyVector","p1","Line","Start point")
        obj.addProperty("App::PropertyVector","p2","Line","End point").p2=FreeCAD.Vector(1,0,0)
        obj.Proxy = self

    def execute(self, fp):
        '''"Print a short message when doing a recomputation, this method is mandatory" '''
        fp.Shape = Part.makeLine(fp.p1,fp.p2)

a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Line")
Line(a)
a.ViewObject.Proxy=0 # just set it to something different from None (this assignment is needed to run an internal notification)
FreeCAD.ActiveDocument.recompute()

Même code en utilisant ViewProviderLine

import FreeCAD as App
import FreeCADGui
import FreeCAD
import Part

class Line:
    def __init__(self, obj):
         '''"App two point properties" '''
         obj.addProperty("App::PropertyVector","p1","Line","Start point")
         obj.addProperty("App::PropertyVector","p2","Line","End point").p2=FreeCAD.Vector(100,0,0)
         obj.Proxy = self
   
    def execute(self, fp):
        '''"Print a short message when doing a recomputation, this method is mandatory" '''
        fp.Shape = Part.makeLine(fp.p1,fp.p2)

class ViewProviderLine:
   def __init__(self, obj):
      ''' Set this object to the proxy object of the actual view provider '''
      obj.Proxy = self

   def getDefaultDisplayMode(self):
      ''' Return the name of the default display mode. It must be defined in getDisplayModes. '''
      return "Flat Lines"

a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Line")
Line(a)
ViewProviderLine(a.ViewObject)
App.ActiveDocument.recompute()

Plus d'informations

Quelques discussions intéressantes sur le forum à propos des objets scriptés:

- Python object attributes lost at load

- New FeaturePython is grey

- Eigenmode frequency always 0?

- how to implement python feature's setEdit properly?

En plus de ces exemples, vous pouvez voir dans le code source de FreeCAD src/Mod/TemplatePyMod/FeaturePython.py pour plus d'exemples.

Arrow-left.svg Page précédente: PySide
Page suivante: Embedding FreeCAD Arrow-right.svg


Arrow-left.svg Page précédente: Script d'objets
Page suivante: Bouts de code Arrow-right.svg

FreeCAD a la capacité incroyable de pouvoir être importé en tant que module Python dans d'autres programmes ou, dans une console Python autonome, avec tous ses modules et ses composants. Il est même possible d'importer l'interface graphique (GUI) de FreeCAD en tant que module python avec toutefois, quelques restrictions. Mais avec quelques restrictions.

Utilisation de FreeCAD sans interface graphique (GUI)

Une première application, directe, facile et utile que vous pouvez faire est d'importer des documents FreeCAD dans votre programme. Dans l'exemple suivant, nous allons importer Part geometry d'un document FreeCAD dans blender. Voici le script complet. J'espère que vous serez impressionné par sa simplicité:

FREECADPATH = '/opt/FreeCAD/lib' # path to your FreeCAD.so or FreeCAD.dll file
import Blender, sys
sys.path.append(FREECADPATH)
 
def import_fcstd(filename):
   try:
       import FreeCAD
   except ValueError:
       Blender.Draw.PupMenu('Error%t

Première chose, s'assurer que Python va trouver notre bibliothèque FreeCAD. Une fois qu'il l'a trouvée, tous les modules FreeCAD comme Part, que nous allons aussi utiliser, seront disponibles automatiquement. Donc, nous utilisons tout simplement la variable sys.path, qui va donner à Python le chemin des modules à rechercher, et nous ajoutons le chemin FreeCAD lib. Cette modification n'est que temporaire, et sera perdue quand nous aurons terminé avec notre interpréteur Python. Une autre façon, est de créer un lien vers votre bibliothèque FreeCAD dans l'un des chemins (Path) de recherche Python. Nous placerons le chemin dans une constante (FREECADPATH), un autre utilisateur du script aura ainsi plus de facilité pour configurer son propre système.

Une fois certain que la bibliothèque a été chargée (the try/except sequence), nous pourrons travailler avec FreeCAD, de la même manière que si nous le ferions à l'intérieur de l’interpréteur Python de FreeCAD. Nous ouvrons le document FreeCAD que nous avons chargé avec la fonction main(), et nous listons ses objets. Puis, comme nous avons choisi de nous occuper que de la forme géométrique, nous vérifions si la propriété Type de chaque objet contient Part, puis nous faison une tesselation.

La tesselation produit une liste de sommets (Vertex) et une liste de faces définis par les indices de sommets. C'est parfait, puisque c'est exactement de cette manière que Blender définit les mailles. Donc, notre tâche est ridiculement simple, nous ajoutons juste les deux listes des sommets et faces comme un maillage de Blender. Une fois fait, nous allons juste redessiner l'écran et, c'est fini !

Vous avez vu, ce script est très simple (en fait, j'en ai écris un plus évolué ici), vous voudrez peut-être l'étendre, par exemple importer des objets "mesh", ou importer "Part geometry" qui n'a pas de face, ou importer d'autres formats que FreeCAD peut lire. Vous pouvez également exporter les formes géométriques dans un document FreeCAD, la procédure est la même. Vous pouvez également créer un dialogue, afin que l'utilisateur puisse choisir ce qu'il veut importer, etc . . . En réalité, la beauté dans tout cela, réside du fait que vous laissez faire la totalité du travail à FreeCAD, tout en présentant ses résultats dans le programme de votre choix.

Utilisation de FreeCAD avec interface graphique (GUI)

Depuis la version 4.2 de Qt, Qt a la capacité d'intégrer des plugins Qt-GUI dépendants d'applications hôtes non-Qt, et, de partager la boucle évènementielle de l'hôte.

Principalement pour FreeCAD, cela signifie qu'il peut être importé à partir d'une autre application avec son interface utilisateur entière (GUI) par conséquences, l'application hôte prend le contrôle total de FreeCAD.

L'ensemble du code Python nécessaire pour atteindre ce but, n'a que deux lignes:

import FreeCADGui 
FreeCADGui.showMainWindow()

Si, l'application hôte est basée sur Qt, alors cette solution devrait fonctionner sur toutes les plates-formes supportées par Qt. Toutefois, l'hôte doit être de la même version Qt que la version utilisée pour FreeCAD, sinon, vous pouvez obtenir des erreurs d'exécution inattendues.

Cependant, pour les applications non-Qt, il ya quelques restrictions, que vous devez connaitre:

  • Cette solution ne fonctionnera probablement pas avec tous les autres outils (toolkit):
    • Pour Windows, il fonctionnera aussi longtemps que l'application hôte utilisée est compatible avec Win32 ou, tout autres outils (toolkit) qui utilisent l'API Win32, comme wxWidgets, MFC ou WinForms.
    • Pour le faire fonctionner sous X11 (Linux), l'application hôte doit utiliser la bibliothèque "glib".

PS:pour toute application console, cette solution, bien sûr ne fonctionnera pas car, il n'y a pas de fonctionnement "boucle évènementielle" dans ce système.

Avertissement

Bien qu'il soit possible d'importer FreeCAD vers un interpréteur Python externe, il ne s'agit pas d'un scénario d'utilisation courant et cela nécessite quelques précautions. En règle générale, il est préférable d'utiliser le Python fourni avec FreeCAD, d'exécuter FreeCAD via une ligne de commande, ou en tant que sous-processus. Voir Démarrage et configuration pour plus d'informations sur les deux dernières options.

Puisque le module Python de FreeCAD est compilé à partir de C ++ (plutôt que d'être un pur module Python), il ne peut être importé qu'à partir d'un interpréteur Python compatible. Cela signifie généralement que l'interpréteur Python doit être compilé avec le même compilateur C que celui utilisé pour construire FreeCAD. Les informations sur le compilateur utilisé pour construire un interpréteur Python (y compris celui construit avec FreeCAD) peuvent être trouvés comme suit:

>>> import sys
>>> sys.version
'2.7.13 (default, Dec 17 2016, 23:03:43) \n[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]'


Arrow-left.svg Page précédente: Script d'objects
Page suivante: Bouts de code Arrow-right.svg
Arrow-left.svg Page précédente: Embedding FreeCAD
Page suivante: Line drawing function Arrow-right.svg
Base ExampleCommandModel.png Tutoriel
Thème
Python
Niveau
Débutant
Temps d'exécution estimé
Auteur
Version de FreeCAD
Fichier(s) exemple(s)


Cette page contient des exemples, des pièces, des extraits de code FreeCAD en Python, recueillis auprès d'utilisateurs expérimentés et de discussions sur les forums. Lisez les et utilisez les comme point de départ pour vos propres scripts...

Un fichier typique InitGui.py

En plus de votre module principal, chaque module doit contenir, un fichier InitGui.py, responsable de l'insertion du module dans l'interface principale.

Ceci est un simple exemple.

class ScriptWorkbench (Workbench): 
    MenuText = "Scripts"
    def Initialize(self):
        import Scripts # assuming Scripts.py is your module
        list = ["Script_Cmd"] # That list must contain command names, that can be defined in Scripts.py
        self.appendToolbar("My Scripts",list) 
        
Gui.addWorkbench(ScriptWorkbench())

Un fichier module typique

Ceci est l'exemple d'un fichier module principal, il contient tout ce que fait votre module. C'est le fichier Scripts.py invoqué dans l'exemple précédent. Vous avez ici toutes vos commandes personnalisées.

import FreeCAD, FreeCADGui 
 
class ScriptCmd: 
   def Activated(self): 
       # Here your write what your ScriptCmd does...
       FreeCAD.Console.PrintMessage('Hello, World!')
   def GetResources(self): 
       return {'Pixmap' : 'path_to_an_icon/myicon.png', 'MenuText': 'Short text', 'ToolTip': 'More detailed text'} 
       
FreeCADGui.addCommand('Script_Cmd', ScriptCmd())

Importer un nouveau type de fichier

Importer un nouveau type de fichier dans FreeCAD est facile. FreeCAD ne prends pas en considération l'importation de n'importe quelle données dans un document ouvert, parce que, vous ne pouvez pas ouvrir directement un nouveau type de fichier.

Donc, ce que vous devez faire, c'est ajouter la nouvelle extension de fichier à la liste des extensions connues de FreeCAD, et, d'écrire le code qui va lire le fichier et créer les objets FreeCAD que vous voulez.

Cette ligne doit être ajoutée au fichier InitGui.py pour ajouter la nouvelle extension de fichier à la liste:

# Assumes Import_Ext.py is the file that has the code for opening and reading .ext files
FreeCAD.addImportType("Your new File Type (*.ext)","Import_Ext")

Puis, dans le fichier Import_Ext.py, faites:

def open(filename): 
   doc=App.newDocument()
   # here you do all what is needed with filename, read, classify data, create corresponding FreeCAD objects
   doc.recompute()

Pour exporter votre document avec une nouvelle extension, le fonctionnement est le même, mais vous devrez faire:

FreeCAD.addExportType("Your new File Type (*.ext)","Export_Ext") 

Ajouter une ligne

Une ligne, à uniquement deux points.

import Part,PartGui 
doc=App.activeDocument() 
# add a line element to the document and set its points 
l=Part.LineSegment()
l.StartPoint=(0.0,0.0,0.0)
l.EndPoint=(1.0,1.0,1.0)
doc.addObject("Part::Feature","Line").Shape=l.toShape() 
doc.recompute()

Ajouter un polygone

Un polygone est simplement un ensemble de segments connnectés (un polyline dans AutoCAD) il n'est pas obligatoirement fermé.

import Part,PartGui 
doc=App.activeDocument()
n=list() 
# create a 3D vector, set its coordinates and add it to the list 
v=App.Vector(0,0,0) 
n.append(v) 
v=App.Vector(10,0,0) 
n.append(v) 
#... repeat for all nodes 
# Create a polygon object and set its nodes 
p=doc.addObject("Part::Polygon","Polygon") 
p.Nodes=n 
doc.recompute()

Ajout et suppression d'objet(s) dans un groupe

doc=App.activeDocument() 
grp=doc.addObject("App::DocumentObjectGroup", "Group") 
lin=doc.addObject("Part::Feature", "Line")
grp.addObject(lin) # adds the lin object to the group grp
grp.removeObject(lin) # removes the lin object from the group grp

PS: vous pouvez aussi ajouter un groupe dans un groupe . . .

Ajout d'une maille (Mesh)

import Mesh
doc=App.activeDocument()
# create a new empty mesh
m = Mesh.Mesh()
# build up box out of 12 facets
m.addFacet(0.0,0.0,0.0, 0.0,0.0,1.0, 0.0,1.0,1.0)
m.addFacet(0.0,0.0,0.0, 0.0,1.0,1.0, 0.0,1.0,0.0)
m.addFacet(0.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,1.0)
m.addFacet(0.0,0.0,0.0, 1.0,0.0,1.0, 0.0,0.0,1.0)
m.addFacet(0.0,0.0,0.0, 0.0,1.0,0.0, 1.0,1.0,0.0)
m.addFacet(0.0,0.0,0.0, 1.0,1.0,0.0, 1.0,0.0,0.0)
m.addFacet(0.0,1.0,0.0, 0.0,1.0,1.0, 1.0,1.0,1.0)
m.addFacet(0.0,1.0,0.0, 1.0,1.0,1.0, 1.0,1.0,0.0)
m.addFacet(0.0,1.0,1.0, 0.0,0.0,1.0, 1.0,0.0,1.0)
m.addFacet(0.0,1.0,1.0, 1.0,0.0,1.0, 1.0,1.0,1.0)
m.addFacet(1.0,1.0,0.0, 1.0,1.0,1.0, 1.0,0.0,1.0)
m.addFacet(1.0,1.0,0.0, 1.0,0.0,1.0, 1.0,0.0,0.0)
# scale to a edge langth of 100
m.scale(100.0)
# add the mesh to the active document
me=doc.addObject("Mesh::Feature","Cube")
me.Mesh=m

Ajout d'un arc ou d'un cercle

import Part
doc = App.activeDocument()
c = Part.Circle() 
c.Radius=10.0  
f = doc.addObject("Part::Feature", "Circle") # create a document with a circle feature 
f.Shape = c.toShape() # Assign the circle shape to the shape property 
doc.recompute()

Accéder et changer la représentation d'un objet

Chaque objet dans un document FreeCAD a un objet vue associé a une représentation qui stocke tous les paramètres qui définissent les propriétés de l'objet, comme, la couleur, l'épaisseur de la ligne, etc ..

gad=Gui.activeDocument()   # access the active document containing all 
                          # view representations of the features in the
                          # corresponding App document 

v=gad.getObject("Cube")    # access the view representation to the Mesh feature 'Cube' 
v.ShapeColor               # prints the color to the console 
v.ShapeColor=(1.0,1.0,1.0) # sets the shape color to white

Observation des évènements de la souris dans la vue 3D via Python

Le cadre Inventor permet d'ajouter un ou plusieurs noeuds (nodes) de rappel à la scène graphique visualisée. Par défaut, FreeCAD, possède un noeud (node) de rappel installé par la visionneuse (fenêtre d'affichage des graphes), qui permet d'ajouter des fonctions statiques ou globales en C++. Des méthodes de liaisons appropriées sont fournies avec Python, pour permettre l'utilisation de cette technique à partir de codes Python.

App.newDocument()
v=Gui.activeDocument().activeView()
 
#This class logs any mouse button events. As the registered callback function fires twice for 'down' and
#'up' events we need a boolean flag to handle this.
class ViewObserver:
   def logPosition(self, info):
       down = (info["State"] == "DOWN")
       pos = info["Position"]
       if (down):
           FreeCAD.Console.PrintMessage("Clicked on position: ("+str(pos[0])+", "+str(pos[1])+")\n")
       
o = ViewObserver()
c = v.addEventCallback("SoMouseButtonEvent",o.logPosition)

Maintenant, choisissez une zone dans l'écran (surface de travail) 3D et observez les messages affichés dans la fenêtre de sortie. Pour terminer l'observation il suffit de faire:

v.removeEventCallback("SoMouseButtonEvent",c)

Les types d’évènements suivants sont pris en charge:

  • SoEvent -- tous types d'évènements
  • SoButtonEvent -- tous les évènements, boutons, molette
  • SoLocation2Event -- tous les évènements 2D (déplacements normaux de la souris)
  • SoMotion3Event -- tous les évènements 3D (pour le spaceball)
  • SoKeyboardEvent -- évènements des touches flèche haut et flèche bas
  • SoMouseButtonEvent -- tous les évènements boutons Haut et Bas de la souris
  • SoSpaceballButtonEvent -- tous les évènements Haut et Bas (pour le spaceball)

Les fonctions Python qui peuvent être enregistrées avec addEventCallback() attendent la définition d'une bibliothèque.

Suivant la façon dont l’évènement survient, la bibliothèque peut disposer de différentes clefs.

Il y a une clef pour chaque événement:

  • Type -- le nom du type d'évènement par exemple SoMouseEvent, SoLocation2Event, ...
  • Time -- l'heure courante codée dans une chaîne string
  • Position -- un tuple de deux integers, donant la position x,y de la souris
  • ShiftDown -- type boolean, true si Shift est pressé sinon, false
  • CtrlDown -- type boolean, true si Ctrl est pressé sinon, false
  • AltDown -- type boolean, true si Alt est pressé sinon, false

Pour un évènement bouton comme clavier, souris ou spaceball

  • State -- la chaîne UP si le bouton est relevé, DOWN si le bouton est enfoncé ou UNKNOWN si rien ne se passe

Pour un évènement clavier:

  • Key -- le caractère de la touche qui est pressée

Pour un évènement bouton de souris:

  • Button -- le bouton pressé peut être BUTTON1, ..., BUTTON5 ou tous

Pour un évènement spaceball:

  • Button -- le bouton pressé peut être BUTTON1, ..., BUTTON7 ou tous

Et finalement les évènement de mouvements:

  • Translation -- un tuple de trois float()
  • Rotation -- un quaternion, tuple de quattre float()

Afficher les évènements claviers et commandes

Cette macro affiche dans la vue du rapport les touches enfoncées et tous les événements commande

App.newDocument()
v=Gui.activeDocument().activeView()
class ViewObserver:
   def logPosition(self, info):
       try:
           down = (info["Key"])
           FreeCAD.Console.PrintMessage(str(down)+"\n") # here the character pressed
           FreeCAD.Console.PrintMessage(str(info)+"\n") # list all events command
           FreeCAD.Console.PrintMessage("_______________________________________"+"\n")
       except Exception:
           None
 
o = ViewObserver()
c = v.addEventCallback("SoEvent",o.logPosition)

#v.removeEventCallback("SoEvent",c) # remove ViewObserver

Manipulation de scènes graphiques en Python

Il est aussi possible d'afficher ou de changer de scène en programmation Python, avec le module pivy en combinaison avec Coin

from pivy.coin import *                # load the pivy module
view = Gui.ActiveDocument.ActiveView   # get the active viewer
root = view.getSceneGraph()            # the root is an SoSeparator node
root.addChild(SoCube())
view.fitAll()

L'API Python de pivy est créé en utilisant l'outil SWIG. Comme dans FreeCAD nous utilisons certains noeuds (nodes) écrits automatiquement nous ne pouvons pas les créer directement en Python. Il est cependant, possible de créer un noeud avec son nom interne. Un exemple de SoFCSelection, le type peut être créé avec:

type = SoType.fromName("SoFCSelection")
node = type.createInstance()

Ajouter et effacer des objets de la scène

Ajouter de nouveaux noeuds dans la scène graphique peut être fait de cette façon. Prenez toujours soin d'ajouter un SoSeparator pour, contenir les propriétés de la forme géométrique, les coordonnées et le matériel d'un même objet. L'exemple suivant ajoute une ligne rouge à partir de (0,0,0) à (10,0,0):

from pivy import coin
sg = Gui.ActiveDocument.ActiveView.getSceneGraph()
co = coin.SoCoordinate3()
pts = [[0,0,0],[10,0,0]]
co.point.setValues(0,len(pts),pts)
ma = coin.SoBaseColor()
ma.rgb = (1,0,0)
li = coin.SoLineSet()
li.numVertices.setValue(2)
no = coin.SoSeparator()
no.addChild(co)
no.addChild(ma)
no.addChild(li)
sg.addChild(no)

Pour le supprimer, il suffit de:

sg.removeChild(no)

Enregistre la vue 3Den pratiquant une rotation dans une série de 36 fichiers dans les axes X Y Z

import math
import time
from FreeCAD import Base
from pivy import coin

size=(1000,1000)
dirname = "C:/Temp/animation/"
steps=36
angle=2*math.pi/steps

matX=Base.Matrix()
matX.rotateX(angle)
stepsX=Base.Placement(matX).Rotation

matY=Base.Matrix()
matY.rotateY(angle)
stepsY=Base.Placement(matY).Rotation

matZ=Base.Matrix()
matZ.rotateZ(angle)
stepsZ=Base.Placement(matZ).Rotation

view=Gui.ActiveDocument.ActiveView
cam=view.getCameraNode()
rotCamera=Base.Rotation(*cam.orientation.getValue().getValue())

# this sets the lookat point to the center of circumsphere of the global bounding box
view.fitAll()

# the camera's position, i.e. the user's eye point
position=Base.Vector(*cam.position.getValue().getValue())
distance=cam.focalDistance.getValue()

# view direction
vec=rotCamera.multVec(Base.Vector(0,0,-1))

# this is the point on the screen the camera looks at
# when rotating the camera we should make this point fix
lookat=position+vec*distance

# around x axis
for i in range(steps):
    rotCamera=stepsX.multiply(rotCamera)
    cam.orientation.setValue(*rotCamera.Q)
    vec=rotCamera.multVec(Base.Vector(0,0,-1))
    pos=lookat-vec*distance
    cam.position.setValue(pos.x,pos.y,pos.z)
    Gui.updateGui()
    time.sleep(0.3)
    view.saveImage(dirname+"x-%d.png" % i,*size)

# around y axis
for i in range(steps):
    rotCamera=stepsY.multiply(rotCamera)
    cam.orientation.setValue(*rotCamera.Q)
    vec=rotCamera.multVec(Base.Vector(0,0,-1))
    pos=lookat-vec*distance
    cam.position.setValue(pos.x,pos.y,pos.z)
    Gui.updateGui()
    time.sleep(0.3)
    view.saveImage(dirname+"y-%d.png" % i,*size)

# around z axis
for i in range(steps):
    rotCamera=stepsZ.multiply(rotCamera)
    cam.orientation.setValue(*rotCamera.Q)
    vec=rotCamera.multVec(Base.Vector(0,0,-1))
    pos=lookat-vec*distance
    cam.position.setValue(pos.x,pos.y,pos.z)
    Gui.updateGui()
    time.sleep(0.3)
    view.saveImage(dirname+"z-%d.png" % i,*size)

Ajout de widgets personnalisés à l'interface

Vous pouvez créer un widget avec Qt designer, le transformer en Script Python et l'incorporer dans l'interface de FreeCAD avec PySide.

Le code python produit par le compilateur python Ui (l'outil qui convertit les fichiers .ui de qt-designer en code python) généralement codé comme ceci (il est simple, vous pouvez aussi le coder directement en Python):

class myWidget_Ui(object):
    def setupUi(self, myWidget):
        myWidget.setObjectName("my Nice New Widget")
        myWidget.resize(QtCore.QSize(QtCore.QRect(0,0,300,100).size()).expandedTo(myWidget.minimumSizeHint())) # sets size of the widget
 
        self.label = QtGui.QLabel(myWidget) # creates a label
        self.label.setGeometry(QtCore.QRect(50,50,200,24)) # sets its size
        self.label.setObjectName("label") # sets its name, so it can be found by name

    def retranslateUi(self, draftToolbar): # built-in QT function that manages translations of widgets
        myWidget.setWindowTitle(QtGui.QApplication.translate("myWidget", "My Widget", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("myWidget", "Welcome to my new widget!", None, QtGui.QApplication.UnicodeUTF8))

Puis, vous devez créer une référence à la fenêtre FreeCAD Qt, lui insérer le widget personnalisé, et transférer le code Ui du widget que nous venons de faire dans le vôtre avec:

app = QtGui.qApp
FCmw = app.activeWindow() # the active qt window, = the freecad window since we are inside it
# FCmw = FreeCADGui.getMainWindow() # use this line if the 'addDockWidget' error is declared
myNewFreeCADWidget = QtGui.QDockWidget() # create a new dckwidget
myNewFreeCADWidget.ui = myWidget_Ui() # load the Ui script
myNewFreeCADWidget.ui.setupUi(myNewFreeCADWidget) # setup the ui
FCmw.addDockWidget(QtCore.Qt.RightDockWidgetArea,myNewFreeCADWidget) # add the widget to the main window

Ajout d'une liste déroulante

Le code suivant vous permet d'ajouter une liste déroulante dans FreeCAD, en plus des onglets "Projet" et "tâches". Il utilise également le module uic pour charger un fichier ui directement dans cet onglet.

# create new Tab in ComboView
from PySide import QtGui,QtCore
#from PySide import uic

def getMainWindow():
   "returns the main window"
   # using QtGui.qApp.activeWindow() isn't very reliable because if another
   # widget than the mainwindow is active (e.g. a dialog) the wrong widget is
   # returned
   toplevel = QtGui.qApp.topLevelWidgets()
   for i in toplevel:
       if i.metaObject().className() == "Gui::MainWindow":
           return i
   raise Exception("No main window found")

def getComboView(mw):
   dw=mw.findChildren(QtGui.QDockWidget)
   for i in dw:
       if str(i.objectName()) == "Combo View":
           return i.findChild(QtGui.QTabWidget)
       elif str(i.objectName()) == "Python Console":
           return i.findChild(QtGui.QTabWidget)
   raise Exception ("No tab widget found")

mw = getMainWindow()
tab = getComboView(getMainWindow())
tab2=QtGui.QDialog()
tab.addTab(tab2,"A Special Tab")

#uic.loadUi("/myTaskPanelforTabs.ui",tab2)
tab2.show()
#tab.removeTab(2)

Activer ou désactiver une fenêtre

from PySide import QtGui
mw=FreeCADGui.getMainWindow()
dws=mw.findChildren(QtGui.QDockWidget)

# objectName may be :
# "Report view"
# "Tree view"
# "Property view"
# "Selection view"
# "Combo View"
# "Python console"
# "draftToolbar"

for i in dws:
  if i.objectName() == "Report view":
    dw=i
    break

va=dw.toggleViewAction()
va.setChecked(True)        # True or False
dw.setVisible(True)        # True or False

Ouverture d'une page web

import WebGui
WebGui.openBrowser("http://www.example.com")

Obtenir le code HTML d'une page Web ouverte

from PySide import QtGui,QtWebKit
a = QtGui.qApp
mw = a.activeWindow()
v = mw.findChild(QtWebKit.QWebFrame)
html = unicode(v.toHtml())
print html

Extraire et utiliser les coordonnées de 3 points sélectionnés

# -*- coding: utf-8 -*-
# the line above to put the accentuated in the remarks
# If this line is missing, an error will be returned
# extract and use the coordinates of 3 objects selected
import Part, FreeCAD, math, PartGui, FreeCADGui
from FreeCAD import Base, Console
sel = FreeCADGui.Selection.getSelection() # " sel " contains the items selected
if len(sel)!=3 :
  # If there are no 3 objects selected, an error is displayed in the report view
  # The \r and \n at the end of line mean return and the newline CR + LF.
  Console.PrintError("Select 3 points exactly\r\n")
else :
  points=[]
  for obj in sel:
    points.append(obj.Shape.BoundBox.Center)

  for pt in points:
    # display of the coordinates in the report view
    Console.PrintMessage(str(pt.x)+"\r\n")
    Console.PrintMessage(str(pt.y)+"\r\n")
    Console.PrintMessage(str(pt.z)+"\r\n")

  Console.PrintMessage(str(pt[1]) + "\r\n")

Lister les objets

# -*- coding: utf-8 -*-
import FreeCAD,Draft
# List all objects of the document
doc = FreeCAD.ActiveDocument
objs = FreeCAD.ActiveDocument.Objects
#App.Console.PrintMessage(str(objs) + "\n")
#App.Console.PrintMessage(str(len(FreeCAD.ActiveDocument.Objects)) + " Objects"  + "\n")

for obj in objs:
    a = obj.Name                                             # list the Name  of the object  (not modifiable)
    b = obj.Label                                            # list the Label of the object  (modifiable)
    try:
        c = obj.LabelText                                    # list the LabeText of the text (modifiable)
        App.Console.PrintMessage(str(a) +" "+ str(b) +" "+ str(c) + "\n") # Displays the Name the Label and the text
    except:
        App.Console.PrintMessage(str(a) +" "+ str(b) + "\n") # Displays the Name and the Label of the object

#doc.removeObject("Box") # Clears the designated object

Lister les dimensions en donnant le nom de l'objet

for edge in FreeCAD.ActiveDocument.MyObjectName.Shape.Edges: # replace "MyObjectName" for list
    print edge.Length


Fonction résidente avec action au clic de souris

Here with SelObserver on a object select

# -*- coding: utf-8 -*-
# causes an action to the mouse click on an object
# This function remains resident (in memory) with the function "addObserver(s)"
# "removeObserver(s) # Uninstalls the resident function
class SelObserver:
    def setPreselection(self,doc,obj,sub):                # Preselection object
        App.Console.PrintMessage(str(sub)+ "\n")          # The part of the object name

    def addSelection(self,doc,obj,sub,pnt):               # Selection object
        App.Console.PrintMessage("addSelection"+ "\n")
        App.Console.PrintMessage(str(doc)+ "\n")          # Name of the document
        App.Console.PrintMessage(str(obj)+ "\n")          # Name of the object
        App.Console.PrintMessage(str(sub)+ "\n")          # The part of the object name
        App.Console.PrintMessage(str(pnt)+ "\n")          # Coordinates of the object
        App.Console.PrintMessage("______"+ "\n")

    def removeSelection(self,doc,obj,sub):                # Delete the selected object
        App.Console.PrintMessage("removeSelection"+ "\n")

    def setSelection(self,doc):                           # Selection in ComboView
        App.Console.PrintMessage("setSelection"+ "\n")

    def clearSelection(self,doc):                         # If click on the screen, clear the selection
        App.Console.PrintMessage("clearSelection"+ "\n")  # If click on another object, clear the previous object
s =SelObserver()
FreeCADGui.Selection.addObserver(s)                       # install the function mode resident
#FreeCADGui.Selection.removeObserver(s)                   # Uninstall the resident function

Other example with ViewObserver on a object select or view

App.newDocument()
v=Gui.activeDocument().activeView()
 
#This class logs any mouse button events. As the registered callback function fires twice for 'down' and
#'up' events we need a boolean flag to handle this.
class ViewObserver:
   def __init__(self, view):
       self.view = view
   
   def logPosition(self, info):
       down = (info["State"] == "DOWN")
       pos = info["Position"]
       if (down):
           FreeCAD.Console.PrintMessage("Clicked on position: ("+str(pos[0])+", "+str(pos[1])+")\n")
           pnt = self.view.getPoint(pos)
           FreeCAD.Console.PrintMessage("World coordinates: " + str(pnt) + "\n")
           info = self.view.getObjectInfo(pos)
           FreeCAD.Console.PrintMessage("Object info: " + str(info) + "\n")

o = ViewObserver(v)
c = v.addEventCallback("SoMouseButtonEvent",o.logPosition)

Recherche et sélection de tous les éléments sous le curseur

from pivy import coin
import FreeCADGui

def mouse_over_cb( event_callback):
    event = event_callback.getEvent()
    pos = event.getPosition().getValue()
    listObjects = FreeCADGui.ActiveDocument.ActiveView.getObjectsInfo((int(pos[0]),int(pos[1])))
    obj = []
    if listObjects:
        FreeCAD.Console.PrintMessage("\n *** Objects under mouse pointer ***")
        for o in listObjects:
            label = str(o["Object"])
            if not label in obj:
                obj.append(label)
        FreeCAD.Console.PrintMessage("\n"+str(obj))


view = FreeCADGui.ActiveDocument.ActiveView

mouse_over = view.addEventCallbackPivy( coin.SoLocation2Event.getClassTypeId(), mouse_over_cb )

# to remove Callback :
#view.removeEventCallbackPivy( coin.SoLocation2Event.getClassTypeId(), mouse_over)

####
#The easy way is probably to use FreeCAD's selection.
#FreeCADGui.ActiveDocument.ActiveView.getObjectsInfo(mouse_coords)

####
#you get that kind of result :
#'Document': 'Unnamed', 'Object': 'Box', 'Component': 'Face2', 'y': 8.604081153869629, 'x': 21.0, 'z': 8.553047180175781

####
#You can use this data to add your element to FreeCAD's selection :
#FreeCADGui.Selection.addSelection(FreeCAD.ActiveDocument.Box,'Face2',21.0,8.604081153869629,8.553047180175781)

Lister les composantes d'un objet

# -*- coding: utf-8 -*-
# This function list the components of an object
# and extract this object its XYZ coordinates,
# its edges and their lengths center of mass and coordinates
# its faces and their center of mass
# its faces and their surfaces and coordinates
# 8/05/2014

import Draft,Part
def detail():
    sel = FreeCADGui.Selection.getSelection()   # Select an object
    if len(sel) != 0:                           # If there is a selection then
        Vertx=[]
        Edges=[]
        Faces=[]
        compt_V=0
        compt_E=0
        compt_F=0
        pas    =0
        perimetre = 0.0   
        EdgesLong = []

        # Displays the "Name" and the "Label" of the selection
        App.Console.PrintMessage("Selection > " + str(sel[0].Name) + "  " + str(sel[0].Label) +"\n"+"\n")

        for j in enumerate(sel[0].Shape.Edges):                                     # Search the "Edges" and their lengths
            compt_E+=1
            Edges.append("Edge%d" % (j[0]+1))
            EdgesLong.append(str(sel[0].Shape.Edges[compt_E-1].Length))
            perimetre += (sel[0].Shape.Edges[compt_E-1].Length)                     # calculates the perimeter

            # Displays the "Edge" and its length
            App.Console.PrintMessage("Edge"+str(compt_E)+" Length > "+str(sel[0].Shape.Edges[compt_E-1].Length)+"\n")

            # Displays the "Edge" and its center mass
            App.Console.PrintMessage("Edge"+str(compt_E)+" Center > "+str(sel[0].Shape.Edges[compt_E-1].CenterOfMass)+"\n")

            num = sel[0].Shape.Edges[compt_E-1].Vertexes[0]
            Vertx.append("X1: "+str(num.Point.x))
            Vertx.append("Y1: "+str(num.Point.y))
            Vertx.append("Z1: "+str(num.Point.z))
            # Displays the coordinates 1
            App.Console.PrintMessage("X1: "+str(num.Point[0])+" Y1: "+str(num.Point[1])+" Z1: "+str(num.Point[2])+"\n")

            try:
                num = sel[0].Shape.Edges[compt_E-1].Vertexes[1]
                Vertx.append("X2: "+str(num.Point.x))
                Vertx.append("Y2: "+str(num.Point.y))
                Vertx.append("Z2: "+str(num.Point.z))
            except:
                Vertx.append("-")
                Vertx.append("-")
                Vertx.append("-")
            # Displays the coordinates 2
            App.Console.PrintMessage("X2: "+str(num.Point[0])+" Y2: "+str(num.Point[1])+" Z2: "+str(num.Point[2])+"\n")

            App.Console.PrintMessage("\n")
        App.Console.PrintMessage("Perimeter of the form  : "+str(perimetre)+"\n") 

        App.Console.PrintMessage("\n")
        FacesSurf = []
        for j in enumerate(sel[0].Shape.Faces):                                      # Search the "Faces" and their surface
            compt_F+=1
            Faces.append("Face%d" % (j[0]+1))
            FacesSurf.append(str(sel[0].Shape.Faces[compt_F-1].Area))

            # Displays 'Face' and its surface
            App.Console.PrintMessage("Face"+str(compt_F)+" >  Surface "+str(sel[0].Shape.Faces[compt_F-1].Area)+"\n")

            # Displays 'Face' and its CenterOfMass
            App.Console.PrintMessage("Face"+str(compt_F)+" >  Center  "+str(sel[0].Shape.Faces[compt_F-1].CenterOfMass)+"\n")

            # Displays 'Face' and its Coordinates
            FacesCoor = []
            fco = 0
            for f0 in sel[0].Shape.Faces[compt_F-1].Vertexes:                        # Search the Vertexes of the face
                fco += 1
                FacesCoor.append("X"+str(fco)+": "+str(f0.Point.x))
                FacesCoor.append("Y"+str(fco)+": "+str(f0.Point.y))
                FacesCoor.append("Z"+str(fco)+": "+str(f0.Point.z))

            # Displays 'Face' and its Coordinates
            App.Console.PrintMessage("Face"+str(compt_F)+" >  Coordinate"+str(FacesCoor)+"\n")

            # Displays 'Face' and its Volume
            App.Console.PrintMessage("Face"+str(compt_F)+" >  Volume  "+str(sel[0].Shape.Faces[compt_F-1].Volume)+"\n")
            App.Console.PrintMessage("\n")

        # Displays the total surface of the form
        App.Console.PrintMessage("Surface of the form    : "+str(sel[0].Shape.Area)+"\n")

        # Displays the total Volume of the form
        App.Console.PrintMessage("Volume  of the form    : "+str(sel[0].Shape.Volume)+"\n")

detail()

Lister les PropertiesList

import FreeCADGui
from FreeCAD import Console
o = App.ActiveDocument.ActiveObject
op = o.PropertiesList
for p in op:
    Console.PrintMessage("Property: "+ str(p)+ " Value: " + str(o.getPropertyByName(p))+"\r\n")

Ajouter une Propriété "Commentaire"

import Draft
obj = FreeCADGui.Selection.getSelection()[0]
obj.addProperty("App::PropertyString","GComment","Draft","Font name").GComment = "Comment here"
App.activeDocument().recompute()

Recherche et extraction de données

Exemple de recherche et décodage des informations d'un objet

Chaque section est séparée par des dièses "############" vous pouvez les copier directement dans la console, les utiliser dans vos macro ou utiliser la macro complète. La description de la commande est dans le commentaire.

L'affichage se fait dans la vue rapport (Menu Affichage → Vues → Vue rapport)

# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
 
# Exemples de recherche et de decodage d'informations sur un objet
# Chaque section peut etre copiee directement dans la console Python ou dans une macro ou utilisez la macro tel quel
# Certaines commandes se repetent seul l'approche est differente
# L'affichage se fait dans la Vue rapport : Menu Affichage > Vues > Vue rapport
#
# Examples of research and decoding information on an object
# Each section can be copied directly into the Python console, or in a macro or uses this macro
# Certain commands as repeat alone approach is different
# Displayed on Report view : Menu View > Views > report view
#
# rev:30/08/2014:29/09/2014:17/09/2015
 
from FreeCAD import Base
import DraftVecUtils, Draft, Part
 
mydoc = FreeCAD.activeDocument().Name                                     # Name of active Document
App.Console.PrintMessage("Active docu    : "+(mydoc)+"\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
object_Label = sel[0].Label                                               # Label of the object (modifiable)
App.Console.PrintMessage("object_Label   : "+(object_Label)+"\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
App.Console.PrintMessage("sel            : "+str(sel[0])+"\n\n")          # sel[0] first object selected
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
object_Name  = sel[0].Name                                                # Name of the object (not modifiable)
App.Console.PrintMessage("object_Name    : "+str(object_Name)+"\n\n")
##################################################################################
 
try:
    SubElement = FreeCADGui.Selection.getSelectionEx()                    # sub element name with getSelectionEx()
    element_ = SubElement[0].SubElementNames[0]                           # name of 1 element selected
    App.Console.PrintMessage("elementSelec   : "+str(element_)+"\n\n")            
except:
    App.Console.PrintMessage("Oups"+"\n\n")            
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
App.Console.PrintMessage("sel            : "+str(sel[0])+"\n\n")          # sel[0] first object selected
##################################################################################
 
SubElement = FreeCADGui.Selection.getSelectionEx()                        # sub element name with getSelectionEx()
App.Console.PrintMessage("SubElement     : "+str(SubElement[0])+"\n\n")   # name of sub element
##################################################################################

SubElement = Gui.Selection.getSelectionEx()[0].SubObjects[0].Length       # sub element or element name with getSelectionEx()
App.Console.PrintMessage("SubElement length: "+str(length)+"\n")          # length
##################################################################################

sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
i = 0
for j in enumerate(sel[0].Shape.Edges):                                   # list all Edges
    i += 1
    App.Console.PrintMessage("Edges n : "+str(i)+"\n")
    a = sel[0].Shape.Edges[j[0]].Vertexes[0]
    App.Console.PrintMessage("X1             : "+str(a.Point.x)+"\n")     # coordinate XYZ first point
    App.Console.PrintMessage("Y1             : "+str(a.Point.y)+"\n")
    App.Console.PrintMessage("Z1             : "+str(a.Point.z)+"\n")
    try:
        a = sel[0].Shape.Edges[j[0]].Vertexes[1]
        App.Console.PrintMessage("X2             : "+str(a.Point.x)+"\n") # coordinate XYZ second point
        App.Console.PrintMessage("Y2             : "+str(a.Point.y)+"\n")
        App.Console.PrintMessage("Z2             : "+str(a.Point.z)+"\n")
    except:
        App.Console.PrintMessage("Oups"+"\n")    
App.Console.PrintMessage("\n")    
##################################################################################
 
try:
    SubElement = FreeCADGui.Selection.getSelectionEx()                                        # sub element name with getSelectionEx()
    subElementName = Gui.Selection.getSelectionEx()[0].SubElementNames[0]                     # sub element name with getSelectionEx()
    App.Console.PrintMessage("subElementName : "+str(subElementName)+"\n")
    
    subObjectLength = Gui.Selection.getSelectionEx()[0].SubObjects[0].Length                  # sub element Length
    App.Console.PrintMessage("subObjectLength: "+str(subObjectLength)+"\n\n")
    
    subObjectX1 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[0].Point.x         # sub element coordinate X1
    App.Console.PrintMessage("subObject_X1   : "+str(subObjectX1)+"\n")
    subObjectY1 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[0].Point.y         # sub element coordinate Y1
    App.Console.PrintMessage("subObject_Y1   : "+str(subObjectY1)+"\n")
    subObjectZ1 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[0].Point.z         # sub element coordinate Z1
    App.Console.PrintMessage("subObject_Z1   : "+str(subObjectZ1)+"\n\n")

    try:
        subObjectX2 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[1].Point.x     # sub element coordinate X2
        App.Console.PrintMessage("subObject_X2   : "+str(subObjectX2)+"\n")
        subObjectY2 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[1].Point.y     # sub element coordinate Y2
        App.Console.PrintMessage("subObject_Y2   : "+str(subObjectY2)+"\n")
        subObjectZ2 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[1].Point.z     # sub element coordinate Z2
        App.Console.PrintMessage("subObject_Z2   : "+str(subObjectZ2)+"\n\n")
    except:
        App.Console.PrintMessage("Oups"+"\n\n")            

    subObjectBoundBox = Gui.Selection.getSelectionEx()[0].SubObjects[0].BoundBox              # sub element BoundBox coordinates
    App.Console.PrintMessage("subObjectBBox  : "+str(subObjectBoundBox)+"\n")
    
    subObjectBoundBoxCenter = Gui.Selection.getSelectionEx()[0].SubObjects[0].BoundBox.Center # sub element BoundBoxCenter
    App.Console.PrintMessage("subObjectBBoxCe: "+str(subObjectBoundBoxCenter)+"\n")
    
    surfaceFace = Gui.Selection.getSelectionEx()[0].SubObjects[0].Area                        # Area of the face selected
    App.Console.PrintMessage("surfaceFace    : "+str(surfaceFace)+"\n\n")
except:
    App.Console.PrintMessage("Oups"+"\n\n")            
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
surface = sel[0].Shape.Area                                               # Area object complete
App.Console.PrintMessage("surfaceObjet   : "+str(surface)+"\n\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
CenterOfMass = sel[0].Shape.CenterOfMass                                  # Center of Mass of the object
App.Console.PrintMessage("CenterOfMass   : "+str(CenterOfMass)+"\n")
App.Console.PrintMessage("CenterOfMassX  : "+str(CenterOfMass[0])+"\n")   # coordinates [0]=X [1]=Y [2]=Z
App.Console.PrintMessage("CenterOfMassY  : "+str(CenterOfMass[1])+"\n")
App.Console.PrintMessage("CenterOfMassZ  : "+str(CenterOfMass[2])+"\n\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
for j in enumerate(sel[0].Shape.Faces):                                   # List alles faces of the object
    App.Console.PrintMessage("Face           : "+str("Face%d" % (j[0]+1))+"\n")
App.Console.PrintMessage("\n\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
volume_ = sel[0].Shape.Volume                                             # Volume of the object
App.Console.PrintMessage("volume_        : "+str(volume_)+"\n\n")
##################################################################################
 
objs = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()

if len(objs) >= 1:
    if hasattr(objs[0], "Shape"):
        s = objs[0].Shape
    elif hasattr(objs[0], "Mesh"):      # upgrade with wmayer thanks #http://forum.freecadweb.org/viewtopic.php?f=13&t=22331
        s = objs[0].Mesh
    elif hasattr(objs[0], "Points"):
        s = objs[0].Points

#sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
#boundBox_= sel[0].Shape.BoundBox                                          # BoundBox of the object
boundBox_= s.BoundBox                                                      # BoundBox of the object
App.Console.PrintMessage("boundBox_      : "+str(boundBox_)+"\n")
 
boundBoxLX  = boundBox_.XLength                                           # Length x boundBox rectangle
boundBoxLY  = boundBox_.YLength                                           # Length y boundBox rectangle
boundBoxLZ  = boundBox_.ZLength                                           # Length z boundBox rectangle
boundBoxDiag= boundBox_.DiagonalLength                                    # Diagonal Length boundBox rectangle

App.Console.PrintMessage("boundBoxLX     : "+str(boundBoxLX)+"\n")
App.Console.PrintMessage("boundBoxLY     : "+str(boundBoxLY)+"\n")
App.Console.PrintMessage("boundBoxLZ     : "+str(boundBoxLZ)+"\n")
App.Console.PrintMessage("boundBoxDiag   : "+str(boundBoxDiag)+"\n\n")

##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
pl = sel[0].Shape.Placement                                               # Placement Vector XYZ and Yaw-Pitch-Roll
App.Console.PrintMessage("Placement      : "+str(pl)+"\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
pl = sel[0].Shape.Placement.Base                                          # Placement Vector XYZ
App.Console.PrintMessage("PlacementBase  : "+str(pl)+"\n\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
oripl_X = sel[0].Placement.Base[0]                                        # decode Placement X
oripl_Y = sel[0].Placement.Base[1]                                        # decode Placement Y
oripl_Z = sel[0].Placement.Base[2]                                        # decode Placement Z
 
App.Console.PrintMessage("oripl_X        : "+str(oripl_X)+"\n")
App.Console.PrintMessage("oripl_Y        : "+str(oripl_Y)+"\n")
App.Console.PrintMessage("oripl_Z        : "+str(oripl_Z)+"\n\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
rotation = sel[0].Placement.Rotation                                      # decode Placement Rotation
App.Console.PrintMessage("rotation              : "+str(rotation)+"\n\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
pl = sel[0].Shape.Placement.Rotation                                      # decode Placement Rotation other method
App.Console.PrintMessage("Placement Rot         : "+str(pl)+"\n\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
pl = sel[0].Shape.Placement.Rotation.Angle                                # decode Placement Rotation Angle
App.Console.PrintMessage("Placement Rot Angle   : "+str(pl)+"\n\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
Rot_0 = sel[0].Placement.Rotation.Q[0]                                    # decode Placement Rotation Q
App.Console.PrintMessage("Rot_0         : "+str(Rot_0)+ " rad ,  "+str(180 * Rot_0 / 3.1416)+" deg "+"\n")
 
Rot_1 = sel[0].Placement.Rotation.Q[1]                                    # decode Placement Rotation 1
App.Console.PrintMessage("Rot_1         : "+str(Rot_1)+ " rad ,  "+str(180 * Rot_1 / 3.1416)+" deg "+"\n")
 
Rot_2 = sel[0].Placement.Rotation.Q[2]                                    # decode Placement Rotation 2
App.Console.PrintMessage("Rot_2         : "+str(Rot_2)+ " rad ,  "+str(180 * Rot_2 / 3.1416)+" deg "+"\n")
 
Rot_3 = sel[0].Placement.Rotation.Q[3]                                    # decode Placement Rotation 3
App.Console.PrintMessage("Rot_3         : "+str(Rot_3)+"\n\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
Yaw   = sel[0].Shape.Placement.Rotation.toEuler()[0]                      # decode angle Euler Yaw (Z)
App.Console.PrintMessage("Yaw            : "+str(Yaw)+"\n")
Pitch = sel[0].Shape.Placement.Rotation.toEuler()[1]                      # decode angle Euler Pitch (Y)
App.Console.PrintMessage("Pitch          : "+str(Pitch)+"\n")
Roll  = sel[0].Shape.Placement.Rotation.toEuler()[2]                      # decode angle Euler Roll (X)
App.Console.PrintMessage("Roll           : "+str(Roll)+"\n\n")
##################################################################################

import DraftGeomUtils
sel = FreeCADGui.Selection.getSelection()
vecteur = DraftGeomUtils.findMidpoint(sel[0].Shape.Edges[0])              # find Midpoint
App.Console.PrintMessage(vecteur)
Draft.makePoint(vecteur)
##################################################################################

Recherche d'un élément en donnant son Label

# Extract the coordinate X,Y,Z and Angle giving the label 
App.Console.PrintMessage("Base.x       : "+str(FreeCAD.ActiveDocument.getObjectsByLabel("Cylindre")[0].Placement.Base.x)+"\n")
App.Console.PrintMessage("Base.y       : "+str(FreeCAD.ActiveDocument.getObjectsByLabel("Cylindre")[0].Placement.Base.y)+"\n")
App.Console.PrintMessage("Base.z       : "+str(FreeCAD.ActiveDocument.getObjectsByLabel("Cylindre")[0].Placement.Base.z)+"\n")
App.Console.PrintMessage("Base.Angle   : "+str(FreeCAD.ActiveDocument.getObjectsByLabel("Cylindre")[0].Placement.Rotation.Angle)+"\n\n")
##################################################################################

PS: Les angles sont affichés en Radian, pour la convertir un radian en degrés faites :

  1. angle en Degrés vers Radians :
    • Angle en radian = pi * (angle en Degrés) / 180
    • Angle en radian = math.radians(angle en Degrés )
  2. angle en Radians vers Degrés :
    • Angle en Degrés = 180 * (angle en radian) / pi
    • Angle en Degrés = math.degrees(angle en radian)

Coordonnées Cartésiennes

Ce code affiche les coordonnées cartésiennes de l'objet sélectionné.

Changer la valeur "numberOfPoints" si vous voulez plus ou moins de précision

numberOfPoints = 100                                                         # Decomposition number (or precision you can change)
selectedEdge = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0].copy() # select one element
points  = selectedEdge.discretize(numberOfPoints)                            # discretize the element
i=0
for p in points:                                                             # list and display the coordinates
    i+=1
    print i, " X", p.x, " Y", p.y, " Z", p.z

Autre méthode d'affichage "Int" et "Float"

import Part
from FreeCAD import Base

c=Part.makeCylinder(2,10)        # create the circle
Part.show(c)                     # display the shape

# slice accepts two arguments:
#+ the normal of the cross section plane
#+ the distance from the origin to the cross section plane. Here you have to find a value so that the plane intersects your object
s=c.slice(Base.Vector(0,1,0),0)  # 

# here the result is a single wire
# depending on the source object this can be several wires
s=s[0]

# if you only need the vertexes of the shape you can use
v=[]
for i in s.Vertexes:
    v.append(i.Point)

# but you can also sub-sample the section to have a certain number of points (int) ...
p1=s.discretize(20)
ii=0
for i in p1:
    ii+=1
    print i                                              # Vector()
    print ii, ": X:", i.x, " Y:", i.y, " Z:", i.z        # Vector decode
Draft.makeWire(p1,closed=False,face=False,support=None)  # to see the difference accuracy (20)

## uncomment to use
#import Draft
#Draft.downgrade(App.ActiveDocument.ActiveObject,delete=True)  # first transform the DWire in Wire         "downgrade"
#Draft.downgrade(App.ActiveDocument.ActiveObject,delete=True)  # second split the Wire in single objects   "downgrade"
#
##Draft.upgrade(FreeCADGui.Selection.getSelection(),delete=True) # to attach lines contiguous SELECTED use "upgrade"


# ... or define a sampling distance (float)
p2=s.discretize(0.5)
ii=0
for i in p2:
    ii+=1
    print i                                              # Vector()
    print ii, ": X:", i.x, " Y:", i.y, " Z:", i.z        # Vector decode 
Draft.makeWire(p2,closed=False,face=False,support=None)  # to see the difference accuracy (0.5)

## uncomment to use
#import Draft
#Draft.downgrade(App.ActiveDocument.ActiveObject,delete=True)  # first transform the DWire in Wire         "downgrade"
#Draft.downgrade(App.ActiveDocument.ActiveObject,delete=True)  # second split the Wire in single objects   "downgrade"
#
##Draft.upgrade(FreeCADGui.Selection.getSelection(),delete=True) # to attach lines contiguous SELECTED use "upgrade"

Sélectionne tous les objets du document

import FreeCAD
for obj in FreeCAD.ActiveDocument.Objects:
    print obj.Name                                # display the object Name
    objName = obj.Name
    obj = App.ActiveDocument.getObject(objName)
    Gui.Selection.addSelection(obj)               # select the object

Sélectionner une face d'un objet

# select one face of the object
import FreeCAD, Draft
App=FreeCAD
nameObject = "Box"                             # objet
faceSelect = "Face3"                           # face to selection
loch=App.ActiveDocument.getObject(nameObject)  # objet
Gui.Selection.clearSelection()                 # clear all selection
Gui.Selection.addSelection(loch,faceSelect)    # select the face specified
s = Gui.Selection.getSelectionEx()
#Draft.makeFacebinder(s)                       #

Créer un objet dans la position de la camera

# create one object of the position to camera with "getCameraOrientation()"
# the object is still facing the screen
import Draft

plan = FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation()
plan = str(plan)
###### extract data
a    = ""
for i in plan:
    if i in ("0123456789e.- "):
        a+=i
a = a.strip(" ")
a = a.split(" ")
####### extract data

#print a
#print a[0]
#print a[1]
#print a[2]
#print a[3]

xP = float(a[0])
yP = float(a[1])
zP = float(a[2])
qP = float(a[3])

pl = FreeCAD.Placement()
pl.Rotation.Q = (xP,yP,zP,qP)         # rotation of object
pl.Base = FreeCAD.Vector(0.0,0.0,0.0) # here coordinates XYZ of Object
rec = Draft.makeRectangle(length=10.0,height=10.0,placement=pl,face=False,support=None) # create rectangle
#rec = Draft.makeCircle(radius=5,placement=pl,face=False,support=None)                   # create circle
print rec.Name

Ici le même code simplifié

import Draft
pl = FreeCAD.Placement()
pl.Rotation = FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation()
pl.Base = FreeCAD.Vector(0.0,0.0,0.0)
rec = Draft.makeRectangle(length=10.0,height=10.0,placement=pl,face=False,support=None)

Recherche du vecteur normal() sur une surface

Cet exemple montre comment trouver le vecteur normal() d'une face en cherchant les paramètres uv d'un point sur la surface et utiliser les paramètres u, v pour trouver le vecteur normal()

def normal(self):
   ss=FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0].copy()#SubObjects[0] is the edge list
   points  = ss.discretize(3.0)#points on the surface edge, 
             #this example just use points on the edge for example. 
             #However point is not necessary on the edge, it can be anywhere on the surface. 
   face=FreeCADGui.Selection.getSelectionEx()[0].SubObjects[1]
   for pp in points:
      pt=FreeCAD.Base.Vector(pp.x,pp.y,pp.z)#a point on the surface edge
      uv=face.Surface.parameter(pt)# find the surface u,v parameter of a point on the surface edge
      u=uv[0]
      v=uv[1]
      normal=face.normalAt(u,v)#use u,v to find normal vector
      print normal
      line=Part.makeLine((pp.x,pp.y,pp.z), (normal.x,normal.y,normal.z))
      Part.show(line)

Lire et écrire une Expression

import Draft
doc = FreeCAD.ActiveDocument

pl=FreeCAD.Placement()
pl.Rotation.Q=(0.0,-0.0,-0.0,1.0)
pl.Base=FreeCAD.Vector(0.0,0.0,0.0)
obj = Draft.makeCircle(radius=1.0,placement=pl,face=False,support=None)    # create circle

print obj.PropertiesList                                                   # properties disponible in the obj

doc.getObject(obj.Name).setExpression('Radius', u'2mm')                    # modify the radius
doc.getObject(obj.Name).setExpression('Placement.Base.x', u'10mm')         # modify the placement 
doc.getObject(obj.Name).setExpression('FirstAngle', u'90')                 # modify the first angle
doc.recompute()

expressions = obj.ExpressionEngine                                         # read the expression list
print expressions

for i in expressions:                                                      # list and separate the data expression
    print i[0]," = ",i[1]


Obtenir le vecteur normal d'une surface à partir d'un fichier STL

def getNormal(cb):
    if cb.getEvent().getState() == coin.SoButtonEvent.UP:
        pp = cb.getPickedPoint()
        if pp:
            vec = pp.getNormal().getValue()
            index = coin.cast(pp.getDetail(), "SoFaceDetail").getFaceIndex()
            print ("Normal: {}, Face index: {}".format(str(vec), index))

from pivy import coin
meth=Gui.ActiveDocument.ActiveView.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), getNormal)

Vous avez terminé et voulez quitter :

Gui.ActiveDocument.ActiveView.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), meth)
Arrow-left.svg Page précédente: Incorporer FreeCAD
Page suivante: Fonction Line drawing Arrow-right.svg
Arrow-left.svg Previous: Code snippets/fr Petits bouts de codes
Next: Dialog/fr Création d'une boite de dialogue creation Arrow-right.svg

Cette page montre comment construire facilement des fonctionnalités avancées en Python. Dans cet exercice, nous allons construire un nouvel outil qui trace une ligne. Cet outil peut alors être lié à une commande FreeCAD, et cette commande peut être appelée par n'importe quel élément de l'interface, comme un élément de menu ou un bouton de la barre d'outils.

Script principal

Première chose, nous allons écrire un script contenant toutes nos fonctionnalités, puis, nous allons l'enregistrer dans un fichier, et l'importer dans FreeCAD, alors toutes les classes et fonctions que nous écrirons seront accessibles à partir de FreeCAD.
Alors, lancez votre éditeur de texte favori, et entrez les lignes suivantes:

import FreeCADGui, Part
from pivy.coin import *
 
class line:
    """This class will create a line after the user clicked 2 points on the screen"""
    def __init__(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.stack = []
        self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getpoint)  

    def getpoint(self,event_cb):
        event = event_cb.getEvent()
        if event.getState() == SoMouseButtonEvent.DOWN:
            pos = event.getPosition()
            point = self.view.getPoint(pos[0],pos[1])
            self.stack.append(point)
            if len(self.stack) == 2:
                l = Part.Line(self.stack[0],self.stack[1])
                shape = l.toShape()
                Part.show(shape)
                self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.callback)

Explications détaillées

import Part, FreeCADGui
from pivy.coin import *

En Python, lorsque vous voulez utiliser les fonctions d'un autre module, vous avez besoin de l'importer.
Dans notre cas, nous aurons besoin de fonctions du Part Module, pour la création de la ligne, et du Gui module (FreeCADGui), pour accéder à la vue 3D.
Nous avons également besoin de tout le contenu de la bibliothèque de pièces, afin que nous puissions utiliser directement tous les objets comme coin, SoMouseButtonEvent (évènement souris) etc ..

class line:

Ici, nous définissons notre classe principale.
Mais pourquoi utilisons-nous une classe et non une fonction ? La raison en est que nous avons besoin que notre outil reste "vivant" en attendant que l'utilisateur clique sur l'écran.

  • Une fonction se termine lorsque sa tâche est terminée,
  • mais un objet, (une classe définit un objet) reste en vie (actif) jusqu'à ce qu'il soit détruit.
"""This class will create a line after the user clicked 2 points on the screen"""

En Python, toutes les classes ou fonctions peuvent avoir une documentation string(docstring).
Ceci est particulièrement utile dans FreeCAD, parce que quand vous appelez cette classe dans l'interpréteur, la description sera affichée comme une info-bulle.

def __init__(self):

Les classes Python doivent toujours contenir une fonction __ init__, qui est exécutée lorsque la classe est appelée pour créer un objet.
Donc, nous allons mettre ici tout ce que nous voulons produire lorsque notre outil de création de ligne commence (appelé).

self.view = FreeCADGui.ActiveDocument.ActiveView

Dans une classe, il est généralement souhaitable d'ajouter self. devant un nom de variable, de sorte que la variable sera facilement accessible à toutes les fonctions à l'intérieur et à l'extérieur de cette classe.
Ici, nous allons utiliser self.view pour accéder et manipuler la vue active 3D.

self.stack = []

Ici, nous créons une liste vide qui contiendra les points en 3D envoyés par la fonction GetPoint.

self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getpoint)

Ceci est un point important:
Du fait qu'il s'agit d'une scène coin3D, FreeCAD utilise les mécanismes de rappel de coin, qui permet à une fonction d'être appelée à chaque fois qu'un évènement se passe sur la scène.
Dans notre cas, nous créons un appel pour SoMouseButtonEvent, et nous le lions à la fonction GetPoint.
Maintenant, chaque fois qu'un bouton de la souris est enfoncé ou relâché, la fonction GetPoint sera exécutée.

Notez qu'il existe aussi une alternative à addEventCallbackPivy() appelée addEventCallback() qui dispense l'utilisation de pivy. Mais, pivy est un moyen très simple et efficace d'accéder à n'importe quelle partie de la scène coin, il est conseillé de l'utiliser autant que possible !

def getpoint(self,event_cb):

Maintenant, nous définissons la fonction GetPoint, qui sera exécutée quand un bouton de la souris sera pressé dans une vue 3D.
Cette fonction recevra un argument, que nous appellerons event_cb. A partir de l'appel de cet événement, nous pouvons accéder à l'objet événement, qui contient plusieurs éléments d'information (plus d'informations sur cette page).

if event.getState() == SoMouseButtonEvent.DOWN:

La fonction GetPoint sera appelée dès qu'un bouton de la souris est enfoncé ou relâché. Mais, nous ne voulons prendre un point 3D uniquement lorsqu'il est pressé (sinon, nous aurons deux points 3D très proches l'un de l'autre).
Donc, nous devons vérifier cela avec:

pos = event.getPosition()

Ici, nous avons les coordonnées du curseur de la souris sur l'écran

point = self.view.getPoint(pos[0],pos[1])

Cette fonction nous donne le vecteur (x, y, z) du point qui se trouve sur le plan focal, juste sous curseur de notre souris.
Si vous êtes dans la vue caméra, imaginez un rayon provenant de la caméra, en passant par le curseur de la souris, et en appuyant sur le plan focal.
C'est notre point dans la vue 3D. Si l'on est en mode orthogonal, le rayon est parallèle à la direction de la vue.

self.stack.append(point)

Nous ajoutons notre nouveau point sur la pile

if len(self.stack) == 2:

Avons nous tous les points ? si oui, alors nous allons tracer la ligne !

l = Part.Line(self.stack[0],self.stack[1])

Ici, nous utilisons la fonction line() de Part Module qui crée une ligne de deux vecteurs FreeCAD.
Tout ce que nous créons et modifions l'intérieur de Part Module, reste dans le Part Module.
Donc, jusqu'à présent, nous avons créé une Line Part. Il n'est lié à aucun objet de notre document actif, c'est pour cela que rien ne s'affiche sur l'écran.

shape = l.toShape()

Le document FreeCAD ne peut accepter que des formes à partir de Part Module. Les formes sont le type le plus courant de Part Module.
Donc, nous devons transformer notre ligne en une forme avant de l'ajouter au document.

Part.show(shape)

Le Part module a une fonction très pratique show() qui crée un nouvel objet dans le document et se lie a une forme.
Nous aurions aussi pu créer un nouvel objet dans le premier document, puis le lier à la forme manuellement.

self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.callback)

Maintenant, nous en avons fini avec notre ligne, nous allons supprimer le mécanisme de rappel, qui consomme de précieux cycles de CPU.

Tester et utiliser un script

Maintenant, nous allons enregistrer notre script dans un endroit où l'interpréteur Python de FreeCAD le trouvera.
Lors de l'importation de modules, l’interpréteur cherchera dans les endroits suivants:

  • les chemins d'installation de python,
  • le répertoire bin FreeCAD,
  • et tous les répertoires des modules FreeCAD.

Donc, la meilleure solution est de créer un nouveau répertoire dans le répertoire Mod de FreeCAD, et sauver votre script dans ce répertoire.
Par exemple, nous allons créer un répertoire "myscripts", et sauver notre script comme "exercise.py".

Maintenant, tout est prêt, nous allons commencer par créez un nouveau document FreeCAD, et, dans l'interpréteur Python, tapons:

import exercise

Si aucun message d'erreur n'apparaît, cela signifie que notre script exercise a été chargé.
Nous pouvons maintenant lister son contenu avec:

dir(exercise)

La commande dir() est une commande intégrée dans python, et lister le contenu d'un module. Nous pouvons voir que notre classe line() est là qui nous attend.
Maintenant, nous allons le tester:

exercise.line()

Puis, cliquez deux fois dans la vue 3D, et bingo, voici notre ligne ! Pour la faire de nouveau, tapez juste exercise.line(), encore et encore, et encore ... C'est bien, non?

Enregistrement du script dans l'interface de FreeCAD

Maintenant, pour que notre outil de création de ligne soit vraiment cool, il devrait y avoir un bouton sur l'interface, nous n'aurons donc pas besoin de taper tout ce code à chaque fois.
Le plus simple est de transformer notre nouveau répertoire myscripts dans un plan de travail FreeCAD. C'est facile, tout ce qui est nécessaire de faire, est de mettre un fichier appelé InitGui.py à l'intérieur de votre répertoire myscripts.
Le fichier InitGui.py contiendra les instructions pour créer un nouveau plan de travail, et s'ajoutera notre nouvel outil.
Sans oublier, que nous aurons aussi besoin de transformer un peu notre code exercise, de sorte que l'outil line() soit reconnu comme une commande FreeCAD officielle.
Commençons par faire un fichier InitGui.py, et écrivons le code suivant à l'intérieur:

class MyWorkbench (Workbench): 
   MenuText = "MyScripts"
   def Initialize(self):
       import exercise
       commandslist = ["line"]
       self.appendToolbar("My Scripts",commandslist)
Gui.addWorkbench(MyWorkbench())

Actuellement, vous devriez comprendre le script ci-dessus par vous-même, du moins, je pense:
Nous créons une nouvelle classe que nous appelons MyWorkbench, nous lui donnons un nom (MenuText), et nous définissons une fonction Initialize() qui sera exécutée quand le plan de travail sera chargé dans FreeCAD.
Dans cette fonction, nous chargeons le contenus de notre fichier 'exercise, et ajoutons les commandes FreeCAD trouvées dans une liste de commandes. Ensuite, nous faisons une barre d'outils appelée "Mes scripts" et nous attribuons notre liste des commandes.

Actuellement, bien sûr, nous n'avons qu'un seul outil, puisque notre liste de commandes ne contient qu'un seul élément. Puis, une fois que notre plan de travail est prêt, nous l'ajoutons à l'interface principale.

Mais, cela ne fonctionne toujours pas, car une commande FreeCAD doit être formatée d'une certaine façon pour travailler. Nous aurons donc besoin de transformer un peu notre outil ligne().
Notre nouveau script exercise.py va maintenant ressembler à ceci:

import FreeCADGui, Part
from pivy.coin import *
class line:
    """This class will create a line after the user clicked 2 points on the screen"""

    def Activated(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.stack = []
        self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getpoint) 
    def getpoint(self,event_cb):
        event = event_cb.getEvent()
        if event.getState() == SoMouseButtonEvent.DOWN:
            pos = event.getPosition()
            point = self.view.getPoint(pos[0],pos[1])
            self.stack.append(point)
            if len(self.stack) == 2:
                l = Part.Line(self.stack[0],self.stack[1])
                shape = l.toShape()
                Part.show(shape)
                self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.callback)
    def GetResources(self): 
        return {'Pixmap' : 'path_to_an_icon/line_icon.png', 'MenuText': 'Line', 'ToolTip': 'Creates a line by clicking 2 points on the screen'} 
FreeCADGui.addCommand('line', line())

Qu'avons fait ici ? nous avons transformé notre fonction __ init__ () en une fonction Activated(), parce que lorsque les commandes sont exécutées dans FreeCAD, il exécute automatiquement la fonction Activated().
Nous avons également ajouté une fonction GetResources(), qui informe FreeCAD où se trouve l'icône de l'outil, le nom et l'info-bulle de l'outil.
Toute image, jpg, png ou svg peut être utilisé comme icône, il peut être de n'importe quelle taille, mais il est préférable d'utiliser une taille standard qui est proche de l'aspect final, comme 16x16, 24x24 ou 32x32.
Puis, nous ajoutons notre class line() comme une commande officielle de FreeCAD avec la méthode addCommand().

Ça y est, nous avons juste besoin de redémarrer FreeCAD et nous aurons un plan de travail agréable avec notre nouvel outil ligne tout neuf !

Vous voulez en savoir plus ?

Si vous avez aimé cet "exercise", pourquoi ne pas essayer d'améliorer ce petit outil ? Il y a beaucoup de choses à faire, comme par exemple:

  • Ajouter des Commentaires utilisateur: jusqu'à présent nous avons fait un outil très dépouillé, l'utilisateur peut être un peu perdu lors de son utilisation. Vous pouvez ajouter vos commentaires, en guidant l'utilisateur. Par exemple, vous pourriez émettre des messages à la console FreeCAD. "Jetez" un oeil dans le module FreeCAD.Console
  • Ajouter la possibilité d'entrer les coordonnées 3D manuellement . Regardez les fonctions Python input(), par exemple
  • Ajouter la possibilité d'ajouter plus de 2 points
  • Ajouter des événements pour d'autres fonctions: Maintenant que nous venons d'apprendre les événements de bouton de souris, si nous souhaitons également faire quelque chose quand la souris est déplacée, comme par exemple l'affichage des coordonnées actuelles?
  • Donnez un nom à l'objet créé et bien d'autres choses

N'hésitez pas de commenter vos idées ou questions sur le forum !

Arrow-left.svg Page précédente: Code snippets
Page suivante: Dialog creation Arrow-right.svg
Arrow-left.svg Previous: Line drawing function/fr Fonction de dessin de lignes
Next: Licence/fr Licence Arrow-right.svg

Dans cette page nous allons vous montrer comment construire une simple boîte de dialogue avec Qt Designer, Qt Designer, est l'outil officiel de Qt pour la conception d'interfaces (Gui), puis de le convertir en code Python, et l'utiliser à l'intérieur de FreeCAD.
Je vais supposer, que pour l'exemple, vous savez déjà comment modifier et exécuter un script Python, et que vous pouvez travailler avec des choses simples dans une fenêtre de terminal tel que se déplacer, etc . . Bien sûr, vous devez également avoir installé PySide.

Construire une boîte de dialogue

Dans les applications de CAO, bien concevoir une UI (interface utilisateur) est très important.
Tout ce que l'utilisateur fera, se fera à travers un outil de l'interface: la lecture des boîtes de dialogue, appuyer sur les boutons, le choix entre les icônes, etc . .
Il est donc très important de réfléchir attentivement à la conception de votre boîte de dialogue, comment vous voulez que l'utilisateur se comporter avec la boîte, et comment sera le flux de travail de votre action.

Il y a une deux choses à savoir lors de la conception de l'interface:

  • Boîtes de dialogue modales ou non-modale :
    • Une boîte de dialogue modale apparaît en face de votre écran et, arrête l'action de la fenêtre principale, forçant l'utilisateur à répondre à la boîte de dialogue.
    • Une boîte de dialogue non modale ne vous empêche pas de travailler sur la Fenêtre principale, vous pouvez travailler sur les deux fenêtres.

Dans certains cas, le premier est préférable, dans d'autres cas non.

  • Identifier ce qui est nécessaire et ce qui est optionnel:
    • Assurez-vous que l'utilisateur sait ce qu'il doit faire. Prévoyez des étiquettes avec des descriptions appropriées, des info-bulles d'utilisation, etc . .
  • Séparez les commandes à partir de paramètres:
    • Cela se fait habituellement avec des boutons et des champs de saisie de texte.
    • L'utilisateur sait que cliquer sur un bouton va produire une action, tout en changeant une valeur dans un champ de texte, va changer un paramètre quelque part. Cependant, aujourd'hui, les utilisateurs savent généralement bien ce qu'est un bouton, ce qu'est un champ de saisie, etc . . .

La boîte à outils de l'interface Qt que nous utilisons, est une boîte à outils state-of-the-art (interface graphique avancée), et nous n'aurons pas beaucoup d'inquiétudes pour rendre les choses claires, car elles sont déjà très claires par elles-mêmes.

Donc, maintenant que nous avons bien défini ce que nous ferons, il est temps d'ouvrir Qt Designer.
Nous allons concevoir très facilement une simple boîte de dialogue, comme ceci:

Qttestdialog.jpg

Nous allons ensuite utiliser cette boîte de dialogue dans FreeCAD pour produire une belle surface plane rectangulaire.
Vous ne trouverez peut-être pas très utile de produire de beaux plans rectangulaires, mais il sera facile de le changer plus tard et de faire des choses plus complexes.
Lorsque vous l'ouvrez, Qt Designer ressemble à ceci:

Qtdesigner-screenshot.jpg

Il est très simple à utiliser. Sur la barre de gauche vous avez des éléments qui peuvent être glissés sur votre widget (tous les outils). Sur le côté droit vous avez des panneaux d'affichage de propriétés de toutes sortes, des propriétés de certains éléments modifiables.
Donc, commencez par créer un nouveau widget. Sélectionnez "Dialog without buttons", car nous ne voulons pas de boutons par défaut Ok/Annuler. Ensuite, faites glisser sur votre widget 3 labels, un pour le titre, un pour l'écriture "Height" (Hauteur) et l'autre pour l'écriture "Width" (Largeur).

Les labels (étiquettes) sont de simples textes qui apparaissent sur ​​votre widget, il servent a informer l'utilisateur.
Si vous sélectionnez un label, sur le côté droit apparaîssent plusieurs propriétés que vous pouvez modifier, comme le style de police, taille, etc . . .

Ensuite, ajoutez 2 LineEdits , qui sont des champs texte que l'utilisateur peut remplir, un pour la hauteur et l'autre pour la largeur.

Ici aussi, nous pouvons modifier les propriétés. Par exemple, pourquoi ne pas définir une valeur par défaut ? Par exemple 1,00 pour chacun d'eux.
De cette façon, lorsque l'utilisateur verra la boîte de dialogue, les deux valeurs seront déjà remplies et si les valeurs conviennent, il peut directement appuyer sur le bouton, gain de temps précieux.
Ensuite, ajoutez un PushButton , qui est le bouton, que l'utilisateur devra appuyer après avoir rempli les 2 champs.

Notez que j'ai choisi ici des contrôles très simples, mais Qt a beaucoup plus d'options, par exemple, vous pouvez utiliser spinbox au lieu de LineEdits, etc ... Regardez tout ce qui est disponible, vous aurez sûrement d'autres idées.

C'est à peu près tout ce que nous devons faire dans Qt Designer.
Une dernière chose, nous allons renommer tous nos éléments avec des noms faciles, de sorte qu'il sera plus facile de les identifier dans nos scripts:

Qtpropeditor.jpg

Conversion de notre boîte de dialogue en code Python avec "pyuic"

Maintenant, nous allons sauver notre widget quelque part. Il sera sauvegardé dans un fichier .Ui, que nous allons facilement convertir en script Python avec pyuic.
Dans windows, le programme est livré avec pyuic pyqt (à vérifier), sur Linux, vous aurez probablement besoin de l'installer séparément à partir de votre gestionnaire de paquets (sur debian-systèmes basés sur, il fait partie du paquet pyqt4-dev-tools).
Pour faire la conversion, vous aurez besoin d'ouvrir une fenêtre de terminal (ou une fenêtre d'invite de commandes), accédez à l'endroit où vous avez enregistré votre fichier ui :

pyuic mywidget.ui > mywidget.py

Dans Windows pyuic.py est présent dans "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" Créez un fichier batch "compQt4.bat" pour automatiser la tâche:

@"C:\Python27\python" "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" -x %1.ui > %1.py

Dans la console Dos tapez sans extension

compQt4 myUiFile

Dans Linux : à venir

Depuis la version 0.13, FreeCAD migre progressivement de PyQt à PySide (Choisissez votre installateur PySide suivant votre système building PySide),

pyside-uic mywidget.ui -o mywidget.py

Dans Windows le fichier uic.py se trouve dans "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" Créez un fichier batch "compSide.bat"

@"C:\Python27\python" "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" %1.ui > %1.py

Dans la console Python tapez sans extension:

compSide myUiFile

Dans Linux: faites

Sur certains systèmes, le programme est appelé pyuic4 lieu de pyuic. Il sert uniquement de convertisseur du fichier .ui pour l'utiliser dans un script Python. Si nous ouvrons le fichier mywidget.py, son contenu est très facile à comprendre:

from PySide import QtCore, QtGui

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(187, 178)
        self.title = QtGui.QLabel(Dialog)
        self.title.setGeometry(QtCore.QRect(10, 10, 271, 16))
        self.title.setObjectName("title")
        self.label_width = QtGui.QLabel(Dialog)
        ...

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

   def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
        self.title.setText(QtGui.QApplication.translate("Dialog", "Plane-O-Matic", None, QtGui.QApplication.UnicodeUTF8))
        ...

Comme vous voyez, il a une structure très simple: une classe nommée Ui_Dialog est créé, qui stocke les éléments de l'interface de notre widget.
Cette classe dispose de deux méthodes, une pour la mise en place du widget, et l'autre pour traduire son contenu, qui fait partie du mécanisme général de Qt pour la traduction des éléments d'interface. La méthode de configuration, crée simplement, un par un, les widgets tels que nous les avons définis dans Qt Designer, et définit leurs options aussi comme nous avons décidé plus tôt. Puis, toute l'interface est traduite, et enfin, les "slots" se connectent (nous en reparlerons plus tard).

Nous pouvons maintenant créer un nouveau widget, et utiliser cette classe pour créer son interface. Nous pouvons déjà voir notre widget en action, en mettant notre fichier mywidget.py dans un endroit où FreeCAD la trouvera (dans le répertoire bin FreeCAD, ou dans l'un des sous-répertoires Mod), et, dans l'interpréteur Python de FreeCAD, faisons:

from PySide import QtGui
import mywidget
d = QtGui.QWidget()
d.ui = mywidget.Ui_Dialog()
d.ui.setupUi(d)
d.show()

Et notre boîte de dialogue apparaîtra! Notez que notre interpréteur Python fonctionne toujours, nous avons une boîte de dialogue non modale.
Donc, pour la fermer, nous pouvons (à part cliquer sur son icône, bien sûr) faire:

d.hide()

Faire quelque chose avec notre boîte de dialogue

Maintenant que nous pouvons afficher et masquer notre boîte de dialogue, nous avons juste besoin d'ajouter la dernière partie, pour en faire quelque chose !
Si vous explorez un peu Qt Designer, vous découvrirez rapidement toute une section appelée "signaux et slots".
Fondamentalement, cela fonctionne comme ceci, ce sont les éléments sur vos widgets (dans la terminologie de Qt, ces éléments sont eux-mêmes des widgets) qui peuvent envoyer des signaux.

Ces signaux diffèrent selon le type de widget. Par exemple, un bouton peut envoyer un signal quand il est pressé et quand il est relâché.
Ces signaux peuvent être connectés à des créneaux, qui peuvent être des fonctionnalités spéciales d'autres widgets (par exemple une boîte de dialogue a un bouton "Fermer" sur lequel vous pouvez connecter le signal à partir d'un autre bouton "Fermer"), ou, peuvent être des fonctions personnalisées.
La documentation de référence PyQt répertorie tous les widgets Qt, ce qu'ils peuvent faire, ce qu'ils signalent, ce qu'ils peuvent envoyer, etc . . .

Ce que nous allons faire ici, c'est créer une nouvelle fonction qui permettra de créer une surface plane basée sur la hauteur et la largeur, et, relier cette fonction au bouton "Create!".
Donc, nous allons commencer par importer nos modules FreeCAD, en mettant la ligne suivante en haut du script, où nous importons déjà QtCore et QtGui:

import FreeCAD, Part

Ensuite, nous allons ajouter une nouvelle fonction à notre classe Ui_Dialog:

def createPlane(self):
    try:
        # first we check if valid numbers have been entered
        w = float(self.width.text())
        h = float(self.height.text())
    except ValueError:
        print("Error! Width and Height values must be valid numbers!")
    else:
        # create a face from 4 points
        p1 = FreeCAD.Vector(0,0,0)
        p2 = FreeCAD.Vector(w,0,0)
        p3 = FreeCAD.Vector(w,h,0)
        p4 = FreeCAD.Vector(0,h,0)
        pointslist = [p1,p2,p3,p4,p1]
        mywire = Part.makePolygon(pointslist)
        myface = Part.Face(mywire)
        Part.show(myface)
        self.hide()

Puis, nous avons besoin d'informer Qt pour qu'il se connecte sur le bouton de la fonction, en plaçant la ligne suivante juste avant QtCore.QMetaObject.connectSlotsByName(Dialog):

QtCore.QObject.connect(self.create,QtCore.SIGNAL("pressed()"),self.createPlane)

Il s'agit, comme vous le voyez, de relier le signal du bouton enfoncé de l'objet a créer ("Create!" Bouton), à un emplacement nommé createPlane, dont nous venons de définir.
Ça y est ! Maintenant, la touche finale, nous pouvons ajouter une petite fonction, pour créer la boîte de dialogue, elle sera plus facile a appeler.
En dehors de la classe Ui_Dialog class, nous allons ajouter le code suivant:

class plane():
   def __init__(self):
       self.d = QtGui.QWidget()
       self.ui = Ui_Dialog()
       self.ui.setupUi(self.d)
       self.d.show()

(Rappel sur Python : la méthode __init__ est une classe qui s'exécute automatiquement chaque fois qu'un nouvel objet est créé ! )

Puis, à partir de FreeCAD, nous avons seulement besoin de faire:

import mywidget
myDialog = mywidget.plane()

Voilà, c'est tout ...
Maintenant, vous pouvez essayer toutes sortes de choses, comme par exemple l'insertion de votre widget dans l'interface FreeCAD (voir la page Code snippets), ou, faire des outils personnalisés beaucoup plus avancés, en utilisant d'autres éléments dans votre widget.

Le script complet

Ceci est le script de référence complet:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'mywidget.ui'
#
# Created: Mon Jun  1 19:09:10 2009
#      by: PyQt4 UI code generator 4.4.4
# Modified for PySide 16:02:2015 
# WARNING! All changes made in this file will be lost!

from PySide import QtCore, QtGui
import FreeCAD, Part 

class Ui_Dialog(object):
   def setupUi(self, Dialog):
       Dialog.setObjectName("Dialog")
       Dialog.resize(187, 178)
       self.title = QtGui.QLabel(Dialog)
       self.title.setGeometry(QtCore.QRect(10, 10, 271, 16))
       self.title.setObjectName("title")
       self.label_width = QtGui.QLabel(Dialog)
       self.label_width.setGeometry(QtCore.QRect(10, 50, 57, 16))
       self.label_width.setObjectName("label_width")
       self.label_height = QtGui.QLabel(Dialog)
       self.label_height.setGeometry(QtCore.QRect(10, 90, 57, 16))
       self.label_height.setObjectName("label_height")
       self.width = QtGui.QLineEdit(Dialog)
       self.width.setGeometry(QtCore.QRect(60, 40, 111, 26))
       self.width.setObjectName("width")
       self.height = QtGui.QLineEdit(Dialog)
       self.height.setGeometry(QtCore.QRect(60, 80, 111, 26))
       self.height.setObjectName("height")
       self.create = QtGui.QPushButton(Dialog)
       self.create.setGeometry(QtCore.QRect(50, 140, 83, 26))
       self.create.setObjectName("create")

       self.retranslateUi(Dialog)
       QtCore.QObject.connect(self.create,QtCore.SIGNAL("pressed()"),self.createPlane)
       QtCore.QMetaObject.connectSlotsByName(Dialog)

   def retranslateUi(self, Dialog):
       Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
       self.title.setText(QtGui.QApplication.translate("Dialog", "Plane-O-Matic", None, QtGui.QApplication.UnicodeUTF8))
       self.label_width.setText(QtGui.QApplication.translate("Dialog", "Width", None, QtGui.QApplication.UnicodeUTF8))
       self.label_height.setText(QtGui.QApplication.translate("Dialog", "Height", None, QtGui.QApplication.UnicodeUTF8))
       self.create.setText(QtGui.QApplication.translate("Dialog", "Create!", None, QtGui.QApplication.UnicodeUTF8))

   def createPlane(self):
       try:
           # first we check if valid numbers have been entered
           w = float(self.width.text())
           h = float(self.height.text())
       except ValueError:
           print("Error! Width and Height values must be valid numbers!")
       else:
           # create a face from 4 points
           p1 = FreeCAD.Vector(0,0,0)
           p2 = FreeCAD.Vector(w,0,0)
           p3 = FreeCAD.Vector(w,h,0)
           p4 = FreeCAD.Vector(0,h,0)
           pointslist = [p1,p2,p3,p4,p1]
           mywire = Part.makePolygon(pointslist)
           myface = Part.Face(mywire)
           Part.show(myface)

class plane():
   def __init__(self):
       self.d = QtGui.QWidget()
       self.ui = Ui_Dialog()
       self.ui.setupUi(self.d)
       self.d.show()

Création d'une boîte de dialogue avec ses boutons

Méthode 1

Un exemple d'une boîte de dialogue complète avec ses connections.

# -*- coding: utf-8 -*-
# Create by flachyjoe

from PySide import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)


class Ui_MainWindow(object):

     def __init__(self, MainWindow):
        self.window = MainWindow

        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(400, 300)
        self.centralWidget = QtGui.QWidget(MainWindow)
        self.centralWidget.setObjectName(_fromUtf8("centralWidget"))

        self.pushButton = QtGui.QPushButton(self.centralWidget)
        self.pushButton.setGeometry(QtCore.QRect(30, 170, 93, 28))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.on_pushButton_clicked) #connection pushButton

        self.lineEdit = QtGui.QLineEdit(self.centralWidget)
        self.lineEdit.setGeometry(QtCore.QRect(30, 40, 211, 22))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.lineEdit.returnPressed.connect(self.on_lineEdit_clicked) #connection lineEdit

        self.checkBox = QtGui.QCheckBox(self.centralWidget)
        self.checkBox.setGeometry(QtCore.QRect(30, 90, 81, 20))
        self.checkBox.setChecked(True)
        self.checkBox.setObjectName(_fromUtf8("checkBoxON"))
        self.checkBox.clicked.connect(self.on_checkBox_clicked) #connection checkBox

        self.radioButton = QtGui.QRadioButton(self.centralWidget)
        self.radioButton.setGeometry(QtCore.QRect(30, 130, 95, 20))
        self.radioButton.setObjectName(_fromUtf8("radioButton"))
        self.radioButton.clicked.connect(self.on_radioButton_clicked) #connection radioButton

        MainWindow.setCentralWidget(self.centralWidget)

        self.menuBar = QtGui.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 26))
        self.menuBar.setObjectName(_fromUtf8("menuBar"))
        MainWindow.setMenuBar(self.menuBar)

        self.mainToolBar = QtGui.QToolBar(MainWindow)
        self.mainToolBar.setObjectName(_fromUtf8("mainToolBar"))
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)

        self.statusBar = QtGui.QStatusBar(MainWindow)
        self.statusBar.setObjectName(_fromUtf8("statusBar"))
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)

     def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.pushButton.setText(_translate("MainWindow", "OK", None))
        self.lineEdit.setText(_translate("MainWindow", "tyty", None))
        self.checkBox.setText(_translate("MainWindow", "CheckBox", None))
        self.radioButton.setText(_translate("MainWindow", "RadioButton", None))

     def on_checkBox_clicked(self):
        if self.checkBox.checkState()==0:
            App.Console.PrintMessage(str(self.checkBox.checkState())+"  CheckBox KO\r\n")
        else:     
            App.Console.PrintMessage(str(self.checkBox.checkState())+" CheckBox OK\r\n")
#        App.Console.PrintMessage(str(self.lineEdit.setText("tititi"))+" LineEdit\r\n") #write text to the lineEdit window !
#        str(self.lineEdit.setText("tititi")) #écrit le texte dans la fenêtre lineEdit
        App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit\r\n")

     def on_radioButton_clicked(self):
        if self.radioButton.isChecked():
             App.Console.PrintMessage(str(self.radioButton.isChecked())+" Radio OK\r\n")
        else:
             App.Console.PrintMessage(str(self.radioButton.isChecked())+"  Radio KO\r\n")

     def on_lineEdit_clicked(self):
#        if self.lineEdit.textChanged():
             App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit Display\r\n")

     def on_pushButton_clicked(self):
        App.Console.PrintMessage("Terminé\r\n")
        self.window.hide()

MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow(MainWindow)
MainWindow.show()

Ici la même fenêtre mais avec un icône sur chaque bouton.

Téléchargez les icônes associés (Faites clic droit sur l'icône "Enregistrer l'image sous ...)"

Icone01.png Icone02.png Icone03.png

# -*- coding: utf-8 -*-

from PySide import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)


class Ui_MainWindow(object):

     def __init__(self, MainWindow):
        self.window = MainWindow
        path = FreeCAD.ConfigGet("UserAppData")
#        path = FreeCAD.ConfigGet("AppHomePath")

        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(400, 300)
        self.centralWidget = QtGui.QWidget(MainWindow)
        self.centralWidget.setObjectName(_fromUtf8("centralWidget"))

        self.pushButton = QtGui.QPushButton(self.centralWidget)
        self.pushButton.setGeometry(QtCore.QRect(30, 170, 93, 28))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.on_pushButton_clicked) #connection pushButton

        self.lineEdit = QtGui.QLineEdit(self.centralWidget)
        self.lineEdit.setGeometry(QtCore.QRect(30, 40, 211, 22))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.lineEdit.returnPressed.connect(self.on_lineEdit_clicked) #connection lineEdit

        self.checkBox = QtGui.QCheckBox(self.centralWidget)
        self.checkBox.setGeometry(QtCore.QRect(30, 90, 100, 20))
        self.checkBox.setChecked(True)
        self.checkBox.setObjectName(_fromUtf8("checkBoxON"))
        self.checkBox.clicked.connect(self.on_checkBox_clicked) #connection checkBox

        self.radioButton = QtGui.QRadioButton(self.centralWidget)
        self.radioButton.setGeometry(QtCore.QRect(30, 130, 95, 20))
        self.radioButton.setObjectName(_fromUtf8("radioButton"))
        self.radioButton.clicked.connect(self.on_radioButton_clicked) #connection radioButton

        MainWindow.setCentralWidget(self.centralWidget)

        self.menuBar = QtGui.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 26))
        self.menuBar.setObjectName(_fromUtf8("menuBar"))
        MainWindow.setMenuBar(self.menuBar)

        self.mainToolBar = QtGui.QToolBar(MainWindow)
        self.mainToolBar.setObjectName(_fromUtf8("mainToolBar"))
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)

        self.statusBar = QtGui.QStatusBar(MainWindow)
        self.statusBar.setObjectName(_fromUtf8("statusBar"))
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)

        # Affiche un icone sur le bouton PushButton
        # self.image_01 = "C:\Program Files\FreeCAD0.13\Icone01.png" # adapt the icon name
        self.image_01 = path+"Icone01.png" # adapt the name of the icon
        icon01 = QtGui.QIcon() 
        icon01.addPixmap(QtGui.QPixmap(self.image_01),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon01) 
        self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button

        # Affiche un icone sur le bouton RadioButton 
        # self.image_02 = "C:\Program Files\FreeCAD0.13\Icone02.png" # adapt the name of the icon
        self.image_02 = path+"Icone02.png" # adapter le nom de l'icone
        icon02 = QtGui.QIcon() 
        icon02.addPixmap(QtGui.QPixmap(self.image_02),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.radioButton.setIcon(icon02) 
        # self.radioButton.setLayoutDirection(QtCore.Qt.RightToLeft) #  This command reverses the direction of the button

        # Affiche un icone sur le bouton CheckBox 
        # self.image_03 = "C:\Program Files\FreeCAD0.13\Icone03.png" # the name of the icon
        self.image_03 = path+"Icone03.png" # adapter le nom de l'icone
        icon03 = QtGui.QIcon() 
        icon03.addPixmap(QtGui.QPixmap(self.image_03),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.checkBox.setIcon(icon03) 
        # self.checkBox.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button


     def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "FreeCAD", None))
        self.pushButton.setText(_translate("MainWindow", "OK", None))
        self.lineEdit.setText(_translate("MainWindow", "tyty", None))
        self.checkBox.setText(_translate("MainWindow", "CheckBox", None))
        self.radioButton.setText(_translate("MainWindow", "RadioButton", None))

     def on_checkBox_clicked(self):
        if self.checkBox.checkState()==0:
            App.Console.PrintMessage(str(self.checkBox.checkState())+"  CheckBox KO\r\n")
        else:     
            App.Console.PrintMessage(str(self.checkBox.checkState())+" CheckBox OK\r\n")
           # App.Console.PrintMessage(str(self.lineEdit.setText("tititi"))+" LineEdit\r\n") # write text to the lineEdit window !
           # str(self.lineEdit.setText("tititi")) #écrit le texte dans la fenêtre lineEdit
        App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit\r\n")

     def on_radioButton_clicked(self):
        if self.radioButton.isChecked():
             App.Console.PrintMessage(str(self.radioButton.isChecked())+" Radio OK\r\n")
        else:
             App.Console.PrintMessage(str(self.radioButton.isChecked())+"  Radio KO\r\n")

     def on_lineEdit_clicked(self):
          # if self.lineEdit.textChanged():
          App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit Display\r\n")

     def on_pushButton_clicked(self):
        App.Console.PrintMessage("Terminé\r\n")
        self.window.hide()

MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow(MainWindow)
MainWindow.show()

Ici le code pour afficher l'icône sur le pushButton, modifiez le nom pour un autre bouton, (radioButton, checkBox) ainsi que le chemin de l'icône.

# Affiche un icône sur le bouton PushButton
        # self.image_01 = "C:\Program Files\FreeCAD0.13\icone01.png" # the name of the icon
        self.image_01 = path+"icone01.png" # the name of the icon
        icon01 = QtGui.QIcon() 
        icon01.addPixmap(QtGui.QPixmap(self.image_01),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon01) 
        self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button

La commande UserAppData donne le chemin utilisateur AppHomePath donne le chemin d'installation de FreeCAD

#        path = FreeCAD.ConfigGet("UserAppData")
        path = FreeCAD.ConfigGet("AppHomePath")

Cette commande inverse le sens horizontal du bouton, droite à gauche

self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button

Méthode 2

Une autre méthode pour afficher une fenêtre, ici en créant un fichier QtForm.py qui renferme l'entête du programme (module appelé avec import QtForm), et d'un deuxième module qui renferme le code de la fenêtre tous ces accessoires, et votre code (le module appelant).

Cette méthode nécessite 2 fichiers distincts, mais permet de raccourcir votre programme, en utilisant le fichier QtForm.py en import. Il faut alors distribuer les deux fichiers ensemble, ils sont indissociables.

Le fichier QtForm.py

# -*- coding: utf-8 -*-
# Create by flachyjoe
from PySide import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
   def _fromUtf8(s):
      return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
      return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
   def _translate(context, text, disambig):
      return QtGui.QApplication.translate(context, text, disambig)

class Form(object):
   def __init__(self, title, width, height):
      self.window = QtGui.QMainWindow()
      self.title=title
      self.window.setObjectName(_fromUtf8(title))
      self.window.setWindowTitle(_translate(self.title, self.title, None))
      self.window.resize(width, height)

   def show(self):
      self.createUI()
      self.retranslateUI()
      self.window.show()
   
   def setText(self, control, text):
      control.setText(_translate(self.title, text, None))

Le fichier appelant, qui contient la fenêtre et votre code.

Le fichier mon_fichier.py

Les connections sont à faire, un bon exercice.

# -*- coding: utf-8 -*-
# Create by flachyjoe
from PySide import QtCore, QtGui
import QtForm

class myForm(QtForm.Form):
   def createUI(self):
      self.centralWidget = QtGui.QWidget(self.window)
      self.window.setCentralWidget(self.centralWidget)
      
      self.pushButton = QtGui.QPushButton(self.centralWidget)
      self.pushButton.setGeometry(QtCore.QRect(30, 170, 93, 28))
      self.pushButton.clicked.connect(self.on_pushButton_clicked)
      
      self.lineEdit = QtGui.QLineEdit(self.centralWidget)
      self.lineEdit.setGeometry(QtCore.QRect(30, 40, 211, 22))
      
      self.checkBox = QtGui.QCheckBox(self.centralWidget)
      self.checkBox.setGeometry(QtCore.QRect(30, 90, 81, 20))
      self.checkBox.setChecked(True)
      
      self.radioButton = QtGui.QRadioButton(self.centralWidget)
      self.radioButton.setGeometry(QtCore.QRect(30, 130, 95, 20))
   
   def retranslateUI(self):
      self.setText(self.pushButton, "Fermer")
      self.setText(self.lineEdit, "essais de texte")
      self.setText(self.checkBox, "CheckBox")
      self.setText(self.radioButton, "RadioButton")
   
   def on_pushButton_clicked(self):
      self.window.hide()

myWindow=myForm("Fenetre de test",400,300)
myWindow.show()

Autre exemple


Sont traités :

  1. icon for window : l'icône affiché sur le coin supérieur gauche de la fenêtre principale
  2. horizontalSlider : horizontal slider sa connexion et extraction / affectation de données
  3. progressBar horizontal : progress bar horizontal sa connexion et extraction / affectation de données
  4. verticalSlider : vertical slider sa connexion et extraction / affectation de données
  5. progressBar vertical : progress bar verticale sa connexion et extraction / affectation de données
  6. lineEdit : line edit sa connexion et extraction / affectation de données
  7. lineEdit :
  8. doubleSpinBox : double spinbox sa connexion et extraction / affectation de données
  9. doubleSpinBox :
  10. doubleSpinBox :
  11. button : button et sa connexion
  12. button :
  13. radioButton : radio button avec icône sa connexion checked
  14. checkBox : checkbox with avec icône sa connexion checked and unchecked
  15. textEdit : text edit sa connexion et extraction / affectation de données
  16. graphicsView : graphic view avec 2 images et la méthode pour changer d'image

La page de code et les icônes Qt Exemples

Icônes personnalisés dans la Vue combinée

Ici un exemple de création d'un objet avec quelques propriétés associé à un icône personnel.

Téléchargez l'icône exemple et placez le dans votre répertoire de macro icône Exemple pour la macro.

Trois méthodes d'affectation d'un icône à un objet sont traitées, un icône fichier au format .png présent sur le disque, un icône sauvé au format .xpm inclus dans la macro elle même et un icône disponible dans les ressources FreeCAD.

icon personalised


import PySide
import FreeCAD, FreeCADGui, Part
from pivy import coin
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
import Draft

global path
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")# macro path in FreeCAD preferences
path = param.GetString("MacroPath","") + "/"                        # macro path
path = path.replace("\\","/")                                       # convert the "\" to "/"


class IconViewProviderToFile:                                       # Class ViewProvider create Property view of object
    def __init__( self, obj, icon):
        self.icone = icon
        
    def getIcon(self):                                              # GetIcon
        return self.icone
        
    def attach(self, obj):                                          # Property view of object
        self.modes = []
        self.modes.append("Flat Lines")
        self.modes.append("Shaded")
        self.modes.append("Wireframe")
        self.modes.append("Points")
        obj.addDisplayMode( coin.SoGroup(),"Flat Lines" )           # Display Mode
        obj.addDisplayMode( coin.SoGroup(),"Shaded" )
        obj.addDisplayMode( coin.SoGroup(),"Wireframe" )
        obj.addDisplayMode( coin.SoGroup(),"Points" )
        return self.modes

    def getDisplayModes(self,obj):
        return self.modes

#####################################################
########## Example with icon to file # begin ########
#####################################################

object1 = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Icon_In_File_Disk")                                     # create your object
object1.addProperty("App::PropertyString","Identity", "ExampleTitle0", "Identity of object").Identity = "FCSpring"        # Identity of object
object1.addProperty("App::PropertyFloat" ,"Pitch",    "ExampleTitle0", "Pitch betwen 2 heads").Pitch  = 2.0               # other Property Data
object1.addProperty("App::PropertyBool"  ,"View",     "ExampleTitle1", "Hello world").View            = True              # ...
object1.addProperty("App::PropertyColor" ,"LineColor","ExampleTitle2", "Color to choice").LineColor   = (0.13,0.15,0.37)  # ...
#...other Property Data
#...other Property Data
#
object1.ViewObject.Proxy = IconViewProviderToFile( object1, path + "FreeCADIco.png")                                      # icon download to file
App.ActiveDocument.recompute()
#
#__Detail__:
# FreeCAD.ActiveDocument.addObject( = create now object personalized
# "App::FeaturePython",             = object as FeaturePython
# "Icon_In_File_Disk")              = internal name of your object
#
#
# "App::PropertyString",    = type of Property , availlable : PropertyString, PropertyFloat, PropertyBool, PropertyColor
# "Identity",               = name of the feature
# "ExampleTitle0",          = title of the "section"
# "Identity of object")     = tooltip displayed on mouse
# .Identity                 = variable (same of name of the feature)
# object1.ViewObject.Proxy  = create the view object and gives the icon
#
########## example with icon to file end



#####################################################
########## Example with icon in macro # begin #######
#####################################################

def setIconInMacro(self):        # def contener the icon in format .xpm
    # File format XPM created by Gimp "https://www.gimp.org/"
    # Choice palette Tango
    # Create your masterwork ...
    # For export the image in XPM format
    #     Menu File > Export as > .xpm
    # (For convert image true color in Tango color palette : 
    #     Menu Image > Mode > Indexed ... > Use custom palette > Tango Icon Theme > Convert)
    return """
            /* XPM */
            static char * XPM[] = {
            "22 24 5 1",
            " 	c None",
            ".	c #CE5C00",
            "+	c #EDD400",
            "@	c #F57900",
            "#	c #8F5902",
            "                      ",
            "                      ",
            "  ....                ",
            "  ..@@@@..            ",
            "  . ...@......        ",
            "  .+++++++++...       ",
            "  .      ....++...    ",
            "  .@..@@@@@@.+++++..  ",
            "  .@@@@@..#  ++++ ..  ",
            "  .       ++++  .@..  ",
            "  .++++++++  .@@@.+.  ",
            " .      ..@@@@@. ++.  ",
            " ..@@@@@@@@@.  +++ .  ",
            " ....@...# +++++ @..  ",
            " .    ++++++++ .@. .  ",
            " .++++++++  .@@@@ .   ",
            " .   #....@@@@. ++.   ",
            " .@@@@@@@@@.. +++ .   ",
            " ........  +++++...   ",
            " ...  ..+++++ ..@..   ",
            "    ......  .@@@ +.   ",
            "          ......++.   ",
            "                ...   ",
            "                      "};
        """

object2 = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Icon_XPM_In_Macro")                                    #
object2.addProperty("App::PropertyString","Identity","ExampleTitle","Identity of object").Identity = "FCSpring"
#...other Property Data
#...other Property Data
#
object2.ViewObject.Proxy = IconViewProviderToFile( object2, setIconInMacro(""))              # icon in macro (.XPM)
App.ActiveDocument.recompute()
########## example with icon in macro end



####################################################################
########## Example with icon to FreeCAD ressource # begin ##########
####################################################################

object3 = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Icon_Ressource_FreeCAD")                               #
object3.addProperty("App::PropertyString","Identity","ExampleTitle","Identity of object").Identity = "FCSpring"
#...other Property Data
#...other Property Data
#
object3.ViewObject.Proxy = IconViewProviderToFile( object3, ":/icons/Draft_Draft.svg")       # icon to FreeCAD ressource
App.ActiveDocument.recompute()
########## example with icon to FreeCAD ressource end

Exemple complet de création d'un cube avec son icône

#https://forum.freecadweb.org/viewtopic.php?t=10255#p83319
import FreeCAD, Part, math
from FreeCAD import Base
from PySide import QtGui

global path
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")# macro path in FreeCAD preferences
path = param.GetString("MacroPath","") + "/"                        # macro path
path = path.replace("\\","/")                                       # convert the "\" to "/"

def setIconInMacro(self):
    return """
        /* XPM */
        static char * xpm[] = {
        "22 22 12 1",
        " 	c None",
        ".	c #A40000",
        "+	c #2E3436",
        "@	c #CE5C00",
        "#	c #F57900",
        "$	c #FCAF3E",
        "%	c #5C3566",
        "&	c #204A87",
        "*	c #555753",
        "=	c #3465A4",
        "-	c #4E9A06",
        ";	c #729FCF",
        "                      ",
        "                      ",
        "                      ",
        "        ..   ..       ",
        "       +@#+++.$$      ",
        "       +.#+%..$$      ",
        "       &*$  &*#*      ",
        "      &   =&=  =      ",
        "   ++&  +.==   %=     ",
        "  ++$@ ..$ %=   &     ",
        "  ..-&%.#$$ &## +=$   ",
        "   .#  ..$ ..#%%.#$$  ",
        "     ;    =+=## %-$#  ",
        "     &=   ;&   %=     ",
        "      ;+ &=;  %=      ",
        "      ++$- +*$-       ",
        "      .#&&+.@$$       ",
        "      ..$# ..$#       ",
        "       ..   ..        ",
        "                      ",
        "                      ",
        "                      "};
        """

class PartFeature:
    def __init__(self, obj):
        obj.Proxy = self

class Box(PartFeature):
    def __init__(self, obj):
        PartFeature.__init__(self, obj)
        obj.addProperty("App::PropertyLength", "Length", "Box", "Length of the box").Length = 1.0
        obj.addProperty("App::PropertyLength", "Width",  "Box", "Width of the box" ).Width  = 1.0
        obj.addProperty("App::PropertyLength", "Height", "Box", "Height of the box").Height = 1.0

    def onChanged(self, fp, prop):
        try:
            if prop == "Length" or prop == "Width" or prop == "Height":
                fp.Shape = Part.makeBox(fp.Length,fp.Width,fp.Height)
        except:
            pass

    def execute(self, fp):
        fp.Shape = Part.makeBox(fp.Length,fp.Width,fp.Height)

class ViewProviderBox:
    def __init__(self, obj, icon):
        obj.Proxy  = self
        self.icone = icon
        
    def getIcon(self):
        return self.icone

    def attach(self, obj):
        return

    def setupContextMenu(self, obj, menu):
        action = menu.addAction("Set default height")
        action.triggered.connect(lambda f=self.setDefaultHeight, arg=obj:f(arg))

        action = menu.addAction("Hello World")
        action.triggered.connect(self.showHelloWorld)

    def setDefaultHeight(self, view):
        view.Object.Height = 15.0

    def showHelloWorld(self):
        QtGui.QMessageBox.information(None, "Hi there", "Hello World")

def makeBox():
    FreeCAD.newDocument()
    a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Box")
    Box(a)
#    ViewProviderBox(a.ViewObject, path + "FreeCADIco.png")    # icon download to file
#    ViewProviderBox(a.ViewObject,  ":/icons/Draft_Draft.svg") # icon to FreeCAD ressource
    ViewProviderBox(a.ViewObject,  setIconInMacro(""))        # icon in macro (.XPM)
    App.ActiveDocument.recompute()

makeBox()

Utiliser QFileDialog pour écrire dans un fichier

Code complet :

# -*- coding: utf-8 -*-
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

try:
    SaveName = QFileDialog.getSaveFileName(None,QString.fromLocal8Bit("Save a file txt"),path,             "*.txt") # PyQt4
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
except Exception:
    SaveName, Filter = PySide.QtGui.QFileDialog.getSaveFileName(None, "Save a file txt", path,             "*.txt") # PySide
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
if SaveName == "":                                                            # if the name file are not selected then Abord process
    App.Console.PrintMessage("Process aborted"+"\n")
else:                                                                         # if the name file are selected or created then 
    App.Console.PrintMessage("Registration of "+SaveName+"\n")                # text displayed to Report view (Menu > View > Report view checked)
    try:                                                                      # detect error ...
        file = open(SaveName, 'w')                                            # open the file selected to write (w)
        try:                                                                  # if error detected to write ...
            # here your code
            print("here your code")
            file.write(str(1)+"\n")                                           # write the number convert in text with (str())
            file.write("FreeCAD the best")                                    # write the the text with ("  ")
        except Exception:                                                     # if error detected to write
            App.Console.PrintError("Error write file "+"\n")                  # detect error ... display the text in red (PrintError)
        finally:                                                              # if error detected to write ... or not the file is closed
            file.close()                                                      # if error detected to write ... or not the file is closed
    except Exception:
        App.Console.PrintError("Error Open file "+SaveName+"\n")      # detect error ... display the text in red (PrintError)

Utiliser QFileDialog pour lire un fichier

Code complet:

# -*- coding: utf-8 -*-
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

OpenName = ""
try:
    OpenName = QFileDialog.getOpenFileName(None,QString.fromLocal8Bit("Read a file txt"),path,             "*.txt") # PyQt4
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
except Exception:
    OpenName, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Read a file txt", path,             "*.txt") #PySide
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
if OpenName == "":                                                            # if the name file are not selected then Abord process
    App.Console.PrintMessage("Process aborted"+"\n")
else:
    App.Console.PrintMessage("Read "+OpenName+"\n")                           # text displayed to Report view (Menu > View > Report view checked)
    try:                                                                      # detect error to read file
        file = open(OpenName, "r")                                            # open the file selected to read (r)  # (rb is binary)
        try:                                                                  # detect error ...
            # here your code
            print("here your code")
            op = OpenName.split("/")                                          # decode the path
            op2 = op[-1].split(".")                                           # decode the file name 
            nomF = op2[0]                                                     # the file name are isolated

            App.Console.PrintMessage(str(nomF)+"\n")                          # the file name are displayed

            for ligne in file:                                                # read the file
                X  = ligne.rstrip('\n\r') #.split()                           # decode the line
                print(X)                                                      # print the line in report view other method 
                                                                              # (Menu > Edit > preferences... > Output window > Redirect internal Python output (and errors) to report view checked) 
        except Exception:                                                     # if error detected to read
            App.Console.PrintError("Error read file "+"\n")                   # detect error ... display the text in red (PrintError)
        finally:                                                              # if error detected to read ... or not error the file is closed
            file.close()                                                      # if error detected to read ... or not error the file is closed
    except Exception:                                                         # if one error detected to read file
        App.Console.PrintError("Error in Open the file "+OpenName+"\n")       # if one error detected ... display the text in red (PrintError)

Utiliser QColorDialog pour utiliser une couleur

Code complet:

# -*- coding: utf-8 -*-
# https://deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/PySide/QtGui/QColor.html
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

couleur = QtGui.QColorDialog.getColor()
if couleur.isValid():
    red   = int(str(couleur.name()[1:3]),16)    # decode hexadecimal to int()
    green = int(str(couleur.name()[3:5]),16)    # decode hexadecimal to int()
    blue  = int(str(couleur.name()[5:7]),16)    # decode hexadecimal to int()

    print(couleur)                              # 
    print("hexadecimal ",couleur.name())        # color format hexadecimal mode 16
    print("Red   color ",red)                   # color format decimal
    print("Green color ",green)                 # color format decimal
    print("Blue  color ",blue)                  # color format decimal

Utilisation de QColorDialog et création de votre palette couleurs (Base et Personnalisée)

This example modify the Standard color and the Customize color with the Tango FreeCAD guide.Cet exemple modifie la palette des couleurs standard et personnalisée en utilisant la palette Tango du FreeCAD guide.

Le code complet


# -*- coding: utf-8 -*-
# https://deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/PySide/QtGui/QColor.html
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *

###############################################
##        Window colors organisation         ##
##        __________________________         ##
## StandardColor:                            ##
##                                           ##
##           Colonnes:                       ##
##           1:  2:  3:  4:  5:  6:  7:  8:  ##
##          _______________________________  ##
## Line 1:   0   6   12  18  24  30  36  42  ##
## Line 2:   1   7   13  19  25  31  37  43  ##
## Line 3:   2   8   14  20  26  32  38  44  ##
## Line 4:   3   9   15  21  27  33  39  45  ##
## Line 5:   4   10  16  22  28  34  40  46  ##
## Line 6:   5   11  17  23  29  35  41  47  ##
##                                           ##
## CustomColor:                              ##
##                                           ##
##           Colonnes:                       ##
##           1:  2:  3:  4:  5:  6:  7:  8:  ##
##          _______________________________  ##
## Line 1:   0   2   4   6   8   10  12  14  ##
## Line 2:   1   3   5   7   9   11  13  15  ##
##                                           ##
###############################################

color_Dialog   = QtGui.QColorDialog()
# FreeCAD-Tango
# Customize the colors in the standard box (in numeric mode)
#
#### Dialog line 1
color_Dialog.setStandardColor( 0, QtGui.QColor(252, 233,  79 , 0).rgba())    # Butte 1
color_Dialog.setStandardColor( 6, QtGui.QColor(237, 212,   0 , 0).rgba())    # Butte 2
color_Dialog.setStandardColor(12, QtGui.QColor(196, 160,   0 , 0).rgba())    # Butte 3
color_Dialog.setStandardColor(18, QtGui.QColor( 48,  43,   0 , 0).rgba())    # Butte 4

color_Dialog.setStandardColor(24, QtGui.QColor(138, 226,  52 , 0).rgba())    # Chameleo 1
color_Dialog.setStandardColor(30, QtGui.QColor(115, 210,  22 , 0).rgba())    # Chameleo 2
color_Dialog.setStandardColor(36, QtGui.QColor( 78, 154,   6 , 0).rgba())    # Chameleo 3
color_Dialog.setStandardColor(42, QtGui.QColor( 23,  42,   4 , 0).rgba())    # Chameleo 4
#### Dialog line 2
color_Dialog.setStandardColor( 1, QtGui.QColor(252, 175,  62 , 0).rgba())    # Orang 1
color_Dialog.setStandardColor( 7, QtGui.QColor(245, 121,   0 , 0).rgba())    # Orang 2
color_Dialog.setStandardColor(13, QtGui.QColor(206,  92,   0 , 0).rgba())    # Orang 3
color_Dialog.setStandardColor(19, QtGui.QColor( 50,  25,   0 , 0).rgba())    # Orang 4

color_Dialog.setStandardColor(25, QtGui.QColor(114, 159, 207 , 0).rgba())    # Sky Blu 1
color_Dialog.setStandardColor(31, QtGui.QColor( 52, 101, 164 , 0).rgba())    # Sky Blu 2
color_Dialog.setStandardColor(37, QtGui.QColor( 32,  74, 135 , 0).rgba())    # Sky Blu 3
color_Dialog.setStandardColor(43, QtGui.QColor( 11,  21,  33 , 0).rgba())    # Sky Blu 4
#### Dialog line 3
color_Dialog.setStandardColor( 2, QtGui.QColor(173, 127, 168 , 0).rgba())    # Plu 1
color_Dialog.setStandardColor( 8, QtGui.QColor(117,  80, 123 , 0).rgba())    # Plu 2
color_Dialog.setStandardColor(14, QtGui.QColor( 92,  53, 102 , 0).rgba())    # Plu 3
color_Dialog.setStandardColor(20, QtGui.QColor( 23,  16,  24 , 0).rgba())    # Plu 4

color_Dialog.setStandardColor(26, QtGui.QColor(233, 185, 110 , 0).rgba())    # Chocolat 1
color_Dialog.setStandardColor(32, QtGui.QColor(193, 125,  17 , 0).rgba())    # Chocolat 2
color_Dialog.setStandardColor(38, QtGui.QColor(143,  89,   2 , 0).rgba())    # Chocolat 3
color_Dialog.setStandardColor(44, QtGui.QColor( 39,  25,   3 , 0).rgba())    # Chocolat 4
#### Dialog line 4
color_Dialog.setStandardColor( 3, QtGui.QColor(239,  41,  41 , 0).rgba())    # Scarle Re 1
color_Dialog.setStandardColor( 9, QtGui.QColor(204,   0,   0 , 0).rgba())    # Scarle Re 2
color_Dialog.setStandardColor(15, QtGui.QColor(164,   0,   0 , 0).rgba())    # Scarle Re 3
color_Dialog.setStandardColor(21, QtGui.QColor( 40,   0,   0 , 0).rgba())    # Scarle Re 4

color_Dialog.setStandardColor(27, QtGui.QColor( 52, 224, 226 , 0).rgba())    # FreeTea 1
color_Dialog.setStandardColor(33, QtGui.QColor( 22, 208, 210 , 0).rgba())    # FreeTea 2
color_Dialog.setStandardColor(39, QtGui.QColor(  6, 152, 154 , 0).rgba())    # FreeTea 3
color_Dialog.setStandardColor(45, QtGui.QColor(  4,  42,  42 , 0).rgba())    # FreeTea 4
#### Dialog line 5
color_Dialog.setStandardColor( 4, QtGui.QColor(255, 255, 255 , 0).rgba())    # Snow White

color_Dialog.setStandardColor(10, QtGui.QColor(238, 238, 236 , 0).rgba())    # Aluminiu 1
color_Dialog.setStandardColor(16, QtGui.QColor(211, 215, 207 , 0).rgba())    # Aluminiu 2
color_Dialog.setStandardColor(22, QtGui.QColor(186, 189, 182 , 0).rgba())    # Aluminiu 3

color_Dialog.setStandardColor(28, QtGui.QColor(136, 138, 133 , 0).rgba())    # Aluminiu 4
color_Dialog.setStandardColor(34, QtGui.QColor( 85,  87,  83 , 0).rgba())    # Aluminiu 5
color_Dialog.setStandardColor(40, QtGui.QColor( 46,  52,  54 , 0).rgba())    # Aluminiu 6

color_Dialog.setStandardColor(46, QtGui.QColor(  0,   0,   0 , 0).rgba())    # Je Black
#### Dialog line 6
color_Dialog.setStandardColor( 5, QtGui.QColor(255, 255, 255 , 0).rgba())    # Snow White
color_Dialog.setStandardColor(11, QtGui.QColor(255,   0,   0 , 0).rgba())    # Aluminiu 1
color_Dialog.setStandardColor(17, QtGui.QColor(  0, 255,   0 , 0).rgba())    # Aluminiu 2
color_Dialog.setStandardColor(23, QtGui.QColor(  0,   0, 255 , 0).rgba())    # Aluminiu 3

color_Dialog.setStandardColor(29, QtGui.QColor(255, 255,   0 , 0).rgba())    # Aluminiu 4
color_Dialog.setStandardColor(35, QtGui.QColor(255,   0, 255 , 0).rgba())    # Aluminiu 5
color_Dialog.setStandardColor(41, QtGui.QColor(  0, 255, 255 , 0).rgba())    # Aluminiu 6
color_Dialog.setStandardColor(47, QtGui.QColor(  0,   0,   0 , 0).rgba())    # Je Black
color_Dialog.setStandardColor(47, QtGui.QColor(  0,   0,   0 , 0).rgba())    # Je Black

#### Customize the colors to Dialog CustomColor (in hexadecimal converted in numeric mode)
# Use the Yellow tones for tools that create objects.
# Dialog line 1
color_Dialog.setCustomColor(0, QtGui.QColor( int("fc",16),int("e9",16),int("4f",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(2, QtGui.QColor( int("ed",16),int("d4",16),int("00",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(4, QtGui.QColor( int("c4",16),int("a0",16),int("00",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(6, QtGui.QColor( int("30",16),int("2b",16),int("00",16) , 0).rgba()) # hexadecimal converted in int

# Use the Blue tones for tools that modify objects
color_Dialog.setCustomColor(8, QtGui.QColor( int("72",16),int("9f",16),int("cf",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(10,QtGui.QColor( int("34",16),int("65",16),int("a4",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(12,QtGui.QColor( int("20",16),int("4a",16),int("87",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(14,QtGui.QColor( int("0b",16),int("15",16),int("21",16) , 0).rgba()) # hexadecimal converted in int

# Use the Teal tones for view-related tools
# Dialog line 2
color_Dialog.setCustomColor(1, QtGui.QColor( int("34",16),int("e0",16),int("e2",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(3, QtGui.QColor( int("16",16),int("d0",16),int("d2",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(5, QtGui.QColor( int("06",16),int("98",16),int("9a",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(7, QtGui.QColor( int("04",16),int("2a",16),int("2a",16) , 0).rgba()) # hexadecimal converted in int

# Use the Red tones for Constraint related tools
color_Dialog.setCustomColor(9, QtGui.QColor( int("ef",16),int("29",16),int("29",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(11,QtGui.QColor( int("cc",16),int("00",16),int("00",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(13,QtGui.QColor( int("a4",16),int("00",16),int("00",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(15,QtGui.QColor( int("28",16),int("00",16),int("00",16) , 0).rgba()) # hexadecimal converted in int

Color = color_Dialog.getColor()                                   # Color.name() extract the color in Hexadecimal mode (#ad7fa8)

if Color.isValid():

    print("__.name()___________")
    print("hexadecimal         ", Color.name())                   # color format hexadecimal mode 16
    red   = int(str( Color.name()[1:3]),16 )                      # decode hexadecimal to int()
    green = int(str( Color.name()[3:5]),16 )                      # decode hexadecimal to int()
    blue  = int(str( Color.name()[5:7]),16 )                      # decode hexadecimal to int()

    print("Red   color decimal ", str( Color.name()[1:3]), red )  # color format hex to decimal
    print("Green color decimal ", str( Color.name()[3:5]), green )# color format hex to decimal
    print("Blue  color decimal ", str( Color.name()[5:7]), blue ) # color format hex to decimal

    print("__.red()____________")
    print("Red   color decimal ", Color.red() )                   # extract the color RGBa with Qt (0 to 255)
    print("Green color decimal ", Color.green() )                 # extract the color RGBa with Qt (0 to 255)
    print("Blue  color decimal ", Color.blue() )                  # extract the color RGBa with Qt (0 to 255)
    print("Alpha       decimal ", Color.alpha() )                 # extract the color RGBa with Qt (0 to 255)

    print("__.redF()___________")
    print("Red   color float   ", Color.redF() )                  # extract the color RGBa with Qt (0.0 to 1.0) as FreeCAD
    print("Green color float   ", Color.greenF() )                # extract the color RGBa with Qt (0.0 to 1.0) as FreeCAD
    print("Blue  color float   ", Color.blueF() )                 # extract the color RGBa with Qt (0.0 to 1.0) as FreeCAD
    print("Alpha       float   ", Color.alphaF() )                # extract the color RGBa with Qt (0.0 to 1.0) as FreeCAD
    print("__enjoy_____________")

else:
    Color = ""


Afficher une Image avec QLabel et afficher un Gif animé avec QMovie

import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import QPixmap, QMovie, QLabel
from PySide.QtCore import *
class MyLabelPatience():
    label = QtGui.QLabel()
    label.setText("<img src=" + path_Name_Image + "><b><center>Wait please</center> \n\n<center>i search the fonts !\n\n</center></b>")
    # center screen
    ecran = FreeCADGui.getMainWindow().frameGeometry()
    xF = 250; yF = 120
    xW = (ecran.width()/2) - (xF/2)
    yW = (ecran.height()/2)- (yF/2)
    label.setGeometry(xW, yW, xF, yF)
    ####
    label.setStyleSheet("QLabel {background-color : #F0C300;font: 12pt; }");
    label.setWindowFlags(Qt.WindowFlags(Qt.FramelessWindowHint))        # pas de bords (not border)
    ### un-comment for use ###############
    movie = QtGui.QMovie(path_Name_Image)    # anime le fichier Gif anime (decommenter)
    label.setMovie(movie)
    movie.start()
    ##################

patience = MyLabelPatience().label
patience.show()                    #show the image
#patience.close()                   #close the Qlabel
#MyLabelPatience().movie.start()    #start the animation (after patience.show())
#MyLabelPatience().movie.stop()     #stop animation
  • Exemple QLabel avec image et texte
Example QLabel with image


  • Exemple QLabel avec image Gif animé
Example animated Gif

Quelques commandes utiles

# Here the code to display the icon on the '''pushButton''', 
# change the name to another button, ('''radioButton, checkBox''') as well as the path to the icon,

       # Displays an icon on the button PushButton
       # self.image_01 = "C:\Program Files\FreeCAD0.13\icone01.png" # he name of the icon
       self.image_01 = path+"icone01.png" # the name of the icon
       icon01 = QtGui.QIcon() 
       icon01.addPixmap(QtGui.QPixmap(self.image_01),QtGui.QIcon.Normal, QtGui.QIcon.Off)
       self.pushButton.setIcon(icon01) 
       self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button


# path = FreeCAD.ConfigGet("UserAppData") # gives the user path
  path = FreeCAD.ConfigGet("AppHomePath") # gives the installation path of FreeCAD

# This command reverses the horizontal button, right to left
self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the horizontal button

# Displays an info button
self.pushButton.setToolTip(_translate("MainWindow", "Quitter la fonction", None)) # Displays an info button

# This function gives a color button
self.pushButton.setStyleSheet("background-color: red") # This function gives a color button

# This function gives a color to the text of the button
self.pushButton.setStyleSheet("color : #ff0000") # This function gives a color to the text of the button

# combinaison des deux, bouton et texte
self.pushButton.setStyleSheet("color : #ff0000; background-color : #0000ff;" ) #  combination of the two, button, and text

# replace the icon in the main window
MainWindow.setWindowIcon(QtGui.QIcon('C:\Program Files\FreeCAD0.13\View-C3P.png'))

# connects a lineEdit on execute
self.lineEdit.returnPressed.connect(self.execute) # connects a lineEdit on "def execute" after validation on enter
# self.lineEdit.textChanged.connect(self.execute) # connects a lineEdit on "def execute" with each keystroke on the keyboard

# display text in a lineEdit
self.lineEdit.setText(str(val_X)) # Displays the value in the lineEdit (convert to string)

# extract the string contained in a lineEdit
 val_X = self.lineEdit.text() # extract the (string) string contained in lineEdit
 val_X = float(val_X0)        # converted the string to an floating
 val_X = int(val_X0)          # convert the string to an integer

# This code allows you to change the font and its attributes
       font = QtGui.QFont()
       font.setFamily("Times New Roman")
       font.setPointSize(10)
       font.setWeight(10)
       font.setBold(True) # same result with tags "<b>your text</b>" (in quotes)
       self.label_6.setFont(font)
       self.label_6.setObjectName("label_6")
       self.label_6.setStyleSheet("color : #ff0000") # This function gives a color to the text
       self.label_6.setText(_translate("MainWindow", "Select a view", None))

En utilisant les caractères accentués, dans le cas ou vous obtenez les erreurs suivantes :

UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-2: invalid data

plusieurs méthodes sont possibles.

# conversion from a lineEdit
App.activeDocument().CopyRight.Text = str(unicode(self.lineEdit_20.text() , 'ISO-8859-1').encode('UTF-8'))
DESIGNED_BY = unicode(self.lineEdit_01.text(), 'ISO-8859-1').encode('UTF-8')

ou avec la procédure

def utf8(unio):
    return unicode(unio).encode('UTF8')

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 9: ordinal not in range(128)

# conversion
a = u"Nom de l'élément : "
f.write('''a.encode('iso-8859-1')'''+str(element_)+"\n")

ou avec la procédure

def iso8859(encoder):
    return unicode(encoder).encode('iso-8859-1')

ou

iso8859(unichr(176))

ou

unichr(ord(176))

ou

uniteSs = "mm"+iso8859(unichr(178))
print(unicode(uniteSs, 'iso8859'))

Liens pertinents

Arrow-left.svg Page précédente: Line drawing function
Page suivante: Licence Arrow-right.svg

Développer une application pour FreeCAD

Arrow-left.svg Page précédente: Création de dialogue
Page suivante: Tracker Arrow-right.svg

Licences utilisées

FreeCAD utilise deux licences différentes, l'une pour l'application et l'autre pour la documentation :

Licence publique générale limitée GNU (LGPL2+) Pour tout le code source FreeCAD trouvé dans le official Git repository

Creative Commons Attribution 3.0 License (CC-BY-3.0) Pour la documentation sur http://www.freecadweb.org

Voir le debian copyright file (en anglais) pour plus de détails sur les licences utilisées par les différents composants open-source utilisés dans FreeCAD

Effet des licences

Vous trouverez ci-dessous une explication plus claire de ce que la licence LGPL signifie pour vous:

Tous les utilisateurs

Tout le monde peut télécharger, utiliser et redistribuer FreeCAD gratuitement, sans aucune restriction. Votre copie de FreeCAD est vraiment la vôtre, tout comme les fichiers que vous produisez avec FreeCAD. Vous ne serez pas obligé de mettre à jour FreeCAD après un certain temps, ni de modifier votre utilisation de FreeCAD. L'utilisation de FreeCAD ne vous lie à aucun type de contrat ou d'obligation. Le code source de FreeCAD est public et peut être inspecté. Il est donc possible de vérifier qu'il ne fait rien à votre insu, tel que l'envoi de vos données personnelles quelque part.

Les utilisateurs professionnels

FreeCAD peut être utilisé librement pour tout type de travail privé, commercial ou institutionnel. Toute version de FreeCAD peut être déployée et installée n’importe où, à tout moment. Vous pouvez également modifier et adapter FreeCAD à vos propres fins sans aucune restriction. Cependant, vous ne pouvez pas engager la responsabilité des développeurs FreeCAD sur d'éventuels dommages ou pertes commerciales pouvant résulter de l'utilisation de FreeCAD.

Développeurs open source

Vous pouvez utiliser FreeCAD comme base pour développer votre propre application ou simplement l'étendre en créant de nouveaux modules. Si FreeCAD est intégré à votre propre application, vous pouvez choisir la licence GPL ou LGPL, ou toute autre licence compatible avec LGPL, pour autoriser ou non l'utilisation de votre travail dans un logiciel propriétaire. Si vous développez un module à utiliser comme extension et n'incluez aucun code FreeCAD dans celui-ci, vous pouvez choisir la licence de votre choix. Toutefois, si vous souhaitez que votre module soit utilisé autant que possible, il est judicieux d'utiliser la même licence LGPL que FreeCAD, afin de pouvoir utiliser plus facilement des parties de votre code dans d'autres modules ou même dans FreeCAD.

Les développeurs professionnels

Vous pouvez utiliser FreeCAD comme base pour votre propre application sans être obligé de rendre votre application open source. La licence LGPL demande toutefois deux choses de base: 1) informer clairement vos utilisateurs que votre application utilise FreeCAD et que FreeCAD est sous licence LGPL, et 2) que vous séparez clairement votre propre application des composants FreeCAD. Cela se fait généralement soit en créant un lien dynamique avec les composants FreeCAD, afin de permettre aux utilisateurs de le modifier, soit en mettant le code source de FreeCAD, ainsi que les modifications que vous y avez apportées, à la disposition de vos utilisateurs. Vous obtiendrez une assistance des développeurs FreeCAD, à condition que ce ne soit pas une rue à sens unique.

Fichiers

Les modèles et autres fichiers produits avec FreeCAD ne sont soumis à aucune licence indiquée ci-dessus, ni à aucun type de restriction ou de propriété. Vos fichiers sont vraiment les vôtres. Vous pouvez définir le propriétaire du fichier et spécifier vos propres conditions de licence pour les fichiers que vous créez dans FreeCAD, via le menu Fichier → Informations sur le projet.

Déclaration du fondateur

Je sais que la discussion sur le « droit » de licence pour l'open source a occupé une partie importante de la bande passante Internet alors voici la raison pour laquelle, à mon avis, FreeCAD doit être sous licence LGPL.

J'ai choisi les licences LGPL et GPL pour le projet, je sais qu’il y a des pros et des anti LGPL et je vous donnerai quelques raisons de cette décision.

FreeCAD est le mélange d'une bibliothèque et d'une application, de sorte que le GPL serait un peu fort pour cela. Il permettrait d'éviter l'écriture de modules commerciaux pour FreeCAD car elle empêcherait la liaison avec les librairies de base FreeCAD. Vous pouvez vous demander pourquoi des modules commerciaux ? Linux aurait-il autant de succès si les bibliothèques C GNU étaient sous licences GPL, et empêchaient donc les liaisons avec des applications non GPL ? Et bien que j'aime la liberté de Linux, je veux aussi être en mesure d'utiliser les très bon pilotes graphique NVIDIA 3D. Je comprends et j'accepte les raisons pour lesquels NVIDIA ne souhaite pas donner les codes des pilotes. Nous travaillons TOUS pour des entreprises, et nous avons besoin d’argent, ou au moins de nourriture... Pour moi, une coexistence de l'open source et les logiciels à code source propriétaire n'est pas une mauvaise chose, quand il obéit à des règles de la licence LGPL. Je voudrais voir quelqu'un écrire un processus d’import / export CATIA pour FreeCAD et de le distribuer gratuitement ou pour de l'argent. Je n'aime pas forcer à donner plus que ce qu'il ne veut. Ce ne serait pas bon ni pour lui ni pour FreeCAD.

Néanmoins, cette décision est prise seulement pour le système de base de FreeCAD. Chaque auteur d'un module d'application peut prendre sa propre décision.

Jürgen Riegel
—15 October 2006
Arrow-left.svg Page précédente: Création de dialogue
Page suivante: Tracker Arrow-right.svg

Le traqueur de bogues FreeCAD est un endroit pour rapporter des bogues, soumettre des demandes de fonctionnalités, de correctifs, ou encore faire une demande de fusion de votre branche si vous développez avec Git. Le traqueur est divisé en plusieurs sections de travail, donc s'il vous plait soyez rigoureux et remplissez votre demande dans la catégorie appropriée. En cas de doutes, laissez le dans la section "FreeCAD".


Flux de travail recommandé

Bugreport-workflow.png

Comme vous pouvez le voir dans l'organigramme présenté ci-dessus, avant de créer des tickets, prenez le temps de faire des recherches dans les forums et le traqueur de bogues pour vérifier si votre problème n'est pas déjà référencé. Ceci afin d'éviter de gaspiller un temps de travail "au combien précieux" pour les développeurs et les volontaires qui pourraient le consacrer davantage au développement de l'application.

Signaler les bugs

Si vous pensez que vous pourriez avoir trouvé un bogue (dysfonctionnement ou erreur), vous êtes invité de le signaler si vous avez suivi nos instructions pas à pas.

Mais, avant de rapporter un bug, s'il vous plaît vérifiez les éléments suivants :

  • Assurez-vous que votre bug est vraiment un bug, qu'il devrait faire quelque chose, mais il ne fonctionne pas.
  • Si vous n'êtes pas sûr, n'hésitez pas à expliquer votre problème sur le forum et demandez ce qu'il faut faire.
  • Avant de soumettre quoi que ce soit, lisez les questions fréquemment posées (en), effectuez une recherche sur le forum, et assurez-vous que le même bug n'a pas déjà été signalé auparavant, en faisant une recherche sur bug tracker de FreeCAD.
  • Décrivez aussi clairement que possible le problème, et comment il peut être reproduit. Si nous ne pouvons pas vérifier le bug, nous ne pourrons pas être en mesure de le réparer.
  • Inscrivez les informations suivantes : Votre système d'exploitation, sa version, s'il est de 32 ou 64 bits, et, la version de FreeCAD vous utilisez.
  • S'il vous plaît déposer un rapport distinct pour chaque bug.
  • Si vous êtes sur un système Linux, et que votre bug provoque un plantage dans FreeCAD, vous pouvez essayer de tracer le débogage :
    • à partir d'un terminal exécuter gdb FreeCAD (en supposant que le paquet gdb soit installé), puis, à l'intérieur de gdb faire run.
    • ensuite exécuter FreeCAD.
    • Après que l'accident se soit reproduit, tapez bt , pour obtenir le backtrace complet.
    • Inclure le backtrace dans votre rapport de bogue.

Demande de fonctionnalités

Si vous désirez une fonctionnalité particulière, qui n'est pas encore implémentée dans FreeCAD, ce n'est pas un bug, mais une demande de fonctionnalité.

Vous pouvez également soumettre une proposition sur mantis bug tracker Mantis logo button.gif même, (envoyez-la comme demande de fonctionnalité au lieu d'un bug), mais gardez bien à l'esprit, qu'il n'y a aucune garantie que votre souhait soit exaucé.

  1. IMPORTANTː Before requesting a potential Feature Request please be certain that you are the first one doing so by searching the forums and the bugtracker. If you have concluded that there are no pre-existing tickets/discussions the next step is toː
  2. Start a forum thread to discuss your feature request with the community via the Open Discussion forum.
  3. Once the community agrees that this is a valid Feature, you then can open a ticket on the tracker (file it under feature request instead of bug).
  • NOTE #1 To keep things organized please remember to link the forum thread URL into the ticket and the ticket number (as a link) in to the forum thread.
  • NOTE #2 Keep in mind there are no guarantees that your wish will be fulfilled.
FreeCAD Bugtracker report page - use the dropdown to correctly designate what the ticket is

Soumettre un correctif (patch)

Dans le cas, où vous avez programmé une correction d'un bug (patch), une extension ou autre chose qui peut être d'utilité publique dans FreeCAD, créer un patch à l'aide de l'outil Subversion diff tool et de le soumettre sur mantis bug tracker Mantis logo button.gif et envoyez-le comme patch.

Addendumː FreeCAD development has switched to the GitHub development model so the workflow for submitting patches has been greatly enhanced/streamlined by submitting Pull Requests.

  • Open a forum thread in the Developer subforum to announce and discuss your patch.
  • Submit your PR to the FreeCAD GitHub repo. Be sure to link the forum thread in to the git commit summary.
  • Paste the PR link in to the forum thread for the devs/testers to test.
  • Be present for the discussion so that your code can potentially be merged more effectively.

NOTEː the FreeCAD community recommends to first discuss any large revision to the source code in advance to save everyone time.

Requesting merge

Si vous avez créé une branche git contenant les modifications que vous aimeriez voir fusionné dans le code FreeCAD, vous pouvez y demander que votre branche soit examinée et fusionnée si les développeurs FreeCAD sont OK avec elle. Vous devez d'abord publier votre branche dans un dépôt git publique (github, bitbucket, sourceforge ...) et donner ensuite l'URL de votre branche dans votre demande de fusion.

If you have created a git branch containing changes that you would like to see merged into the FreeCAD code, you can ask there to have your branch reviewed and merged if the FreeCAD developers are OK with it. You must first publish your branch to a public git repository (github, gitlab, bitbucket, sourceforge etc...) and then give the URL of your branch in your merge request.

MantisBT Tips and Tricks

MantisBT Markup

MantisBT (Mantis Bug Tracker) has it's own unique markup.

  • @mention - works just like on GitHub where if you prepend '@' to someone's username they will receive an email that they have been 'mentioned' in a ticket thread
Mantisbt-mention-example.jpg
  • #1234 - By adding a hash tag in front of a number a shortcut to link to another ticket within MantisBT will present.
    Note: if you hover over a ticket it will show you the summary + if the ticket is closed, it will be struck-through like #1234.
Mantisbt-ticket-shortcut-example.jpg
  • ~5678 - a shortcut that links to a bug note within a ticket. This can be used to reference someone's response within the thread. Each person that posts will show a unique ~#### number next to their username. If you look at the image in the example, you see that the shortcut is referencing the ticket number:comment number of said ticket
Mantisbt-comment-shortcut-example.jpg
  • <del></del> - Using these tags will strikeout text.
Mantisbt-strikeout-text-example.jpg
  • <code></code> - To present a line or block of code, use this tag and it will colorize and differentiate it elegantly.
Mantisbt-colorized-code-example.jpg

MantisBT BBCode

In addition to the above Tracker/MantisBT ̠Markup one also has the possibility to use BBCode format. For a comprehensive list see the BBCode plus plugin page. Here is a list of supported BBCode tagsː
[img][/img] - Images
[url][/url] - Links
[email][/email] - Email addresses
[color=red][/color] - Colored text
[highlight=yellow][/highlight] - Highlighted text
[size][/size] - Font size
[list][/list] - Lists
[list=1][/list] - Numbered lists (number is starting number)
[*] - List items
[b][/b] - Bold
[u][/u] - underline
[i][/i] - Italic
[s][/s] - Strikethrough
[left][/left] - Left align
[center][/center] - Center
[right][/right] - Right align
[justify][/justify] - Justify
[hr] - Horizontal rule
[sub][/sub] - Subscript
[sup][/sup] - Superscript
[table][/table] - Table
[table=1][/table] - Table with border of specified width
[tr][/tr] - Table row
[td][/td] - Table column
[code][/code] - Code block
[code=sql][/code] - Code block with language definition
[code start=3][/code] - Code block with line numbers starting at number
[quote][/quote] - Quote by *someone* (no name)
[quote=name][/quote] - Quote by *name*

MantisBT <=> GitHub Markup

Below are special MantisBT Source-Integration plugin keywords which will link to the FreeCAD GitHub repo. See Tracker#GitHub_and_MantisBT.

  • c:FreeCAD:git commit hash: - c stands for 'commit'. FreeCAD stands for the FreeCAD GitHub repo. 'git commit hash' is the specific git commit hash to reference. Note: the trailing colon is necessary. Exampleː cːFreeCADː709d2f325db0490016807b8fa6f49d1c867b6bd8ː
  • d:FreeCAD:git commit hash: - similar to the above, d stands for 'diff' which will provide a Diff view of the commit. Exampleː dːFreeCADː709d2f325db0490016807b8fa6f49d1c867b6bd8ː
  • p:FreeCAD:pullrequest: - similar to the above, p stands for Pull Request. Exampleː pːFreeCADː498ː
Mantisbt-source-integration-markup.jpg


GitHub and MantisBT

The FreeCAD bugtracker has a plug-in called Source Integration which essentially ties both the FreeCAD GitHub repo to our MantisBT tracker. It makes it easier to track and associate git commits with their respective MantisBT tickets. The Source Integration plugin scans the git commit messages for specific keywords in order to execute the following actions:

Note The below keywords need to be added in the git commit message and not the PR subject

Remotely referencing a ticket

Using this pattern will automagically associate a git commit to a ticket (Note: this will not close the ticket.) The format MantisBT will recognize:

  • bug #1234
  • bugs #1234, #5678
  • issue #1234
  • issues #1234, #5678
  • report #1234
  • reports #1234, #5678

For the inquisitive here is the regex MantisBT uses for this operation:
/(?:bugs?|issues?|reports?)+\s*:?\s+(?:#(?:\d+)[,\.\s]*)+/i

Remotely resolving a ticket

The format MantisBT will recognize:

  • fix #1234
  • fixed #1234
  • fixes #1234
  • fixed #1234, #5678
  • fixes #1234, #5678
  • resolve #1234
  • resolved #1234
  • resolves #1234
  • resolved #1234, #5678
  • resolves #1234, #5678

For the inquisitive here is the regex MantisBT uses for this operation:
/(?:fixe?d?s?|resolved?s?)+\s*:?\s+(?:#(?:\d+)[,\.\s]*)+/i

Related

Arrow-left.svg Page précédente: Licence
Page suivante: CompileOnWindows Arrow-right.svg
Arrow-left.svg Page précédente: Tracker
Page suivante: Compiler sous Unix Arrow-right.svg

Cet page explique pas à pas comment compiler FreeCAD 0.18 ou plus récent dans Windows.

Prérequis

Premièrement, vous devez installer les bibliothèques et programmes suivants:

Requis

  • Git (Il y a plusieurs solutions alternatives telles que GitCola, Tortoise Git, et d'autres.)
  • CMake version 3.11.x - 3.14.x. Remarque: On ne peut généralement pas utiliser la dernière version de CMake. Par conséquent, utilisez uniquement une version de CMake dans la plage spécifiée sur cette page!
    Il est recommandé d'utiliser l'option "Ajouter CMake au chemin système pour tous les utilisateurs" lors de l'installation de CMake. Ensuite, vous pourrez facilement accéder ultérieurement à CMake également à partir de la ligne de commande/powershell.
  • LibPack (également appelé FreeCADLibs). Ceci est un ensemble de bibliothèques nécessaires à la compilation de FreeCAD sous Windows. Selon la version de FreeCAD que vous souhaitez compiler, vous devez télécharger le LibPack correspondant. Par exemple, pour compiler FreeCAD 0.18, téléchargez la version 32 bits ou la version 64 bits du LibPack for 0.18, afin de compiler la dernière version de développement 0.19, téléchargez LibPack pour la version 0.19 (il n’existe qu'une version 64 bits).
    Il suffit de télécharger le LibPack pour décompresser et installez-le plus tard.
    Note: Il est recommandé d'utiliser la même version de compilationMS Visual Studio (MSVC) pour laquelle LibPack est conçu. Cela garantit la réussite de la compilation et de l’exécution de FreeCAD.exe compilé. Ainsi, vous devriez par exemple pouvoir compiler FreeCAD 0.18 en utilisant LibPack pour 0.19 et MSVC 15, mais vous rencontrerez peut-être des problèmes pour compiler FreeCAD 0.18 en utilisant LibPack pour 0.18 et MSVC 15, car LibPack pour 0.18 est conçu pour être construit avec MSVC 12.

Programmes optionnels

  • Python 3.x. Une installation distincte de python n'est pas obligatoire car LibPack contient Python. Cependant, pour pouvoir tester ultérieurement votre version de FreeCAD, il est utile de disposer d'une installation Python autonome. Il est recommandé d’utiliser non pas la dernière version, mais la version précédente (par exemple, pas Python 3.7 mais 3.6).
  • Une interface graphique pour Git. Plusieurs interfaces sont disponibles, voir cette liste. L'avantage principal d'une interface est qu'il n'est pas nécessaire d'apprendre les commandes Git pour obtenir le code source de FreeCAD ou pour envoyer des correctifs au référentiel GitHub de FreeCAD.
    Nous décrivons ci-après la gestion du code source à l'aide de l'interface TortoiseGit. Cette interface s’intègre directement à l’explorateur de fichiers Windows et dispose d’une large communauté d’utilisateurs pour obtenir de l’aide en cas de problème.
  • NSIS Ceci est le programme pour générer l'installateur Windows de FreeCAD. (Information: pour FreeCAD 0.17 et les versions antérieures, le programme WiX a été utilisé pour créer le programme d'installation.)

Code source

Vous pouvez maintenant obtenir le code source de FreeCAD:

Utiliser une interface

Lorsque vous utilisez le Git frontend TortoiseGit:

  1. Créez un nouveau dossier où placer le code source.
  2. Cliquez avec le bouton droit sur ce dossier dans l’explorateur de fichiers Windows et sélectionnez-le dans le menu contextuel Git Clone.
  3. Un dialogue apparaîtra. Utilisez-le ici comme URL pour le référentiel FreeCAD
    https://github.com/FreeCAD/FreeCAD.git
    et cliquez sur OK.

Maintenant, le code source est téléchargé et son dossier devient un dossier suivi par Git.

Utiliser la ligne de commande

Pour créer une branche locale et télécharger le code source, vous devez ouvrir un terminal (invite de commande) et entrez dans le répertoire ou vous désirez placer le code source, puis tapez:

git clone https://github.com/FreeCAD/FreeCAD.git

Compiler

Le compilateur par défaut (recommandé) est MS Visual Studio (MSVC). Bien qu'il soit possible d'utiliser d'autres compilateurs utilisant Cygwin ou MinGW gcc, il n'a pas encore été testé ou porté.

Vous pouvez obtenir une version gratuite de MSVC (pour une utilisation OpenSource) en téléchargeant l'édition "Communauté" de MS Visual Studio. Pour ce faire, utilisez cette URL
https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&rel=xx
où xx est le numéro de version. Donc, pour obtenir MSVC 15 (appelé également MSVC 2017), utilisez cette URL:
https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&rel=15

Pour ceux qui ne veulent pas installer l'énorme MSVC uniquement pour avoir un compilateur, voir CompileOnWindows - Réduire l'espace disque.

Remarque: Bien que l'édition Communauté de MSVC soit gratuite, vous devez créer un compte Microsoft à partir de l'EDI MSVC pour pouvoir utiliser l'EDI pendant plus de 30 jours. Si vous ne compilez qu'en utilisant la ligne de commande, vous n'avez pas besoin de l'EDI et donc pas de compte Microsoft.

Chemin de Configuration Système optionnelle

Vous pouvez éventuellement inclure les chemins d'accès à certains dossiers de la variable système PATH. Ceci est utile si vous souhaitez accéder aux programmes de ces dossiers à partir de la ligne de commande/powershell ou si vous souhaitez que des programmes spéciaux soient trouvés par le compilateur ou CMake. En outre, l’ajout de dossiers à PATH peut s’avérer nécessaire si vous n’utilisez pas les options correspondantes lors de l’installation du programme.

  • Vous pouvez inclure le dossier de votre LibPack dans votre variable système PATH. Ceci est utile si vous envisagez de créer plusieurs configurations/versions de FreeCAD.
  • Si vous n'avez pas utilisé l'option permettant d'ajouter CMake à PATH lors de son installation, ajoutez son dossier d'installation
    C:\Program Files\CMake\bin à PATH.
  • Si vous n'avez pas utilisé l'option permettant d'ajouter TortoiseGit à PATH lors de son installation, ajoutez son dossier d'installation
    C:\Program Files\TortoiseGit\bin à PATH.

Pour ajouter à votre chemin au système:

  1. Dans le menu Démarrer de Windows, cliquez avec le bouton droit de la souris sur Ordinateur et choisissez Propriétés.
  2. Dans la boîte de dialogue qui apparaît, cliquez sur Paramètres système avancés.
  3. Une autre boîte de dialogue s'ouvrira. Cliquez sur l'onglet Avancé sur Variables d'environnement.
  4. Encore une autre boîte de dialogue s'ouvrira. Sélectionnez ensuite la variable Path et cliquez sur Editer.
  5. Une autre boîte de dialogue s'ouvrira. Cliquez ici sur Nouveau et ajoutez le chemin d'accès au dossier de Git ou du LibPack.
  6. Enfin, appuyez sur OK et fermez toutes les boîtes de dialogue en appuyant sur OK.

Configuration

LibPack

Au début, vous devez configurer un dossier de construction:

  1. Créez un nouveau dossier où va se trouver FreeCAD compilé. Il est fortement recommandé que ce dossier ne se trouve pas dans le dossier du code source de FreeCAD.
  2. Créez-y un nouveau sous-dossier pour le LibPack. Remarque: Le nom de ce sous-dossier doit être identique au nom du fichier LibPack. Si par exemple le LibPack a le nom de fichier FreeCADLibs_12.1.2_x64_VC15.7z, vous devez nommer le sous-dossier FreeCADLibs_12.1.2_x64_VC15.
  3. Extrayez le LibPack dans ce sous-dossier.

CMake

Maintenant, vous devez configurer l'environnement de construction à l'aide de CMake:

  1. Ouvrez l'interface graphique de CMake
  2. Spécifiez le dossier source de FreeCAD
  3. Spécifiez le dossier de construction que vous venez de créer à l'étape précédente.
  4. Cliquez sur Configurer
  5. Dans la boîte de dialogue qui apparaît, spécifiez le générateur en fonction de celui que vous souhaitez utiliser. Pour MS Visual Studio standard, utilisez Visual Studio xx 2yyy, où xx correspond à la version du compilateur et à l'année de sa publication. Il est recommandé d'utiliser l'option par défaut Utiliser les compilateurs natifs par défaut.
    Remarque: Il est important de spécifier la variante de bit correcte. Si vous avez la variante 64 bits de LibPack, vous devez également utiliser le compilateur x64.

Cela commencera la configuration et échouera à cause de paramètres manquants.

S'il échoue avec le message "Visual Studio est introuvable", la prise en charge de CMake dans MSVC n'est pas encore installée. Pour l'installer:

  1. Ouvrez l'EDI MSVC
  2. Utilisez le menu Outils → Obtenir les outils et fonctionnalités
  3. Dans l'onglet Workloads, activez Développement de bureau avec C++
  4. Sur le côté droit, vous devriez maintenant voir que le composant Outils Visual C++ pour CMake sera installé.
  5. Installez-le.

S'il n'y a pas d'erreur à propos de Visual Studio, tout va bien, mais CMake ne connaît pas encore tous les paramètres nécessaires. Donc maintenant:

  1. Assurez-vous que l'option de recherche Avancée est cochée.
  2. Recherchez dans CMake la variable FREECAD_LIBPACK_DIR et spécifiez-y l'emplacement correct dans le dossier LibPack.
  3. Recherchez la variable BUILD_QT5 et activez cette option.
  4. Cliquez à nouveau sur Configurer

Il ne devrait maintenant y avoir aucune erreur. Si oui, cliquez sur Générer. Ceci fait, vous pouvez fermer CMake et continuer à démarrer la compilation de FreeCAD. Cependant, pour la première compilation, maintenez-le ouvert pour le cas où vous souhaitez ou devez modifier certaines options pour le processus de construction:

Options pour le procédé de compilation

Le système de construction CMake vous donne la flexibilité nécessaire pour le processus de construction. Cela signifie que vous pouvez activer et désactiver certaines fonctionnalités ou certains modules avec les variables CMake.

Voici la description de certaines de ces variables:

Link table
Nom de la Variable Description Défaut
BUILD_XXX Construisez FreeCAD avec le composant XXX. Si vous ne voulez pas/n'avez pas besoin de compiler, par exemple le plan de travail OpenSCAD, désactivez la variable BUILD_OPENSCAD. FreeCAD n'aura alors pas cet atelier.
Remarque: Certains composants sont requis pour d'autres composants. Si vous décochez, par exemple, BUILD_ROBOT, CMake vous informera que le composant Chemin ne peut pas être compilé correctement. Par conséquent, vérifiez la sortie de CMake après avoir modifié une option BUILD_XXX!
dépend
CMAKE_INSTALL_PREFIX Le dossier de sortie lors de la construction de la cible INSTALL, voir aussi la section Exécution et installation de FreeCAD Dossier d'installation de programme par défaut de Windows
FREECAD_COPY_DEPEND_DIRS_TO_BUILD Copie les bibliothèques LibPack nécessaires pour exécuter FreeCAD.exe dans le dossier de construction. Voir aussi la section Exécution et installation de FreeCAD. OFF
FREECAD_LIBPACK_USE Activer ou désactiver l'utilisation de FreeCAD LibPack ON
FREECAD_LIBPACK_DIR Répertoire où se trouve le LibPack Le dossier de code source de FreeCAD
FREECAD_RELEASE_PDB Créer des bibliothèques de débogage également pour les versions de revision ON

Compilation de FreeCAD

En fonction de votre compilateur, le processus de construction de FreeCAD sera légèrement différent. Dans les sections suivantes, vous décrivez les flux de travail connus. Si vous construisez avec Qt Creator, passez à Compiler avec Qt Creator, sinon, procédez directement:

Construire avec Visual Studio 15 2017

  1. Démarrez l'IDE Visual Studio. Cela peut être effectué en appuyant sur le bouton Ouvrir un projet dans l'interface graphique de CMake ou en double-cliquant sur le fichier FreeCAD.sln que vous trouvez dans votre dossier de construction.
  2. Dans la barre d’outils de l’EDI MSVC, assurez-vous que vous utilisez pour la première compilation Release.
  3. Il y a une fenêtre appelée "Solution" explorateur. Il répertorie toutes les cibles de compilation possibles.
    Pour démarrer une compilation complète, cliquez avec le bouton droit de la souris sur la cible ALL_BUILD, puis choisissez Construire.

Cela va maintenant prendre beaucoup de temps.

Pour compiler un FreeCAD prêt à l’emploi, compilez la cible INSTALL, voir la section Exécution et installation de FreeCAD.

Si vous n'obtenez aucune erreur, vous avez terminé. Félicitations! Vous pouvez quitter MSVC ou le garder ouvert.

Compilation avec Visual Studio 12 2013

Assurez vous de spécifier Visual Studio 12 x64(ou un Compilateur-C que vous utilisez) comme compilateur utilisé par CMake avant de continuer.

  • Démarrez Visual Studio 12 2013 en cliquant sur l'icône du bureau créé lors de son installation.
  • Ouvrez le projet par:

Fichier → Ouvrir → Projet/Solution

  • Ouvrez le fichier FreeCAD_Trunk.sln dans le dossier CMake créé
  • Dans Configuration Solutions, en haut de la barre déroulante activez Release X64

Cette action peut prendre un certain temps en fonction de votre système

  • Build → Build Solution
  • Cela va prendre un certain temps ...

Si vous ne recevez pas d'erreurs vous avez terminé. Quitter Visual Studio et lancez FreeCAD en double cliquant sur l'icône FreeCAD dans le dossier bin du répertoire de compilation.

Compiler avec Qt Creator

Installation et configuration de Qt Creator

  • Téléchargez et installez Qt Creator
  • Outils → Options → Editeur Texte → Behavior tab:
    • File Encodings → Default Encodings:
    • Set to: ISO-8859-1 /...csISOLatin1 (Certain caracteres créent une errors/warnings avec Qt Creator if left set to UTF-8. Cela semble pour corrigé.)
  • Tools → Options → Build & Run:
    • CMake tab
      • Fill Executable box with path to cmake.exe
    • Kits tab
      • Name: MSVC 2008
      • Compiler: Microsoft Visual C++ Compiler 9.0 (x86)
      • Debugger: Détection automatique ...
      • Qt version: None
    • General tab
      • Uncheck: Toujours compiler et déployer le projet
      • Uncheck: Toujours déployer le projet avant de l'exécuter

Importer un projet et compiler

  • File → Open File or Project
  • Open CMakeLists.txt qui est dans le plus haut niveau de la source
  • Ceci démarre CMake
  • Choisissez créer le répertoire et cliquez sur suivant
  • Ensemble de générateurs de NMake Generator (MSVC 2008)
  • Cliquez sur Démarrer CMake. Suivez les instructions décrites ci-dessus pour configurer CMake à votre convenance.

Maintenant FreeCAD est construit

  • Build → Build All
  • Ceci peut prendre du temps...

Une fois terminé, il peut être exécuté: Il y a 2 triangles verts en bas à gauche. Un est pour la mise au point. L'autre est pour l'exécution. Faites votre choix.

Compilation en ligne de commande

Les étapes pour compiler à partir de la ligne de commande dépendent du compilateur. Pour MSVC 2017, les étapes sont les suivantes:

  1. Dans le menu Démarrer de Windows, accédez à Visual Studio 2017 → Outils Visual Studio et choisissez Invite de commande du développeur pour VS 2017.
  2. Allez dans votre dossier de construction.
  3. Exécute la commande
    msbuild ALL_BUILD.vcxproj/p:Configuration=Release
    ou
    msbuild INSTALL.vcxproj/p:Configuration=Release

Ces étapes peuvent également être automatisées. Voici par exemple une solution pour MSVC 2017:

  1. Téléchargez le script compile-FC.txt.
  2. Le renommer en compile-FC.bat
  3. Dans l'explorateur de fichiers de Winddows Shift+Cliquez-droit sur votre dossier de construction et utilisez-le dans le menu contextuel Invite de commandes ici '.
  4. Exécute la commande
    compile-FC install

Au lieu d'appeler compile-FC avec l'option installer, vous pouvez aussi utiliser déboguer ou release:
déboguer   - compiler FreeCAD dans la configuration de débogage
release - compiler FreeCAD dans la configuration de release
install   - compiler FreeCAD dans la configuration de la version et créer une installation

Exécution et installation de FreeCAD

Il existe 2 méthodes pour exécuter la compilation de FreeCAD:
Method 1: Vous exécutez FreeCAD.exe que vous trouvez dans votre dossier de construction qui se trouve dans le sous-dossier bin
Method 2: Vous construisez la cible INSTALL

La méthode 2 est la plus simple, car elle assure automatiquement que toutes les bibliothèques requises pour exécuter FreeCAD.exe se trouvent dans le bon dossier. FreeCAD.exe et les bibliothèques seront sortis dans le dossier que vous avez spécifié dans la variable CMake CMAKE_INSTALL_PREFIX.

Pour la méthode 1, vous devez placer les bibliothèques dans le dossier bin de votre dossier de construction (où se trouve FreeCAD.exe). Cela peut être facilement fait en utilisant les variables CMake en option:

  1. Ouvrez l'interface graphique de CMake.
  2. Recherchez et cochez la variable FREECAD_COPY_DEPEND_DIRS_TO_BUILD.
  3. Recherchez et cochez la variable FREECAD_COPY_LIBPACK_BIN_TO_BUILD.
  4. Cliquez sur Configurer. A la fin de la configuration, CMake copiera automatiquement les bibliothèques nécessaires du dossier LibPack.

Pour FreeCAD 0.19, un seul problème nécessite actuellement une action manuelle:

  1. Téléchargez le fichier qwindowsvistastyle.zip à partir du forum FreeCAD.
  2. Créez un nouveau sous-dossier nommé styles dans le dossier bin (où se trouve FreeCAD.exe).
  3. Extraire le fichier ZIP dans ce dossier.
    Cela ajoute le style nécessaire pour que FreeCAD ressemble à un programme Win 10 normal. Sinon, il ressemblera à Windows 98.

Mise à jour de la compilation

FreeCAD est très activement développé. Par conséquent, son code source change presque quotidiennement. De nouvelles fonctionnalités sont ajoutées et des bugs corrigés. Pour bénéficier de ces modifications du code source, vous devez reconstruire votre FreeCAD. Cette reconstruction se fait en deux étapes:

  1. Mise à jour du code source
  2. Recompilation

Mise à jour du code source

Utiliser une interface

Lorsque vous utilisez le Git frontend TortoiseGit:

  1. Dans l'explorateur de fichiers Windows faites clic droit sur le dossier de code source FreeCAD et sélectionnez dans le menu contextuel Pull.
  2. Une boîte de dialogue apparaîtra. Sélectionnez la branche de développement que vous souhaitez obtenir. master est la branche principale. Par conséquent, utilisez la sauf si vous voulez compiler une nouvelle fonctionnalité spéciale à partir d'une branche qui n'a pas encore été fusionnée avec maître. (Pour plus d'informations sur les branches Git, consultez Processus de développement Git). Cliquez enfin sur OK.

Utiliser la ligne de commande

Ouvrez un terminal (invite de commande) et accédez au répertoire source. Puis tapez:

git pull https://github.com/FreeCAD/FreeCAD.git master

master est le nom de la branche principale du développement. Si vous voulez obtenir le code d’une autre branche, utilisez son nom au lieu de master.

Recompilation

  1. Ouvrez l'EDI MSVC en double-cliquant sur le fichier FreeCAD.sln ou sur le fichier ALL_BUILD.vcxproj dans votre dossier de construction.
  2. Continuer à l'étape 2 de la section Construire avec Visual Studio 15 2017.

Références

A voir

Arrow-left.svg Page précédente: Compiler sur Windows
Page suivante: Compiler sur Mac Arrow-right.svg

Sous les distributions GNU/Linux récentes, FreeCAD est généralement facile à compiler, puisque toutes les dépendances sont fournies par le gestionnaire de paquets. Cela se fait en 3 étapes :

  1. Obtenir le code source de FreeCAD
  2. Obtenir les dépendances ou les paquets dont FreeCAD dépend
  3. Configurer avec cmake et compiler avec make

Vous trouverez ci-dessous des instructions détaillées du processus complet, quelques scripts de compilation et des particularités que vous pourriez rencontrer. Si vous constatez des informations erronées ou désuètes (les distributions Linux changent régulièrement), ou si vous utilisez une distribution qui n'est pas listée, pour les discussion voir sur le forum, votre aide pour corriger le tout sera appréciée.

FreeCAD source compilation workflow.svg

Processus général pour compiler FreeCAD à partir des sources. Les dépendances tierces doivent être dans le système, ainsi que le code source de FreeCAD lui-même. CMake configure le système de manière à ce que le projet entier soit compilé avec une seule instruction make.


Obtenir le code source

Git

Le meilleur moyen d’obtenir le code est de cloner le dépôt Git en lecture seule. Pour cela, vous avez besoin du programme git qui peut être installé dans la plupart des distributions Linux. Il peut également être obtenu sur le site officiel.

Ceci créera une copie de la dernière version du code source de FreeCAD dans un nouveau répertoire nommé freecad-source.

sudo apt install git
git clone https://github.com/FreeCAD/FreeCAD.git freecad-source

Pour plus d'informations sur l'utilisation de Git et sur la contribution de code au projet, voir gestion du code source.

Source sous forme archive

Vous pouvez alternativement télécharger la source sous forme d'archive, en fichier .zip ou .tar.gz, et décompresser cela dans le dossier voulu.

Obtenir les dépendances

Pour compiler FreeCAD, vous devez installer les dépendances requises mentionnées dans les Bibliothèques externes ; les packages contenant ces dépendances sont répertoriés ci-dessous pour différentes distributions Linux. Veuillez noter que les noms et la disponibilité des bibliothèques dépendront de votre distribution particulière. Si votre distribution est ancienne, certains paquets peuvent ne pas être disponibles ou avoir un nom différent. Dans ce cas, consultez la section Anciennes distributions et distributions non-conventionnelles ci-dessous.

Une fois que vous avez toutes les dépendances installées procédez àla Compilation de FreeCAD.

Veuillez noter que le code source de FreeCAD est d’environ 500 Mo ; il peut être trois fois plus gros si vous clonez le référentiel Git avec son historique de modifications complet. Obtenir toutes les dépendances peut nécessiter le téléchargement de 500 Mo ou plus de nouveaux fichiers ; Lorsque ces fichiers sont décompressés, ils peuvent nécessiter 1500 Mo ou plus d’espace. Notez également que le processus de compilation peut générer jusqu'à 1500 Mo de fichiers supplémentaires lorsque le système copie et modifie le code source complet. Par conséquent, assurez-vous de disposer de suffisamment d’espace libre sur votre disque dur, au moins 4 Go, lors de la tentative de compilation.

Debian et Ubuntu

Sous les systèmes basés sur Debian (Debian, Ubuntu, LinuxMint, etc...) , il est très facile d'installer toutes les dépendances requises. La plupart des bibliothèques sont disponibles via apt, le gestionnaire de paquets Synaptic, ou le gestionnaire de paquets de votre choix.

Si vous avez déjà installé FreeCAD depuis les dépôts officiels, vous pouvez installer ses dépendances de compilation à l'aide de cette unique ligne de commande dans un terminal :

sudo apt build-dep freecad

Cependant, si la version de FreeCAD dans les référentiels est ancienne, les dépendances peuvent être mauvaises pour compiler une version récente de FreeCAD. Par conséquent, vérifiez que vous avez installé les packages suivants.

Ces packages sont essentiels à la réussite de toute compilation :

  • build-essential, installe les compilateurs C et C++ et les librairies C.
  • cmake, un outil indispensable pour configurer la source de FreeCAD. Vous pouvez également souhaiter installer cmake-gui et cmake-curses-gui pour une option graphique.
  • libtool, des outils essentiels pour produire des librairies partagées.
  • lsb-release, l'utilitaire reporting de base standard est normalement déjà installé sur un système Debian et vous permet de distinguer, par programme, entre une installation Debian pure et une variante, telle que Ubuntu ou Linux Mint. Ne supprimez pas ce paquet, car de nombreux autres paquets système peuvent en dépendre.

La compilation de FreeCAD utilise le langage Python, et est également utilisé au moment de l'exécution en tant que script. Si vous utilisez une distribution basée sur Debian, l'interpréteur Python est normalement déjà installé.

  • python3
  • swig, l'outil qui crée des interfaces entre le code C++ et Python.

Veuillez vérifier que vous avez installé Python 3. Python 2 étant obsolète en 2019, les nouveaux développements dans FreeCAD ne sont pas testés avec cette version du langage.

Les librairies Boost doivent être installées :

  • libboost-dev
  • libboost-date-time-dev
  • libboost-filesystem-dev
  • libboost-graph-dev
  • libboost-iostreams-dev
  • libboost-program-options-dev
  • libboost-python-dev
  • libboost-regex-dev
  • libboost-serialization-dev
  • libboost-signals-dev
  • libboost-thread-dev

Les librairies Coin doivent être installées :

  • libcoin80-dev, pour Debian Jessie, Stretch, Ubuntu 16.04 à 18.10, ou
  • libcoin-dev, pour Debian Buster, Ubuntu 19.04 et suivants, ainsi que pour Ubuntu 18.04/18.10 avec les PPAs freecad-stable/freecad-daily ajoutés à vos sources logicielles.

Plusieurs librairies traitant des mathématiques, des surfaces triangulées, du tri, des maillages, de la vision par ordinateur, des projections cartographiques, de la visualisation 3D, du système X11 Window, de l'analyse XML et de la lecture de fichiers Zip :

  • libeigen3-dev
  • libgts-bin
  • libgts-dev
  • libkdtree++-dev
  • libmedc-dev
  • libopencv-dev or libcv-dev
  • libproj-dev
  • libvtk7-dev or libvtk6-dev
  • libx11-dev
  • libxerces-c-dev
  • libzipios++-dev

Python 2 et Qt4

Ceci n’est plus recommandé pour les nouvelles installations car Python 2 et Qt4 sont obsolètes.

Pour compiler FreeCAD pour Debian Jessie, Stretch, Ubuntu 16.04, en utilisant Python 2 et Qt4, installez les dépendances suivantes.

  • qt4-dev-tools
  • libqt4-dev
  • libqt4-opengl-dev
  • libqtwebkit-dev
  • libshiboken-dev
  • libpyside-dev
  • pyside-tools
  • python-dev
  • python-matplotlib
  • python-pivy
  • python-ply
  • python-pyside

Python 3 et Qt5

Pour compiler FreeCAD avec Debian Buster, Ubuntu 19.04 et ultérieures, ainsi que Ubuntu 18.04/18.10 avec l'un ou l'autre des dépôts PPA freecad-stable/freecad-daily ajouté à vos sources de logiciels, installez les dépendances suivantes.

  • qtbase5-dev
  • qttools5-dev
  • libqt5opengl5-dev
  • libqt5svg5-dev
  • libqt5webkit5-dev or qtwebengine5-dev
  • libqt5xmlpatterns5-dev
  • libqt5x11extras5-dev
  • libpyside2-dev
  • libshiboken2-dev
  • pyside2-tools
  • python3-dev
  • python3-matplotlib
  • python3-pivy
  • python3-ply
  • python3-pyside2.qtcore
  • python3-pyside2.qtgui
  • python3-pyside2.qtsvg
  • python3-pyside2.qtwidgets
  • python3-pyside2uic

Noyau OpenCascade

Le noyau OpenCascade est la librairie graphique principale pour créer des formes 3D. Il existe dans une version officielle OCCT et une version communautaire OCE. La version communautaire n'est plus recommandée car elle est obsolète.

Pour Debian Buster, Ubuntu 18.10 et versions ultérieures, ainsi que pour Ubuntu 18.04 avec les freecad-stable/freecad-daily PPAs ajoutés à vos sources de logiciels, installez les paquets officiels.

  • libocct*-dev
    • libocct-data-exchange-dev
    • libocct-draw-dev
    • libocct-foundation-dev
    • libocct-modeling-algorithms-dev
    • libocct-modeling-data-dev
    • libocct-ocaf-dev
    • libocct-visualization-dev
  • occt-draw

Pour Debian Jessie, Stretch, Ubuntu 16.04 et plus récente, installez les paquetages Edition Communautaire.

  • liboce*-dev
    • liboce-foundation-dev
    • liboce-modeling-dev
    • liboce-ocaf-dev
    • liboce-ocaf-lite-dev
    • liboce-visualization-dev
  • oce-draw

Vous pouvez installer toutes les librairies individuellement ou en utilisant l’extension astérisque. Changez occ par oce si vous voulez installer les librairies de la communauté.

sudo apt install libocct*-dev

Paquets optionnels

Vous pouvez éventuellement installer ces paquets supplémentaires :

  • libsimage-dev, pour que Coin prenne en charge d'autres formats de fichier image.
  • doxygen et libcoin-doc (ou libcoin80-doc pour d'anciens systèmes), si vous avez l’intention de générer de la documentation sur le code source.
  • libspnav-dev, pour la prise en charge des périphériques 3Dconnexion, comme "Space Navigator" ou "Space Pilot".
  • checkinstall, si vous avez l'intention d'enregistrer vos fichiers installés dans le gestionnaire de paquets de votre système, afin de pouvoir les désinstaller ultérieurement.

Commande unique pour Qt5 et Python 3

Requiert Pyside2, disponible sous Debian Buster et les freecad-stable/freecad-daily PPAs.

sudo apt install cmake cmake-gui libboost-date-time-dev libboost-dev libboost-filesystem-dev libboost-graph-dev libboost-iostreams-dev libboost-program-options-dev libboost-python-dev libboost-regex-dev libboost-serialization-dev libboost-signals-dev libboost-thread-dev libcoin-dev libeigen3-dev libgts-bin libgts-dev libkdtree++-dev libmedc-dev libocct-data-exchange-dev libocct-ocaf-dev libocct-visualization-dev libopencv-dev libproj-dev libpyside2-dev libqt5opengl5-dev libqt5svg5-dev libqt5webkit5-dev libqt5x11extras5-dev libqt5xmlpatterns5-dev libshiboken2-dev libspnav-dev libvtk7-dev libx11-dev libxerces-c-dev libzipios++-dev occt-draw pyside2-tools python3-dev python3-matplotlib python3-pivy python3-ply python3-pyside2.qtcore python3-pyside2.qtgui python3-pyside2.qtsvg python3-pyside2.qtwidgets python3-pyside2uic qtbase5-dev qttools5-dev swig

Commande unique pour Python 2 et Qt4

Ceci n'est pas recommandé pour les installations plus récentes car Python 2 et Qt4 sont obsolètes.

sudo apt install cmake debhelper dh-exec dh-python libboost-date-time-dev libboost-dev libboost-filesystem-dev libboost-graph-dev libboost-iostreams-dev libboost-program-options-dev libboost-python-dev libboost-regex-dev libboost-serialization-dev libboost-signals-dev libboost-thread-dev libcoin80-dev libeigen3-dev libgts-bin libgts-dev libkdtree++-dev libmedc-dev libocct-data-exchange-dev libocct-ocaf-dev libocct-visualization-dev libopencv-dev libproj-dev libpyside-dev libqt4-dev libqt4-opengl-dev libqtwebkit-dev libshiboken-dev libspnav-dev libvtk6-dev libx11-dev libxerces-c-dev libzipios++-dev lsb-release occt-draw pyside-tools python-dev python-matplotlib python-pivy python-ply swig

Utilisateurs de Ubuntu 16.04, veuillez aussi consulter la discussion sur la compilation dans le forum Compiler sur Linux (Kubuntu): CMake ne peut pas trouver VTK.

Fedora

Vous avez besoin des paquets suivants :

  • gcc-c++ (or possibly another C++ compiler?)
  • cmake
  • doxygen
  • swig
  • gettext
  • dos2unix
  • desktop-file-utils
  • libXmu-devel
  • freeimage-devel
  • mesa-libGLU-devel
  • OCE-devel
  • python
  • python-devel
  • python-pyside-devel
  • pyside-tools
  • boost-devel
  • tbb-devel
  • eigen3-devel
  • qt-devel
  • qt-webkit-devel
  • ode-devel
  • xerces-c
  • xerces-c-devel
  • opencv-devel
  • smesh-devel
  • coin3-devel

(si coin2 est la dernière disponible pour votre version de Fedora, utilisez les paquets à partir de http://www.zultron.com/rpm-repo/)

  • soqt-devel
  • freetype
  • freetype-devel

Et optionnellement :


Gentoo

Le moyen le plus facile de vérifier quels paquets sont nécessaires pour compiler FreeCAD et de vérifier via portage :

emerge -pv freecad

Ceci devrait vous donner une superbe liste de paquets supplémentaires que devez avoir installés sur votre système.

Si FreeCAD n'est pas disponible sur portage, il est disponible sur la waebbl overlay. Le suivi des problèmes sur le recouvrement waebbl Github peut vous aider à résoudre certains problèmes que vous pourriez rencontrer. La superposition fournit freecad-9999 , que vous pouvez choisir de compiler ou simplement utiliser pour obtenir les dépendances.

layman -a waebbl

openSUSE

Tumbleweed

Les commandes suivantes installeront les packages nécessaires à la construction de FreeCAD avec Qt5 et Python 3.

zypper in --no-recommends -t pattern devel_C_C++ devel_qt5

zypper in libqt5-qtbase-devel libqt5-qtsvg-devel libqt5-qttools-devel boost-devel swig libboost_program_options-devel libboost_mpi_python3-devel libboost_system-devel libboost_program_options-devel libboost_regex-devel libboost_python3-devel libboost_thread-devel libboost_system-devel libboost_headers-devel libboost_graph-devel python3 python3-devel python3-matplotlib python3-matplotlib-qt5 python3-pyside2 python3-pyside2-devel python3-pivy gcc gcc-fortran cmake occt-devel libXi-devel opencv-devel libxerces-c-devel Coin-devel SoQt-devel freetype2-devel eigen3-devel libode6 vtk-devel libmed-devel hdf5-openmpi-devel openmpi2-devel netgen-devel freeglut-devel libspnav-devel f2c doxygen dos2unix glew-devel

La commande suivante installera Qt Creator et le débogueur de projet GNU.

zypper in libqt5-creator gdb

S'il manque des packages, vous pouvez vérifier le fichier Tumbleweed "FreeCAD.spec" sur Open Build Service.

Vérifiez également s’il existe des correctifs à appliquer (tels que 0001-find-openmpi2-include-files.patch).

Saut

S'il existe une différence entre les packages disponibles sur Tumbleweed et Leap, alors vous pouvez lire le lien "FreeCAD.spec" file on the Open Build Service pour déterminer les paquets requis.

Arch Linux

Vous aurez besoin des bibliothèques suivantes des référentiels officiels:

  • boost-libs
  • curl
  • desktop-file-utils
  • glew
  • hicolor-icon-theme
  • jsoncpp
  • libspnav
  • med
  • opencascade
  • shiboken2
  • xerces-c
  • pyside2
  • python-matplotlib
  • python-netcdf4
  • qt5-svg
  • qt5-webkit
  • qt5-webengine
  • boost
  • cmake
  • eigen
  • git
  • gcc-fortran
  • pyside2-tools
  • swig
  • qt5-tools
  • shared-mime-info

Aussi, assurez vous de vérifier le AUR pour tout paquet manquant qui ne sont pas dans les dépôts, actuellement :

  • coin
  • python-pivy
  • med
sudo pacman -S boost-libs curl desktop-file-utils glew hicolor-icon-theme jsoncpp libspnav med opencascade shiboken2 xerces-c pyside2 python-matplotlib python-netcdf4 qt5-svg qt5-webkit qt5-webengine cmake eigen git gcc-fortran pyside2-tools swig qt5-tools shared-mime-info coin python-pivy med

Distributions anciennes et non-conventionnelles

Sous d'autres distributions, nous n'avons que très peu de retours des utilisateurs, il pourrait être plus difficile de trouver les paquets requis.

Essayez d’abord de localiser les bibliothèques requises mentionnées dans third party libraries/fr|bibliothèques tierces dans votre gestionnaire de paquets. Attention, certains d'entre eux pourraient avoir un nom de paquet légèrement différent; recherchez name, mais aussi libname, name-dev, name-devel et similaire. Si ce n'est pas possible, essayez de compiler vous-même ces bibliothèques.

FreeCAD requiert une version du compilateur GNU g++ supérieure ou égale à la version 3.0.0, car FreeCAD est principalement écrit en C++. Lors de la compilation, certains scripts Python sont exécutés. L'interpréteur Python doit donc fonctionner correctement. Pour éviter tout problème d’éditeur de liens, il est également conseillé d’avoir les chemins de bibliothèque dans la variable LD_LIBRARY_PATH ou dans le fichier ld.so.conf. Cela est déjà fait dans les distributions Linux modernes, mais il faudra peut-être le configurer dans les anciennes.

Pivy

Pivy (les wrappers Python sous Coin3d) n'est pas nécessaire pour construire FreeCAD ni pour le démarrer, mais il est nécessaire en tant que dépendance d'exécution par l'atelier Draft. Si vous n'utilisez pas cet atelier, vous n'aurez pas besoin de Pivy. Cependant, notez que l'atelier Draft est utilisé en interne par d'autres ateliers, tels que Arch et BIM, aussi Pivy doit-il être installé pour pouvoir également utiliser ces ateliers.

Depuis novembre 2015, la version obsolète de Pivy incluse dans le code source de FreeCAD n'est plus compilée sur de nombreux systèmes. Ce n'est pas un gros problème car normalement vous devriez obtenir Pivy depuis le gestionnaire de paquets de votre distribution ; si vous ne trouvez pas Pivy, vous devrez peut-être le compiler vous-même, voir les instructions de compilation de Pivy.

Symboles de débogage

Afin de résoudre les pannes dans FreeCAD, il est utile de disposer des symboles de débogage d'importantes bibliothèques de dépendances telles que Qt. Pour cela, essayez d'installer les packages de dépendance se terminant par -dbg, -dbgsym, -debuginfo ou similaire, selon votre distribution Linux.

Pour Ubuntu, vous devrez peut-être activer les dépôts spéciaux pour pouvoir voir et installer ces paquets de débogage avec le gestionnaire de paquets. Voir Paquets de symboles de débogage pour plus d'informations.

Compiler FreeCAD

FreeCAD utilise CMake comme système de construction principal, qui est un système de compilation disponible sur tous les principaux systèmes d'exploitation. Compiler avec CMake est généralement très simple et se fait en deux étapes.

  1. CMake vérifie que tous les programmes et toutes les bibliothèques nécessaires sont présents sur votre système et génère un Makefile qui est configuré pour la deuxième étape. FreeCAD a le choix entre plusieurs options de configurations. Certaines alternatives sont détaillées ci-dessous.
  2. La compilation elle-même, effectuée avec le programme make, génère les exécutables FreeCAD.

FreeCAD étant une application volumineuse, la compilation de tout le code source peut durer de 10 minutes à une heure, en fonction de votre CPU et du nombre de cœurs de CPU utilisés pour la compilation.

Vous pouvez générer le code dans ou hors du répertoire source. La construction hors source est généralement la meilleure option.

Compilation out-of-source

Construire dans un dossier séparé est plus pratique que de construire dans le même répertoire que celui où se trouve le code source, car chaque fois que vous mettez à jour le code source, CMake peut déterminer de manière intelligente les fichiers modifiés et recompiler uniquement ce qui est nécessaire. Ceci est très utile lorsque vous testez différentes branches de Git, car vous ne confondez pas le système de construction.

Pour construire out-of-source, créez simplement un répertoire de construction (freecad-build) distinct de votre dossier source FreeCAD (freecad-source) ; ensuite depuis le dossier de compilation pointez cmake comme dossier source. Vous pouvez également utiliser cmake-gui ou ccmake au lieu de cmake dans les instructions ci-dessous. Une fois que cmake a fini de configurer l’environnement, utilisez make pour lancer la nouvelle compilation.

mkdir freecad-build
cd freecad-build
cmake ../freecad-source
make -j$(nproc --ignore=2)

L'option -j de make contrôle le nombre de jobs (fichiers) compilés en parallèle. Le programme nproc retourne le nombre de cœurs de processeur de votre système utilisés avec l'option -j, vous pouvez choisir de procéder sur autant de fichiers que vous avez de cœurs afin d'accélérer la compilation. Dans l'exemple ci-dessus, il sera utilisé tous les cœurs de votre système sauf deux ; Cela permettra à votre ordinateur de rester réactif pour d'autres usages pendant la compilation en arrière-plan. L'exécutable FreeCAD apparaîtra éventuellement dans le dossier freecad-build/bin. Voir aussi Compilation (accélération) pour améliorer la vitesse de compilation.

Compilation in-source

Les compilations in-source conviennent si vous voulez compiler rapidement une version de FreeCAD et que vous n’avez pas l’intention de mettre à jour souvent le code source. Dans ce cas, vous pouvez supprimer le programme compilé et la source en supprimant simplement un seul dossier.

Allez dans le répertoire source et pointez cmake dans le répertoire actuel (désigné par un simple point) :

cd freecad-source
cmake .
make -j$(nproc --ignore=2)

L’exécutable FreeCAD se trouvera alors dans le répertoire freecad-source/bin.

Comment réparer votre répertoire du code source

Si vous avez accidentellement effectué une compilation dans le répertoire du code source, ou ajouté des fichiers étranges, et souhaitez restaurer le contenu uniquement du code source d'origine, vous pouvez effectuer les étapes suivantes.

> .gitignore
git clean -df
git reset --hard HEAD

La première ligne efface le fichier .gitignore. Cela garantit que les commandes de nettoyage et de réinitialisation suivantes s'appliqueront à tout le contenu du répertoire et n'ignoreront pas les éléments correspondant aux expressions contenues dans .gitignore. La deuxième ligne supprime tous les fichiers et répertoires qui ne sont pas suivis par le référentiel git, puis la dernière commande réinitialisera toutes les modifications apportées aux fichiers suivis, y compris la première commande effaçant le fichier .gitignore.

Si vous n'effacez pas le répertoire source, les exécutions ultérieures de cmake risquent de ne pas intégrer les nouvelles options sur le système si le code change.

Configuration

En appliquant différentes options à cmake, vous pouvez modifier la manière dont FreeCAD est compilé. La syntaxe est la suivante.

cmake -D <var>:<type>=<value> $SOURCE_DIR

$SOURCE_DIR est le répertoire qui contient le code source. Le <type> peut être omis dans la plupart des cas. L'espace après l'option -D peut également être omis.

Par exemple, pour éviter de construire le module FEM :

cmake -D BUILD_FEM:BOOL=OFF ../freecad-source
cmake -DBUILD_FEM=OFF ../freecad-source

Toutes les variables possibles sont répertoriées dans le fichier CMakeLists.txt, situé dans le dossier primaire freecad-source. Dans ce fichier, recherchez le mot option pour obtenir toutes les variables pouvant être définies et voir leurs valeurs par défaut.


# ==============================================================================
# =================   Toutes les options du processus de construction =================
# ==============================================================================

option(BUILD_FORCE_DIRECTORY "Le répertoire de construction doit être différent du répertoire source." OFF)
option(BUILD_GUI "Construction FreeCAD Gui. Sinon, vous avez uniquement la ligne de commande et le module d'importation Python." ON)
option(FREECAD_USE_EXTERNAL_ZIPIOS "Utilisez le système installé zipios++ au lieu de celui fourni." OFF)
option(FREECAD_USE_EXTERNAL_SMESH "Utilisez smesh installé par le système au lieu de celui fourni." OFF)
...

Vous pouvez également utiliser la commande cmake -LH pour répertorier la configuration actuelle, ainsi que toutes les variables pouvant être modifiées. Vous pouvez également installer et utiliser cmake-gui pour lancer une interface graphique affichant toutes les variables pouvant être modifiées. Dans les sections suivantes, nous énumérons certaines des options les plus pertinentes que vous souhaiterez peut-être utiliser.

Pour une compilation de Debogage

Créez une version Debug pour résoudre les pannes dans FreeCAD. Attention, avec cette construction Sketcher devient très lent avec des esquisses complexes.

cmake -DCMAKE_BUILD_TYPE=Debug ../freecad-source

Pour une compilation "Release"

Créez une version Release pour tester que le code qui ne plante pas. Une Release sera beaucoup plus rapide qu'une version Debug.

cmake -DCMAKE_BUILD_TYPE=Release ../freecad-source

Compiler en s'appuyant sur Python 3 et Qt5

Par défaut FreeCAD est compilé pour Python 2 et Qt4. Ces deux paquets étant obsolètes, il est préférable de les compiler pour Python 3 et Qt5.

Dans une distribution Linux moderne, il suffit de fournir deux variables spécifiant l'utilisation de Qt5 et le chemin d'accès à l'interpréteur Python.

cmake -DBUILD_QT5=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 ../freecad-source

Compiler pour une version spécifique de Python

Si l'exécutable python par défaut de votre système est un lien symbolique vers Python 2, cmake essaiera de configurer FreeCAD pour cette version. Vous pouvez choisir une autre version de Python en donnant le chemin d'un exécutable spécifique :

cmake -DPYTHON_EXECUTABLE=/usr/bin/python3 ../freecad-source

Si cela ne fonctionne pas, vous devrez peut-être définir des variables supplémentaires pointant sur les bibliothèques Python souhaitées et les répertoires inclus :

cmake -DPYTHON_EXECUTABLE=/usr/bin/python3.6 \
    -DPYTHON_INCLUDE_DIR=/usr/include/python3.6m \
    -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.6m.so \
    -DPYTHON_PACKAGES_PATH=/usr/lib/python3.6/site-packages/ \
    ../freecad-source

Il est possible d'avoir plusieurs versions indépendantes de Python dans le même système. Par conséquent, l'emplacement et le numéro de version de vos fichiers Python dépendent de votre distribution Linux. Utilisez python3 -V pour afficher la version de Python que vous utilisez actuellement. Seuls les deux premiers chiffres sont nécessaires ; Par exemple, si le résultat est Python 3.6.8, vous devez spécifier les répertoires associés à la version 3.6. Si vous ne connaissez pas les bons répertoires, essayez de les rechercher avec la commande locate.

locate python3.6

Vous pouvez utiliser python3 -m site dans un terminal pour déterminer les répertoires site-package ou dist-package sur les systèmes Debian.

Compiler avec Qt Creator en s'appuyant sur Python 3 and Qt5

Pour compiler dans Qt Creator, ajoutez les variables appropriées au bas du menu Projects → Manage Kits → Kits → Default (or your kit) → CMake Configuration. Spécifiez à nouveau les chemins corrects et la version Python que vous souhaitez utiliser.

PYTHON_EXECUTABLE=/usr/bin/python3.7
PYTHON_INCLUDE_DIR=/usr/include/python3.7m
PYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.7m.so
PYTHON_PACKAGES_PATH=/usr/lib/python3.7/site-packages
BUILD_QT5=ON

Allez à Projects → Run → Run Configuration et choisissez FreeCADMain pour compiler la version graphique de FreeCAD ou FreeCADMainCMD pour ne compiler que la version en ligne de commande.

Plugin Qt Designer

Si vous souhaitez développer des éléments de code Qt pour FreeCAD, vous aurez besoin du plugin Qt Designer qui fournit tous les widgets personnalisés de FreeCAD.

Allez dans un répertoire auxiliaire du code source, lancez qmake avec le fichier de projet indiqué pour créer un Makefile ; puis lancez make pour compiler le plugin.

cd freecad-source/src/Tools/plugins/widget
qmake plugin.pro
make

Si vous compilez pour Qt5, assurez-vous que le code binaire qmake est celui de cette version, afin que Makefile résultant contienne les informations nécessaires pour Qt5.

cd freecad-source/src/Tools/plugins/widget
$QT_DIR/bin/qmake plugin.pro
make

$QT_DIR est le répertoire qui stocke les bibliothèques binaires Qt, par exemple, /usr/lib/x86_64-linux-gnu/qt5.

La librairie créée est libFreeCAD_widgets.so, qui doit être copiée dans $QTDIR/plugins/designer.

sudo cp libFreeCAD_widgets.so $QT_DIR/plugins/designer

Pivy interne ou externe

Auparavant, une version de Pivy était incluse dans le code source de FreeCAD (interne). Si vous souhaitez utiliser la copie de Pivy (externe) de votre système, vous devez utiliser -DFREECAD_USE_EXTERNAL_PIVY=1.

L'utilisation externe de Pivy est devenue la valeur par défaut à partir du développement de FreeCAD 0.16 ; cette option n'a donc plus besoin d'être définie manuellement.

Documentation Doxygen

Si vous avez installé Doxygen, vous pouvez créer la documentation du code source. Voir la documentation source pour les instructions.

Documentation complémentaire

Le code source de FreeCAD est très complet et avec CMake, il est possible de configurer de nombreuses options. Apprendre à utiliser pleinement CMake peut être utile pour choisir les bonnes options pour vos besoins particuliers.

Construire un paquet Debian

Si vous envisagez de construire un paquet Debian voici les sources que vous devez d’abord installer certains paquets :

sudo apt install dh-make devscripts lintian

Allez dans le répertoire FreeCAD et appelez

debuild

Une fois que le paquet est construit, vous pouvez utiliser lintian pour vérifier si le paquet contient des erreurs

lintian freecad-package.deb

Mettre à jour le code source

Le système CMake vous permet de mettre à jour intelligemment le code source et de ne recompiler que ce qui a changé, ce qui accélère les compilations ultérieures.

Déplacez-vous à l'emplacement où le code source FreeCAD a été téléchargé pour la première fois et récupérez le nouveau code :

cd freecad-source
git pull

Puis déplacez-vous dans le répertoire de construction où le code a été initialement compilé, et lancez cmake spécifiant le répertoire actuel (indiqué par un point), puis déclenchez la recompilation avec make.

cd ../freecad-build
cmake .
make -j$(nproc --ignore=2)

Dépannage

Note sur les systèmes 64 bits

Pour la compilation de FreeCAD en 64 bits, il y a un problème connu avec le paquet OpenCASCADE (OCCT) 64 bits. Pour que FreeCAD fonctionne correctement, vous devrez peut-être exécuter le script configure et définir des CXXFLAGS supplémentaires :

./configure CXXFLAGS="-D_OCC64"

Pour les systèmes basés sur Debian, cette option n’est pas nécessaire lors de l’utilisation des packages OpenCASCADE pré-construits, car ceux-ci définissent le bon CXXFLAGS en interne.

Scripts de compilation automatiques

Voici tout ce dont vous avez besoin pour une compilation complète de FreeCAD. C'est une approche en un script qui fonctionne sur une distribution Linux récemment installée. Les commandes demanderont le mot de passe root pour l'installation des packages et des nouveaux référentiels en ligne. Ces scripts doivent fonctionner sur les versions 32 et 64 bits. Ils sont écrits pour différentes versions, mais sont également susceptibles de fonctionner sur une version ultérieure avec ou sans modifications majeures.

Si vous avez un tel script pour votre distribution préférée, veuillez en discuter sur le forum FreeCAD afin que nous puissions l'intégrer.

Ubuntu

Ces scripts constituent un moyen fiable d’installer le bon ensemble de dépendances requises pour créer et exécuter FreeCAD sur Ubuntu. Ils utilisent les PPA (personal package archives) et devraient fonctionner sur toute version d'Ubuntu ciblée par le PPA. Le PPA freecad-daily cible les versions récentes d'Ubuntu, tandis que le PPA freecad-stable cible les versions officiellement prises en charge d'Ubuntu.

Ce script installe l’aperçu instantané de la compilation quotidiennement de FreeCAD et ses dépendances. Il ajoute le référentiel quotidien, obtient les dépendances pour construire cette version et installe les packages requis. Ensuite, il extrait le code source dans un répertoire particulier, crée un répertoire de construction et y apporte des modifications, configure l'environnement de compilation avec cmake et finalement construit l'ensemble du programme avec make. Enregistrez le script dans un fichier, rendez-le exécutable et exécutez-le, mais n'utilisez pas sudo; les privilèges de super-utilisateur ne seront demandés que pour les commandes sélectionnées.

#!/bin/sh
sudo add-apt-repository --enable-source ppa:freecad-maintainers/freecad-daily && sudo apt-get update
sudo apt-get build-dep freecad-daily
sudo apt-get install freecad-daily

git clone https://github.com/FreeCAD/FreeCAD.git freecad-source
mkdir freecad-build
cd freecad-build
cmake -DBUILD_QT5=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 ../freecad-source
make -j$(nproc --ignore=2)

Si vous le souhaitez, vous pouvez désinstaller la version pré-compilée de FreeCAD (freecad-daily) en laissant les dépendances en place. Toutefois, laisser ce paquet installé permettra au gestionnaire de paquets de garder ses dépendances à jour également ; Cela est surtout utile si vous souhaitez suivre le développement de FreeCAD et mettre à jour et compiler en permanence les sources à partir du référentiel Git.

Le script précédent suppose que vous souhaitiez compiler la dernière version de FreeCAD, vous utilisez donc le référentiel "quotidien" pour obtenir les dépendances. Cependant, vous pouvez préférer obtenir les dépendances de construction de la version "stable" pour la version actuelle d'Ubuntu. Si tel est le cas, remplacez la partie supérieure du script précédent par les instructions suivantes. Pour Ubuntu 12.04, omettez --enable-source de la commande.

#!/bin/sh
sudo add-apt-repository --enable-source ppa:freecad-maintainers/freecad-stable && sudo apt-get update
sudo apt-get build-dep freecad
sudo apt-get install freecad

Une fois que vous avez installé le paquet freecad à partir du référentiel freecad-stable, il remplacera l'exécutable FreeCAD disponible à partir du référentiel Universe Ubuntu. L'exécutable s'appellera simplement freecad, et non pas freecad-stable.

OpenSUSE 12.2

Aucuns dépôts externes ne sont nécessaires pour compiler FreeCAD 0.13 avec cette version. Cependant, il existe un incompatibilité avec python3-devel qui doit être enlevé. FreeCAD peut être compilé à partir de GIT de la même manière que pour OpenSUSE 12.2

# install needed packages for development
sudo zypper install gcc cmake OpenCASCADE-devel libXerces-c-devel \
python-devel libqt4-devel python-qt4 Coin-devel SoQt-devel boost-devel \
libode-devel libQtWebKit-devel libeigen3-devel gcc-fortran git swig
 
# create new dir, and go into it
mkdir FreeCAD-Compiled 
cd FreeCAD-Compiled
 
# get the source
git clone https://github.com/FreeCAD/FreeCAD.git free-cad
 
# Now you will have subfolder in this location called free-cad. It contains the source
 
# make another dir for compilation, and go into it
mkdir FreeCAD-Build1
cd FreeCAD-Build1 
 
# build configuration 
cmake ../free-cad
 
# build FreeCAD
make
 
# test FreeCAD
cd bin
./FreeCAD -t 0

Après avoir utilisé git, la prochaine fois que vous souhaiterez recompiler vous même, vous n'aurez pas à tout cloner, il vous suffira d'extraire de git et de recompiler une nouvelle fois.

# go into free-cad dir created earlier
cd free-cad
 
# pull
git pull
 
# get back to previous dir
cd ..
 
# Now repeat last few steps from before.
 
# make another dir for compilation, and go into it
mkdir FreeCAD-Build2
cd FreeCAD-Build2
 
# build configuration 
cmake ../free-cad
 
# build FreeCAD
# Note: to speed up build use all CPU cores: make -j$(nproc)
make
 
# test FreeCAD
cd bin
./FreeCAD -t 0

Debian Squeeze

# get the needed tools and libs
sudo apt-get install build-essential python libcoin60-dev libsoqt4-dev \
libxerces-c2-dev libboost-dev libboost-date-time-dev libboost-filesystem-dev \
libboost-graph-dev libboost-iostreams-dev libboost-program-options-dev \
libboost-serialization-dev libboost-signals-dev libboost-regex-dev \
libqt4-dev qt4-dev-tools python2.5-dev \
libsimage-dev libopencascade-dev \
libsoqt4-dev libode-dev subversion cmake libeigen2-dev python-pivy \
libtool autotools-dev automake gfortran
 
# checkout the latest source
git clone https://github.com/FreeCAD/FreeCAD.git freecad
 
# go to source dir
cd freecad
 
# build configuration 
cmake .
 
# build FreeCAD
# Note: to speed up build use all CPU cores: make -j$(nproc)
make
 
# test FreeCAD
cd bin
./FreeCAD -t 0

Fedora 27/28/29

Vous pouvez poster à l'utilisateur [PrzemoF] sur le forum.

#!/bin/bash

ARCH=$(arch)

MAIN_DIR=FreeCAD
BUILD_DIR=build

#FEDORA_VERSION=27
#FEDORA_VERSION=28
FEDORA_VERSION=29

PACKAGES="gcc cmake gcc-c++ boost-devel zlib-devel swig eigen3 qt-devel \
shiboken shiboken-devel pyside-tools python-pyside python-pyside-devel xerces-c \
xerces-c-devel OCE-devel smesh graphviz python-pivy python-matplotlib tbb-devel \
 freeimage-devel Coin3 Coin3-devel med-devel vtk-devel"

FEDORA_29_PACKAGES="boost-python2 boost-python3 boost-python2-devel boost-python3-devel"

if [ "$FEDORA_VERSION" = "29" ]; then
    PACKAGES="$PACKAGES $FEDORA_29_PACKAGES"
fi

echo "Installing packages required to build FreeCAD"
sudo dnf -y install $PACKAGES
cd ~
mkdir $MAIN_DIR || { echo "~/$MAIN_DIR already exist. Quitting.."; exit; }
cd $MAIN_DIR
git clone https://github.com/FreeCAD/FreeCAD.git
mkdir $BUILD_DIR || { echo "~/$BUILD_DIR already exist. Quitting.."; exit; }
cd $BUILD_DIR
cmake ../FreeCAD 
make -j$(nproc)

Arch using AUR

Arch User Repository (AUR) est une collection de recettes faites par les utilisateurs pour construire des packages qui ne sont pas officiellement supportés par les responsables de la distribution / la communauté. Ils sont généralement en sécurité. Vous pouvez voir qui gère le colis et pendant combien de temps il l'a fait. Il est recommandé de vérifier les fichiers de construction. Des logiciels non-open source sont également disponibles dans cette zone même s'ils sont gérés par la société propriétaire.

Prérequis : git

Steps :

  1. Ouvrez un terminal. Créez éventuellement un répertoire, par exemple mkdir git. Éventuellement changer de répertoire par exemple cd git.
  2. Cloner le référentiel AUR : git clone http://aur.archlinux.org/packages/freecad-git
  3. Entrez le dossier du référentiel AUR : cd freecad-git
  4. Compiler en utilisant Arch makepkg : makepkg -s. Les flag -s ou --syncdeps installeront également les dépendances requises.
  5. Installer le paquet créé : makepkg --install ou double-cliquez sur pkgname-pkgver.pkg.tar.xz dans votre navigateur de fichiers.

Pour mettre à jour FreeCAD vers la dernière version, recommencez à partir de l'étape 3. Mettez à jour le référentiel AUR en cas de modifications importantes de la recette ou de nouvelles fonctionnalités à l'aide de git checkout -f dans le dossier.

Arrow-left.svg Page précédente: CompileOnWindows
Page suivante: CompileOnMac Arrow-right.svg

This page describes how to compile the latest FreeCAD source on macOS X. Latest means the most recent commit to the master branch of the FreeCAD github repository.

These instructions have been tested on macOS High Sierra

This page serves as a quick start, and is not intended to be comprehensive with regard to describing all the available build options.

If you just want to evaluate the latest pre-release build of FreeCAD, you can download pre-built binaries from here.

Install Prerequisites

The following software must be installed to support the build process.

Homebrew Package Manager

Homebrew is a command line based package manager for macOS. The Homebrew main page provides an installation command line that you simply paste into a terminal window.

CMake

CMake is build tool that generates a build configuration based on variables you specify. You then issue the 'make' command to actually build that configuration. The command-line version of CMake is automatically installed as part of the Homebrew installation, above. If you prefer to use a GUI version of CMake, you can download it from here.

Install Dependencies

FreeCAD maintains a Homebrew 'tap' which installs the required formulas and dependencies. Issue the following brew commands in your terminal.


brew tap freecad/freecad
brew install eigen
brew install --only-dependencies freecad --with-packaging-utils

Notes:

  1. 'brew install' may take quite a while, so you may want go grab a beverage. :-)

Get the source

In the following instructions, the source and build folders are created side-by-side under

/Users/username/FreeCAD

but you can use whatever folders you want.

mkdir ~/FreeCAD
cd ~/FreeCAD

The following command will clone the FreeCAD git repository into a directory called FreeCAD-git.

git clone https://github.com/FreeCAD/FreeCAD FreeCAD-git

Create the build folder.

mkdir ~/FreeCAD/build


Run CMake

Next, we will run CMake to generate the build configuration. Several options must be passed to CMake. The following table describes the options and gives some background.

CMake Options

Name Value Notes
CMAKE_BUILD_TYPE Release (STRING) Release or Debug. Debug is generally used for developer-level testing but may also be required for user-level testing and troubleshooting.
BUILD_QT5 1 (BOOL) Required to build with Qt5.
CMAKE_PREFIX_PATH "/usr/local/Cellar/qt@5.6/5.6.2/lib/cmake" (PATH) Required to build with Qt5. See note below.
FREECAD_CREATE_MAC_APP 1 (BOOL) Create a FreeCAD.app bundle at the location specified in CMAKE_INSTALL_PREFIX, when the 'make install' command issued.
CMAKE_INSTALL_PREFIX "./.." (PATH) Path where you want to generate the FreeCAD.app bundle.
FREECAD_USE_EXTERNAL_KDL 1 (BOOL) Required.
BUILD_FEM_NETGEN 1 (BOOL) Required.

Note: Command line to generate CMAKE_PREFIX_PATH:

ls -d $(brew list -1 | grep qt | tail -1 | xargs brew --cellar)/*/lib/cmake

CMake GUI

Open the CMake app, and fill in the source and build folder fields. In this example, it would be /Users/username/FreeCAD/FreeCAD-git for the source, and /Users/username/FreeCAD/build for the build folder.

Next, click the Configure button to populate the list of configuration options. This will display a dialog asking you to specify what generator to use. Leave it at the default Unix Makefiles. Configuring will fail the first time because there are some options that need to be changed. Note: You will need to check the Advanced checkbox to get all of the options.

Set options from the table above, then click Configure again and then Generate.

CMake command line

Enter the following in the terminal.

$cd ~/FreeCAD/build
$cmake \
  -DCMAKE_BUILD_TYPE="Release"   \
  -DBUILD_QT5=1                  \
  -DCMAKE_PREFIX_PATH="/usr/local/Cellar/qt@5.6/5.6.2/lib/cmake"  \
  -DFREECAD_USE_EXTERNAL_KDL=1   \
  -DBUILD_FEM_NETGEN=1           \
  -DFREECAD_CREATE_MAC_APP=1     \
  -DCMAKE_INSTALL_PREFIX="./.."  \
  ../FreeCAD-git/

Run make

Finally, from a terminal run make to compile and link FreeCAD, and generate the app bundle.

cd ~/FreeCAD/build
make -j5 install

The -j option specifies how many make processes to run at once. One plus the number of CPU cores is usually a good number to use. However, if compiling fails for some reason, it is useful to rerun make without the -j option, so that you can see exactly where the error occurred.

See also Compiling - Speeding up.

If make finishes without any errors, you can now launch FreeCAD by double clicking the executable in the Finder.

Updating from Github

FreeCAD development happens fast; every day or so there are bug fixes or new features. To get the latest changes, use git to update the source directory (see Source code management), then re-run the CMake and make steps above. It is not usually necessary to start with a clean build directory in this case, and subsequent compiles will generally go much faster than the first one.

Building with Qt4

FreeCAD has transitioned from Qt 4 to Qt 5. If you need to build with Qt4, the following additional steps are required.

  1. Append '--with-qt4' to the 'brew install' command.
  2. Do not specify BUILD_QT5 CMake option.
  3. Do not specify CMAKE_PREFIX_PATH CMake option

After you install Qt4, if you want to switch to building with Qt5, you will need to uninstall Qt4.

brew uninstall --ignore-dependencies --force cartr/qt4/shiboken@1.2 cartr/qt4/pyside@1.2 cartr/qt4/pyside-tools@1.2 cartr/qt4/qt

Troubleshooting

Segfault on Qt5 launch

If Qt4 was previously installed via brew, and you then build with Qt5, you may get a EXC_BAD_ACCESS (SEGSEGV) exception when launching the new Qt5 build. The fix for this is to manually uninstall Qt4.

brew uninstall --ignore-dependencies --force cartr/qt4/shiboken@1.2 cartr/qt4/pyside@1.2 cartr/qt4/pyside-tools@1.2 cartr/qt4/qt-legacy-formula

Fortran

"No CMAKE_Fortran_COMPILER could be found." during configuration - Older versions of FreeCAD will need a fortran compiler installed. With Homebrew, do "brew install gcc" and try configuring again, giving cmake the path to Fortran ie -DCMAKE_Fortran_COMPILER=/opt/local/bin/gfortran-mp-4.9 . Or, preferably use a more current version of FreeCAD source!

OpenGL

See OpenGL on MacOS for OpenGL issues when Qt 4.8 and earlier are used on MacOS.

FreeType

When using CMake versions older than 3.1.0, it's necessary to set CMake variable FREETYPE_INCLUDE_DIR_freetype2 manually, eg /usr/local/include/freetype2

Arrow-left.svg Page précédente: CompileOnUnix
Page suivante: Third Party Libraries Arrow-right.svg
Arrow-left.svg Page précédente: Compilation
Page suivante: Outils tiers Arrow-right.svg

Vue d'ensemble

Ce sont des bibliothèques que FreeCAD utilise comme dépendances tierces lors de la compilation. Ils sont généralement bibliothèques liées dynamiquement et ont une extension .so sous Linux/MacOS et .dll sous Windows, et sont accompagnés de leurs fichiers d’en-tête .h ou .hpp ou similaire. Si une bibliothèque modifiée est nécessaire, ou si une classe wrapper est nécessaire, le code de la bibliothèque modifiée, ou du wrapper, doit faire partie du code source de FreeCAD et être compilé avec ce dernier.

Les dépendances doivent être installées dans le système avant de procéder à la compilation. Voir Compiler sous Unix, Compiler sous Windows et Compiler sur Mac pour plus d'informations.

Si voulez compiler en utilisant Windows, pensez à utiliser le LibPack au lieu d'essayer d'installer individuellement des librairies.

Liens

Nom de la librairie Version needed Link to get it
Python >= 3.4 http://www.python.org/
Boost >= 1.33 http://www.boost.org/
OpenCASCADE >= 6.7 http://www.opencascade.org
Qt >= 4.1 https://www.qt.io/
Shiboken2 même que Qt https://wiki.qt.io/Qt_for_Python/Shiboken
PySide2 même que Qt https://wiki.qt.io/Qt_for_Python/Shiboken
Coin3D >= 3.x https://bitbucket.org/Coin3D/coin/wiki/Home
SoQt (deprecated) >= 1.2 https://bitbucket.org/Coin3D/soqt/src/default/
Quarter >= 1.0 https://bitbucket.org/Coin3D/quarter/src/default/
FreeType >= XXX XXX
PyCXX >= XXX XXX
KDL >= XXX XXX
Point Cloud Library >= XXX XXX
Salome SMESH >= XXX XXX
VTK >= 6.0 XXX
Xerces-C++ >= 3.0 https://xerces.apache.org/xerces-c/
Eigen3 >= 3.0 http://eigen.tuxfamily.org/index.php?title=Main_Page
Zipios++ >= 0.1.5 https://snapwebsites.org/project/zipios, https://github.com/Zipios/Zipios
Zlib >= 1.0 http://www.zlib.net/, https://github.com/madler/zlib
libarea >= 0.0.20140514-1 https://github.com/danielfalck/libarea

Details

Python

Version : 3.3 ou plus

Licence : Python 3.3 licence

Python 2 est devenu obsolète en 2019. Le développement ultérieur de FreeCAD utilisera exclusivement Python 3; la compatibilité avec Python 2 ne sera pas testée. Par conséquent, les anciens ateliers et macros utilisant cette version devront être mis à jour ou risquent de ne plus fonctionner. Veuillez poster sur le Forum FreeCAD si vous rencontrez des problèmes avec Python 3.


Python est un langage de script polyvalent populaire largement utilisé sous Linux et dans les logiciels open source. Dans FreeCAD, Python est utilisé de différentes manières lors de la compilation et lors de l'exécution. C'est utilisé

  • écrire des scripts de test pour tester différentes conditions, telles que des fuites de mémoire, afin de garantir la fonctionnalité du logiciel après les modifications, pour les vérifications après la construction et les tests de couverture,
  • pour écrire macros et l'enregistrement de macros,
  • implémenter la logique d'application pour les packages standard,
  • pour implémenter des outils auxiliaires tels que Addon Manager,
  • mettre en place des ateliers complets comme Draft et Arch,
  • charger dynamiquement des paquets,
  • mettre en place des règles de conception (des connaissances en ingénierie),
  • faire des interactions Internet fantaisistes comme des groupes de travail et PDM

Sous Linux, Python est généralement déjà installé dans votre distribution. Pour Windows, vous pouvez utiliser le source ou le binaire pré compilées de Python.org ou utiliser ActiveState Python bien qu’il soit un peu difficile d’obtenir les bibliothèques de débogage de ce dernier.

Python a été choisi comme langage de script pour FreeCAD pour différentes raisons:

  • Il est plus orienté objet que Perl et Tcl.
  • Le code est plus lisible que Perl et Visual Basic.
  • Il est plus facile d'intégrer une autre application, contrairement à Java.

En résumé, Python est bien documenté et il est facile à intégrer et à étendre dans une application C++. Il est également bien testé et bénéficie du soutien de la communauté open source. Pour en savoir plus sur Python et parcourir la documentation officielle voyez à l'adresse Python.org.

Boost

Version: 1.33 ou plus

License: Boost Software License - Version 1.0

Les bibliothèques Boost C++ sont des collections de bibliothèques open source révisées par des pairs qui étendent les fonctionnalités de C++. Elles sont destinés à être largement utilisées dans un grand nombre d'applications et à bien fonctionner avec la bibliothèque standard C++. La licence Boost est conçue pour encourager son utilisation dans les projets open source et sources propriétaires.

En raison de leur popularité et de leur stabilité, de nombreuses bibliothèques Boost ont été acceptées pour être incorporées dans la norme C++11 et d’autres sont prévues pour être intégrées dans les normes C++ suivantes.

Afin d'assurer l'efficacité et la flexibilité, Boost fait un usage intensif de modèles (templates). Boost a été une source de travail, et, de recherches approfondies dans la programmation générique, et, méta-données en C++. Vous en saurez plus sur Boost en visitant la page Boost homepage.

OpenCasCade Technologie

Version: 6.7 ou plus

Licence: version 6.7.0 et les versions ultérieures sont régies par GNU Lesser General Public License (LGPL) version 2.1 with additional exception. Les versions antérieures utilisent une licence légèrement différente: Open CASCADE Technology Public License.

La technologie OpenCASCADE (OCCT) est un noyau CAO complet de qualité professionnelle. Il a été développé en 1993 et s'appelait à l'origine CAS.CADE par Matra Datavision en France pour les applications Strim (Styler) et Euclid Quantum. En 1999, il a été publié en tant que logiciel open source, et depuis lors, il s'appelle OpenCASCADE.

OCC est un noyau complet CAD. A l'origine, il a été développé en France par Matra Datavision, pour la Strim (Styler) et Euclide applications quantiques, et, plus tard fait pour l'Open Source. C'est une bibliothèque vraiment énorme, et, faire en premier lieu une application de CAO libre est possible, en fournissant certains paquets, qui seraient difficiles, ou impossibles à mettre en œuvre dans un projet Open Source :

  • Un noyau géométrique complet conforme à STEP.
  • Un modèle topologique de données et toutes les fonctions nécessaires pour travailler sur les (coupes, fusion, extrusion, etc ...)
  • Import-standard/exportation des processeurs comme STEP, IGES, VRML.
  • Visionneuse 2D et 3D avec le soutien de la sélection.
  • Une structure de document, et, données de projet, avec le soutien de, sauvegarde et restauration, de liaison externe des documents, de recalcul de l'historique du dessin (modélisation paramétrique) et d'un centre de chargement de nouveaux types de données, comme un module d'extension dynamique.

Il existe deux versions principales d'OpenCASCADE dans différentes distributions Linux. L'un est distribué par les développeurs d'origine; il est appelé OCCT et est regroupé sous les noms occ ou occt. L'autre version est "l'édition communautaire", en abrégé OCE, et se trouve normalement sous le nom oce. FreeCAD peut être compilé avec l'une ou l'autre version, cependant, depuis 2016, FreeCAD recommande de compiler avec les bibliothèques officielles de l'OCCT plutôt que celles de l'OCE. La raison en est que l'édition de la communauté manque d'importantes corrections de bogues et de fonctions qui améliorent l'utilisation de FreeCAD.

Pour en savoir plus sur OpenCascade visitez la page OpenCASCADE website.

Qt

Version: 4.1 ou plus

Licence : GPL v2.0/v3.0 ou commerciale; (à partir de la version 4.5 aussi sur v2.1 LPGL).

Je ne pense pas que j'ai besoin de dire beaucoup de choses sur Qt. C'est un des outils les plus souvent utilisés, dans l'interface graphique des projets Open Source. Pour moi, le point le plus important d'utiliser Qt est le Qt Designer et la possibilité de charger les boîtes de dialogue entières comme, une ressource (XML), et, d'intégrer des widgets spécialisés.

Vous trouverez de plus amples informations sur la librairie Qt et une très bonne documentation en ligne sur la documentation Qt.

Shiboken2 and Pyside2

Shiboken est le générateur de liaison Python utilisé par Qt pour créer le module PySide pour être utilisé par Python. En d'autres termes, c'est le système utilisé pour exposer l'API Qt C++ au langage Python.

Les paquets originaux Shiboken et PySide devaient être utilisés avec Python 2 et Qt4; étant donné que ces deux versions sont considérées obsolètes en 2019, veuillez utiliser Shiboken2 et PySide2, qui fonctionnent avec Python 3 et Qt5. Les nouveaux développements de FreeCAD sont réalisés avec Python 3 et Qt5. Par conséquent, la compatibilité avec Python 2 et Qt4 n’est plus garantie après FreeCAD 0.18.

Pour en savoir plus sur Shiboken et Pyside voyez sur la page Qt for Python.

Coin3D

Version: 3.0 ou plus

License: BSD 3-clause license

Coin3D est une bibliothèque graphique 3D de haut niveau avec une interface de programmation d'applications C++. Il utilise des structures de données scenegraph pour rendre les graphiques en temps réel adaptés à tout type d'applications de visualisation scientifique et technique.

Coin3D est basé sur la bibliothèque de rendu en mode immédiat OpenGL, standard du secteur, et ajoute des abstractions pour les primitives de niveau supérieur, fournit une interactivité 3D et contient de nombreuses fonctionnalités d'optimisation complexes pour le rendu rapide, transparentes pour le programmeur d'application.

Coin3D est compatible avec l'API Open Inventor 2.1 de SGI. Cette API est devenue l'interface graphique standard de facto pour la visualisation 3D dans la communauté scientifique et technique. Il a fait ses preuves depuis l'an 2000 en tant que pierre angulaire de milliers d'applications d'ingénierie dans le monde.

Coin3D (Open Inventor) est utilisé comme visualiseur 3D dans FreeCAD car le visualiseur OpenCASCADE (AIS et Graphics3D) présente des limitations et des goulots d'étranglement en termes de performances, notamment avec le rendu technique à grande échelle; d'autres éléments tels que les textures ou le rendu volumétrique ne sont pas entièrement pris en charge par le visualiseur OpenCASCADE.

Coin3D est portable sur une large gamme de plates-formes: systèmes d'exploitation UNIX, Linux, BSD, MacOS X et Microsoft Windows. Pour en savoir plus sur cette bibliothèque, visitez Coin3D homepage.

SoQt (déprécié)

Version: 1.2.0 ou plus

License: BSD 3-clause license

SoQt est la liaison Coin3D (Open Inventor) à la boîte à outils de l'interface graphique Qt. Malheureusement, ce n'est plus la licence LGPL qui est utilisée, nous devons donc le supprimer de la base de code de FreeCAD et le lier en tant que bibliothèque. Il a le même modèle de licence que Coin3D. Et vous devez le compiler avec votre version de Qt.

SoQt n'est plus utilisé dans FreeCAD, il a été remplacé par Quarter, une liaison Qt plus récente.

Quarter

Version : 1.0 ou plus

License: BSD 3-clause license

Quarter est une nouvelle liaison Coin3D à la boîte à outils Qt. Une version de celle-ci est incluse dans le code source de FreeCAD, elle est donc compilée avec elle.

Xerces-C++

Version: 3.0 ou plus

License: Apache Software License Version 2.0

Xerces-C++ est un analyseur XML de validation écrit dans un sous-ensemble portable de C++. Xerces-C++ facilite la possibilité pour votre application de lire et d’écrire des données XML. Une bibliothèque partagée est fournie pour analyser, générer, manipuler et valider des documents XML. Xerces-C++ est fidèle à la recommandation XML 1.0 et aux normes associées.

L'analyseur est utilisé pour enregistrer et restaurer les paramètres dans FreeCAD. Pour plus d'informations, voir Xerces-C++ homepage.

Eigen3

Version: 3.0 or higher

Licence: À partir de la version 3.1.1, il est sous licence Mozilla Public License 2.0. Les versions précédentes étaient concédées sous la licence GNU Lesser General Public License 3.

Eigen est une bibliothèque de modèles C++ pour l’algèbre linéaire: matrices, vecteurs, solveurs numériques et algorithmes associés.

Si vous souhaitez simplement utiliser Eigen, vous pouvez utiliser les fichiers d’en-tête immédiatement. Il n'y a pas de bibliothèque binaire à lier, ni de fichier d'en-tête configuré. Eigen est une bibliothèque de modèles pure définie dans les en-têtes.

Eigen est utilisé dans FreeCAD pour de nombreuses opérations vectorielles dans l'espace 3D. Pour en savoir plus, visitez Eigen homepage.

Zipios++

Version: 0.1.5 ou plus

License: GNU Lesser General Public License 2.1

Zipios++ est une bibliothèque C++ pour la lecture et l’écriture de fichiers .zip. L'accès aux entrées individuelles est fourni via iostream C++ standard. Un système de fichiers virtuel simple en lecture seule qui monte des répertoires normaux et des fichiers .zip est également fourni. La structure et l'interface publique de Zipios ++ sont basées sur le paquet java.util.zip de Java.

Le format de fichier natif de FreeCAD .FCstd est en réalité un fichier .zip qui stocke et compresse d'autres types de données qu'il contient, tels que les fichiers BREP et XML. Par conséquent, Zipios++ est utilisé pour enregistrer et ouvrir des archives compressées, y compris des fichiers FreeCAD.

Une copie de Zipios++ est incluse dans le code source de FreeCAD et est donc compilée avec celui-ci. Si vous souhaitez utiliser une bibliothèque Zipios++ externe, fournie par votre système d'exploitation, vous pouvez définir -DFREECAD_USE_EXTERNAL_ZIPIOS = ON avec cmake.

Zipios++ utilise la bibliothèque Zlib pour effectuer la décompression réelle des fichiers.

Zlib

Version: 1.0 ou plus

License: zlib licence

Zlib est conçu pour être une bibliothèque de compression de données gratuite, polyvalente et sans perte, utilisable sur tout matériel informatique et système d'exploitation. Il implémente l'algorithme de compression DEFLATE couramment utilisé dans les fichiers .zip et .gzip.

Une copie de cette bibliothèque est incluse dans le code source de FreeCAD, elle est donc compilée avec elle.

libarea

Version: 0.0.20140514-1 ou plus

Licence: BSD 3-clause license

Libarea est une bibliothèque de logiciels permettant de calculer les opérations de profil et de poche utilisées dans les logiciels de fabrication assistée par ordinateur (FAO). Il a été créé par Dan Heeks pour son projet HeeksCNC.

Une copie de la bibliothèque est incluse avec le code source de l'atelier Path. Elle est donc compilée avec celle-ci.

LibPack

LibPack est un paquet pratique qui regroupe les dépendances de construction de FreeCAD. Cela n'est nécessaire que si vous compilez FreeCAD sous Windows avec Visual Studio 2015 et versions ultérieures. Vous pouvez trouver le dernier LibPack sur la page releases page.

Si vous travaillez sous Linux, vous n’avez pas besoin de LibPack, car vous pouvez obtenir les dépendances dans les dépôts de votre distribution, comme indiqué dans la page compiler avec Unix.

FreeCAD 12.1.2

Voir l'annonce dans le forum: New libpacks for Windows with Qt5.12, OCC7.3 and Python 3.6 by apeltauer

Cela inclut entre autres: Boost 1,67, Coin3D 4.0.0a, Eigen3, Open CASCADE Technology 7.3.0, Python 3.6.8, PySide2, Qt 5.12.1, Salomé, Shiboken2, vtk7, Xerces-C, Zipios++, zlib 1.2 11

Arrow-left.svg Page précédente: Compilation
Page suivante: Outils tiers Arrow-right.svg
Arrow-left.svg Page précédente: Bibliothèques tierces

Page d'outils

Pour chaque développement de logiciels sérieux, vous avez besoin d'outils sérieux. Voici une liste d'outils, que nous utilisons pour développer FreeCAD :

Outils indépendants de la plate-forme

Qt-Toolkit

Qt-toolkit est un outil de conception d'interfaces utilisateur​​, indépendamment de la plate forme utilisée. Elle est contenue dans le LibPack de FreeCAD, mais peut aussi être téléchargé à l'adresse Qt project.

InkScape

Excellent programme de dessin vectoriel. Adhère à la norme SVG, et, est utilisé pour dessiner les icônes et les images. Pour le télécharger, allez sur inkscape.

Doxygen

Un très bon outil, stable, il génère de la documentation à partir de fichiers sources .h et .cpp .

Gimp

Pas grand chose à dire sur le célèbre Gnu Image Manipulation Program. Outre, qu'il peut gérer les fichiers .Xpm, qui est un moyen très pratique pour créer les icônes dans le programme Qt-Toolkit. Le format .XPM est fondamentalement C-Code, qui peut être compilé, dans un programme comme Qt-Toolkit.Gimp produit des fichiers de format libres .png utilisé dans le wiki.

Téléchargez la dernière version de GIMP ici

Gitkraken

C'est une interface graphique propriétaire de git qui est très utile pour apprendre le fonctionnement de git si vous souhaitez contribuer à FreeCAD. Pages pertinentes à rechercher:

OBS Studio

Logiciel libre et open source pour l'enregistrement de vidéos et la diffusion en direct. Plus de détails sur le site officiel: obsproject

StarUML

StarUML est un programme Open Source. Il a beaucoup de caractéristiques des grands, y compris le reverse engineering du code source C++...

Téléchargez le ici : staruml.io

Outils pour Windows

Communauté Visual Studio

Visual Studio Community est gratuit pour les projets open source et les petites structures. L'installation est modulaire, vous pouvez ajouter la prise en charge d'une grande variété de langages, notamment C++ et Python.

Vous pouvez le télécharger sur [1].

CamStudio

CamStudio est un outil Open Source pour créer des enregistrements vidéos d'écran (Webcasts). C'est un très bon outil, pour créer des tutoriels vidéos (avec ou sans son), en enregistrant toutes vos opérations et mouvements de souris, qui se passent sur votre écran . Une vidéo est bien moins ennuyeuse, que l'écriture d'une documentation.

Vous pouvez aller voir le site de camstudio pour plus de détails.

Outils pour Linux

A venir.

Arrow-left.svg Page précédente: Bibliothèques tierces


Arrow-left.svg Page précédente: Outils tiers

Cette page montre les différentes façons de lancer FreeCAD et ses éléments de configuration les plus importants.

Démarrer FreeCAD en ligne de commande

FreeCAD peut être lancé normalement en double-cliquant sur son icône qui est sur le bureau, ou en le sélectionnant dans le menu de démarrage, mais il peut également être lancé directement à partir de la ligne de commande. Cela vous permet de changer les options de démarrage par défaut.

Utilisation des options en ligne de commande sans utiliser le shell

  • Sur Ubuntu, vous pouvez créer une icône de bureau et modifier leurs propriétés. Ajoutez les options de ligne de commande séparées par des espaces derrière le nom du programme dans le champ "Commande".
  • Sous Windows, créez un raccourci et modifiez ses propriétés. Ajoutez les options de ligne de commande séparées par des espaces dans le champ "Cible".

Options disponibles en ligne de commande

Les options en ligne de commande sont l'objet de fréquents changements. Il est donc sage de vérifier les options de votre version courante en tapant :

FreeCAD --help

La réponse vous permet de connaître les paramètres disponibles :

 Usage: FreeCAD [options] File1 File2 ...
 
 Allowed options:
 
 Generic options:
   -v [ --version ]          Prints version string
   -h [ --help ]             Prints help message
   -c [ --console ]          Starts in console mode
   --response-file arg       Can be specified with '@name', too
   --dump-config             Dumps configuration
   --get-config arg          Prints the value of the requested configuration key
 
 Configuration:
   -l [ --write-log ]        Writes a log file to:
                             /home/beast/.FreeCAD/FreeCAD.log
   --log-file arg            Unlike --write-log this allows logging to an 
                             arbitrary file
   -u [ --user-cfg ] arg     User config file to load/save user settings
   -s [ --system-cfg ] arg   System config file to load/save system settings
   -t [ --run-test ] arg     Test case - or 0 for all
   -M [ --module-path ] arg  Additional module paths
   -P [ --python-path ] arg  Additional python paths
   --single-instance         Allow to run a single instance of the application

Fichiers de configuration et Response

Vous pouvez lire certaines options de FreeCAD à partir d'un fichier de configuration. Ce fichier doit être dans le répertoire /bin et doit être nommé FreeCAD.cfg. Notez que les options spécifiées en ligne de commande remplacent le fichier de configuration !

Certains systèmes d'exploitation ne permettent qu'un nombre de caractères assez limité en ligne de commande. La façon courante de contourner cette limitation, est l'utilisation des fichiers response. Un fichier response n'est qu'un fichier de configuration, qui utilise la même syntaxe qu'en ligne de commande. Si la ligne de commande spécifie un nom de fichier response à utiliser, il est chargé, analysé et ajouté à la ligne de commande :

FreeCAD @ResponseFile.txt

ou :

FreeCAD --response-file=ResponseFile.txt

Options cachées

Il y a des options qui sont invisibles à l'utilisateur. Ces options sont, par exemple, les paramètres X-Window analysés par le système Windows :

  • -display display, définit l'affichage X (valeur par défaut est $DISPLAY).
  • -geometry geometry, la géométrie fixe de la première fenêtre client qui est affichée.
  • -fn or -font font, définit la police de l'application. La police doit être spécifié en utilisant la description de police logique X.
  • -bg or -background color, définit la couleur de fond par défaut et une palette d'application (tons clairs et foncés sont calculés).
  • -fg or -foreground color, définit la couleur de premier plan par défaut.
  • -btn or -button color, définit la couleur des boutons par défaut.
  • -name name, définit le nom de l'application.
  • -title title, définit le titre de l'application.
  • -visual TrueColor, force l'application à utiliser un visuel TrueColor sur un affichage 8-bits.
  • -ncols count, limite le nombre de couleurs allouées dans le cube de couleur sur un écran 8-bits, si l'application utilise la spécification de couleur QApplication::ManyColor. Si le nombre est 216, un cube 6x6x6 couleurs est utilisé (soit 6 niveaux de rouge, 6 de vert, et 6 de bleu); pour d'autres valeurs un cube à peu près proportionnel à un cube 2x3x1 couleurs est utilisé.
  • -cmap, provoque l'installation d'une carte de couleurs réservée à l'application, sur un affichage 8-bits.

Démarrer FreeCAD sans interface graphique utilisateur

FreeCAD est généralement construit avec deux exécutables : un compatible avec une interface graphique appelé FreeCAD, et un uniquement en ligne de commande FreeCADCmd. FreeCAD peut être utilisé en mode console en utilisant le commutateur "-c", c'est le comportement par défaut de FreeCADCmd :

FreeCAD -c

En ligne de commande. En mode console, aucune interface utilisateur ne sera affichée, et l'invite vous sera présentée avec un interpréteur Python.

A partir de ce prompt Python, vous avez les mêmes fonctionnalités que l'interpréteur Python lancé au sein de l'interface graphique de FreeCAD, et un accès normal à tous les modules et plugins de FreeCAD, à l'exception du module FreeCADGui. Notez que les modules qui dépendent de FreeCADGui peuvent également être inaccessibles.

Les macros Python de FreeCAD peuvent être spécifiées comme arguments de ligne de commande pour l'un des exécutables mentionnés ci-dessus.

Ensemble de configuration

A chaque démarrage, FreeCAD examine son environnement, ainsi que les paramètres en ligne de commande. Il construit un ensemble de configuration qui détient le cœur des informations d'exécution. Ces informations sont ensuite utilisées pour déterminer l’emplacement où enregistrer les données des utilisateurs ou des fichiers journaux. Il est également très important pour les analyses post-mortem. Par conséquent, il est enregistré dans le fichier journal (log file).

Informations correspondant à l'utilisateur

L'appel se fait de la manière suivante :

path = FreeCAD.ConfigGet("UserAppData")
Entrées de configuration utilisateur
Nom var config Synopsis Exemple M$ Exemple Posix (Linux)
UserAppData Chemin où FreeCAD met les données utilisateur de l'application. C:\Documents and Settings\username\AppData\FreeCAD /home/username/.FreeCAD
UserParameter Chemin où FreeCAD met les fichier utilisateur de l'application. C:\Documents and Settings\username\AppData\FreeCAD\user.cfg /home/username/.FreeCAD/user.cfg
SystemParameter Fichier où sont les données de l'application. C:\Documents and Settings\username\AppData\FreeCAD\system.cfg /home/username/.FreeCAD/system.cfg
UserHomePath Chemin racine de l'utilisateur courant. C:\Documents and Settings\username\My Documents /home/username

Arguments en ligne de commande

Entrées de configuration utilisateur
Nom var config Synopsis Exemple
LoggingFile 1 si l'enregistrement est activé 1
LoggingFileName Nom du fichier ou le joural est placé C:\Documents and Settings\username\AppData\FreeCAD\FreeCAD.log
RunMode Cela indique comment la boucle principale travaillera. "Script" signifie que le script donné est appelé puis quitté. "Cmd" est destiné à l’interpréteur en ligne de commande. "Internal" exécute un script interne. "Gui" entre dans la boucle d'évènement Gui. "Module" charge un module Python donné. "Cmd"
FileName Dépend du RunMode
ScriptFileName Dépend du RunMode
Verbose Niveau de verbosité de FreeCAD "" or "strict"
OpenFileCount Donne le nombre de dossiers ouverts par les arguments en ligne de commande "12"
AdditionalModulePaths Contient les chemins des modules supplémentaires donnés dans la ligne de commande "extraModules/"

Relations au système

L'appel se fait de la manière suivante :

path = FreeCAD.ConfigGet("AppHomePath")
Entrées de configuration utilisateur
Nom var config Synopsis Exemple M$ Exemple Posix (Linux)
AppHomePath Chemin où est installé FreeCAD c:/Progam Files/FreeCAD_0.7 /user/local/FreeCAD_0.7
PythonSearchPath Donne une liste de chemins que les modules Python recherchent. S'effectue au démarrage, et peut changer en cours d'exécution

Exemple d’exécution d'un fichier

Ligne de commande pour exécuter un fichier
Fichier a exécuter Système Command line configuration
Module, cfg Windows "C:\Program Files\FreeCAD\bin\FreeCAD.exe" -M "C:\FreeCAD\Mod\Draft" -u "C:\FreeCAD\Config\user.cfg" -s "C:\FreeCAD\Config\system.cfg"
Linux todo
.FCMacro or .py Windows "C:\Program Files\FreeCAD\bin\FreeCAD.exe" "C:\Users\userName\AppData\Roaming\FreeCAD\Mod\WorkFeature\start_WF.FCMacro"
Linux todo


Certaines bibliothèques ont besoin d'appeler les variables d'environnement système. Parfois, lorsqu'il y a des problèmes avec une installation de FreeCAD, c'est que certaines variables d'environnements sont absentes ou mal réglées. C'est pour cela que certaines variables importantes sont dupliquées dans la configuration et enregistrées dans le fichier journal (log file).

Variables d’environnement relatives à Python :

  • PYTHONPATH
  • PYTHONHOME
  • TCL_LIBRARY
  • TCLLIBPATH

Variables d’environnement relatives à OpenCascade :

  • CSF_MDTVFontDirectory
  • CSF_MDTVTexturesDirectory
  • CSF_UnitsDefinition
  • CSF_UnitsLexicon
  • CSF_StandardDefaults
  • CSF_PluginDefaults
  • CSF_LANGUAGE
  • CSF_SHMessage
  • CSF_XCAFDefaults
  • CSF_GraphicShr
  • CSF_IGESDefaults
  • CSF_STEPDefaults

Variables d’environnement relatives au Système :

  • PATH

Informations relatives à la version

Le tableau ci-dessous montre les informations générées par la version disponible. La plupart proviennent du dépôt de sous-version. Cette astuce est nécessaire pour reconstruire exactement une version !

Entrées de configuration utilisateur
Nom var config Synopsis Exemple
BuildVersionMajor Numéro de version majeure de la construction. Définie dans src/Build/Version.h.in 0
BuildVersionMinor Numéro de version mineure de la construction. Définie dans src/Build/Version.h.in 7
BuildRevision Numéro de révision du référentiel SVN du src de construction. Généré par SVN 356
BuildRevisionRange Gamme de différents changements 123-356
BuildRepositoryURL URL de référence https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk/src
BuildRevisionDate Date de la révision ci-dessus 2007/02/03 22:21:18
BuildScrClean Indique si la source a été modifiée après la dernière construction Src modifié
BuildScrMixed Src non mixé

Identité liée à la marque

Ces entrées de configuration sont liées au dispositif d'identification à la marque FreeCAD. Voir Branding pour plus de renseignements.

Entrées de configuration utilisateur
Nom var config Synopsis Exemple
ExeName Nom du fichier exécutable de compilation. Ce nom peut être différent de FreeCAD si un main.cpp différent est utilisé. FreeCAD.exe
ExeVersion La version présente au moment de la compilation V0.7
AppIcon L'icône qui est utilisé pour l'exécutable, affichée dans la fenêtre principale d'application "FCIcon"
ConsoleBanner Bannière du prompt en mode console
SplashPicture Nom de l'icône utilisée pour l'écran de démarrage "FreeCADSplasher"
SplashAlignment Alignement du texte dans la boîte de dialogue Splash "Bottom" ou "Left"
SplashTextColor Couleur du texte splashé "#000000"
StartWorkbench Nom de l'atelier lancé automatiquement après le démarrage "Part design"
HiddenDockWindow Liste des dockwindows (séparés par un point-virgule) qui seront désactivés "Property editor"

Pages connexes

Arrow-left.svg Page précédente: Outils tiers
Arrow-left.svg Page précédente: Démarrage et Configuration
Page suivante: Création de module Arrow-right.svg

L'outil de construction de FreeCAD ou fcbt est un script python qui se trouve ici :

trunc/src/Tools/fcbt.py

Il peut être utilisé, pour simplifier certaines tâches fréquemment utilisées dans la construction (compilation), la distribution, et, l'extension de FreeCAD.

Utilisation

Quand Python est correctement installé, fcbt peut être invoqué par la commande :

python fbct.py

Il affiche un menu, où vous pouvez sélectionner la tâche, que vous souhaitez utiliser pour :

FreeCAD Build Tool
 Usage:
    fcbt <command name> [command parameter]
 possible commands are:
  - DistSrc         (DS)   Build a source Distr. of the current source tree
  - DistBin         (DB)   Build a binary Distr. of the current source tree
  - DistSetup       (DI)   Build a Setup Distr. of the current source tree
  - DistSetup       (DUI)  Build a User Setup Distr. of the current source tree
  - DistAll         (DA)   Run all three above modules
  - NextBuildNumber (NBN)  Increase the Build Number of this Version
  - CreateModule    (CM)   Insert a new FreeCAD Module in the module directory
 
 For help on the modules type:
   fcbt <command name> ?

À l'invite de commande, entrez la commande abrégée que vous voulez appeler. Par exemple, tapez «CM» pour la création d'un module.

DistSrc

La commande "DS" Crée le source de la distribution de l'arborescence source en court.

DistBin

La commande "DB" Créer une distribution binaire de l'arborescence source en court.

DistSetup

La commande "DI" crée une distribution d'installation de l'arborescence source en court.

DistSetup

La commande "DUI" crée une distribution de configuration utilisateur de l'arborescence source en court.

DistAll

La commande "DA" exécute les séquences "DS", "DB" et "DI".

NextBuildNumber

La commande "NBN" incrémente le numéro de compilation pour créer une nouvelle version de FreeCAD.

CreateModule

La commande "CM" crée un nouveau module de l'application.

Arrow-left.svg Page précédente: Démarrage et Configuration
Page suivante: Création de module Arrow-right.svg
Arrow-left.svg Page précédente: FreeCAD Build Tool
Page suivante: Debugging Arrow-right.svg

Ajouter de nouveaux modules et boîtes à outils dans FreeCAD est très facile. Nous appelons module, toute extension de FreeCAD, tandis qu'un plan de travail (workbench) est une configuration spéciale GUI, habituellement, les groupes de barres d'outils et de menus. Vous créez un nouveau module qui contient son propre plan de travail (sa barre d'outils et ses commandes).

Les modules peuvent être programmés en C++ ou en Python, ou un mélange des deux, mais les fichiers de module d'initialisation, doivent être en Python. La mise en place d'un nouveau module, avec les fichiers d'initialisation est facile, et, peut être effectuée, soit manuellement, soit avec l'outil build de FreeCAD.

Utilisation des outils de FreeCAD

La création d'un nouveau module dans FreeCAD est assez simple. Dans l'arborescence de développement de FreeCAD, il existe l'outil FreeCAD Build Tool (fcbt) qui, fait les choses les plus importantes pour vous.
Il s'agit d'un script Python situé à :

trunk/src/Tools/fcbt.py

Lorsque votre interpréteur Python est correctement installé, vous pouvez exécuter le script en ligne de commande avec :

python fcbt.py

Le menu suivant s'afficher :

FreeCAD Build Tool
Usage:
   fcbt <command name> [command parameter] 
possible commands are:
 - DistSrc         (DS)   Build a source Distr. of the current source tree
 - DistBin         (DB)   Build a binary Distr. of the current source tree
 - DistSetup       (DI)   Build a Setup Distr. of the current source tree
 - DistSetup       (DUI)  Build a User Setup Distr. of the current source tree
 - DistAll         (DA)   Run all three above modules
 - NextBuildNumber (NBN)  Increase the Build Number of this Version
 - CreateModule    (CM)   Insert a new FreeCAD Module in the module directory
 - CreatePyModule  (CP)   Insert a new FreeCAD Python Module in the module directory

For help on the modules type:
  fcbt <command name> ?

À l'invite de comande, entrez CM pour commencer la création d'un module :

Insert command: ''CM''

Vous êtes maintenant invité à spécifier un nom pour votre nouveau module.
Appelons le TestMod par exemple :

Please enter a name for your application: ''TestMod''

Après avoir validé, fcbt commence à copier, tous les fichiers nécessaires pour votre module dans un nouveau dossier, à :

trunk/src/Mod/TestMod/

Puis, tous les fichiers sont modifiés avec votre nouveau nom de module. La seule chose que vous devez faire maintenant, est d'ajouter les deux nouveaux projets, "appTestMod" et "appTestModGui", à votre espace de travail (sous Windows) ou à vos objectifs Makefile (unix). C'est tout !

Mise en place d'un nouveau module manuellement

Vous avez besoin de deux choses, pour créer un nouveau module :

  • Un nouveau dossier dans le dossier Mod de FreeCAD (soit dans Installationd_Path/FreeCAD/Mod ou dans UserPath/.FreeCAD/Mod). Vous pouvez le nommer comme vous le souhaitez.
  • Dans ce dossier, il y a un fichier InitGui.py. Ce fichier sera automatiquement exécuté au démarrage de FreeCAD (par ex, mettre un print("Bonjour tout le monde") à l'intérieur)

En outre, vous pouvez également ajouter un fichier Init.py. La différence est, que le fichier InitGui.py n'est chargé que lorsque FreeCAD fonctionne en mode graphique (InitGUI), et, le fichier Init.py est toujours chargé. Mais si nous faisons un plan de travail (workbench), nous allons le mettre en InitGui.py, parce les outils, sont utilisés uniquement en mode GUI, bien sûr.

Création de nouveaux outils

Une des premières choses que vous voudrez faire, est de définir un plan de travail dans le fichier InitGui.py.
Voici un petit code que vous pouvez utiliser :

class MyWorkbench ( Workbench ):
	"My workbench object"
	Icon = """
			/* XPM */
			static const char *test_icon[]={
			"16 16 2 1",
			"a c #000000",
			". c None",
			"................",
			"................",
			"..############..",
			"..############..",
			"..############..",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"................",
			"................"};
			"""
	MenuText = "My Workbench"
	ToolTip = "This is my extraordinary workbench"

        def GetClassName(self):
               return "Gui::PythonWorkbench"
	
	def Initialize(self):
		import myModule1, myModule2
		self.appendToolbar("My Tools", ["MyCommand1","MyCommand2"])
		self.appendMenu("My Tools", ["MyCommand1","MyCommand2"])
		Log ("Loading MyModule... done\n")

	def Activated(self):
               # do something here if needed...
		Msg ("MyWorkbench.Activated()\n")

	def Deactivated(self):
               # do something here if needed...
		Msg ("MyWorkbench.Deactivated()\n")

FreeCADGui.addWorkbench(MyWorkbench)

L'atelier (boîte à outils) doit disposer de toutes ces définissions (attributs) :

  • Icon L'attribut Icon est une image XPM (La plupart des logiciels tel que GIMP permet de convertir une image en format xpm, qui, est un simple fichier texte. Vous pouvez ensuite coller le contenu ici).
  • MenuText est le nom établi tel qu'il apparaîtra dans la liste établis (boîte à outils).
  • Tooltip (Info-bulle) s'affiche lorsque vous le survolez avec la souris.
  • Initialize() est exécuté au chargement de FreeCAD, et doit créer tous les menus, et, barres d'outils que le plan de travail (workbench) va utiliser. Si vous faites votre module en C++, vous pouvez aussi définir vos menus et barres d'outils à l'intérieur du module C++, et pas dans le fichier InitGui.py. L'important est, qu'il soit créé maintenant, et pas lorsque le module est activé.
  • Activated() est exécuté, lorsque l'utilisateur bascule sur votre plan de travail (module).
  • Deactivated() est exécuté, lorsque l'utilisateur bascule de vôtre atelier (module), à un autre atelier (module) ou, quitte FreeCAD

Creation de commandes FreeCAD en Python

Habituellement, vous définissez tous vos outils (appelés commandes dans FreeCAD), dans un autre module, puis importez ce module, avant de créer les barres d'outils et de menus.
Il s'agit ici d'un code minimum, que vous pouvez utiliser pour définir une commande :

import FreeCAD,FreeCADGui

class MyTool:
	"My tool object"

       def GetResources(self):
               return {"MenuText": "My Command",
                       "Accel": "Ctrl+M",
                       "ToolTip": "My extraordinary command",
                       "Pixmap"  : """
			/* XPM */
			static const char *test_icon[]={
			"16 16 2 1",
			"a c #000000",
			". c None",
			"................",
			"................",
			"..############..",
			"..############..",
			"..############..",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"......####......",
			"................",
			"................"};
			"""}

       def IsActive(self):
               if FreeCAD.ActiveDocument == None:
                       return False
               else:
                       return True

	def Activated(self):
               # do something here...

FreeCADGui.addCommand('MyCommand1',MyTool())
  • La méthode GetResources() doit retourner un dictionnaire avec les attributs visuels de votre outil. Accel, définit une touche de raccourci, mais, n'est pas obligatoire.
  • IsActive() définit si la commande est active, ou grisée dans les menus, et, barres d'outils.
  • La méthode Activated() est exécutée lorsque la commande est appelée par un bouton de la barre d'outils, ou dans le menu, ou même par le script.

Création d'une commande FreeCAD en C++

Bientôt documentée.

Liens

  • Quelques exemples d'utilisateurs avancés de FreeCAD avec divers établis externes personnalisés sont rassemblés dans Ateliers externes.
  • Autre exemple dans le hub utilisateur puissant Création d'atelier
  • Création de commandes Command
Arrow-left.svg Page précédente: FreeCAD Build Tool
Page suivante: Debugging Arrow-right.svg
Arrow-left.svg Page précédente: Module Creation
Page suivante: Testing Arrow-right.svg

Premiers tests

Avant de passer à la douloureuse phase de débogage, utilisez le Test framework, pour vérifier, si les tests standards fonctionnent correctement. Si ce n'est pas le cas, c'est peut-être dû a une installation défectueuse.

Ligne de commande

Le débogage de FreeCAD est supporté par quelques mécanismes internes. La version en ligne de commande de FreeCAD fournit des options d'aide au débogage :

Ce sont les options actuellement reconnues par FreeCAD 0.15:

Options Génériques:

 -v [ --version ]      Affiche la version sous la forme d'une chaîne
 -h [ --help ]         Affiche un message d'aide
 -c [ --console ]      Démarre en mode console
 --response-file arg   Peut aussi être spécifié avec '@name'

Configuration:

 -l [ --write-log ]       Ecrit un fichier journal dans:
                          $HOME/.FreeCAD/FreeCAD.log
 --log-file arg           Contrairement à --write-log cela permet de se connecter à un
                          fichier arbitraire
 -u [ --user-cfg ] arg    Fichier de configuration utilisateur pour charger/enregistrer les paramètres utilisateur
 -s [ --system-cfg ] arg  fichier de configuration pour charger/enregistrer les paramètres du système
 -t [ --run-test ] arg    Niveau de test
 -M [ --module-path ] arg Chemin de module supplémentaire
 -P [ --python-path ] arg Autres chemins python

Générer un Backtrace

Si vous exécutez une version de FreeCAD à partir de l'extrémité saillante de la courbe de développement, il se peut qu'il se "bloque". Vous pouvez aider à résoudre ces problèmes en fournissant aux développeurs une "backtrace". Pour ce faire, vous devez exécuter une "version de débogage" du logiciel. "Debug build" est un paramètre qui est défini au moment de la compilation, donc vous devrez soit compiler vous-même FreeCAD, soit obtenir une version "debug" précompilée.

For Linux

Linux Debugging ---->

Prerequisites:

  • logiciel gdb installé
  • une version de débogage de FreeCAD (à ce moment seulement disponible par Pour une compilation "Debug")
  • un modèle FreeCAD qui provoque un crash

Étapes: Entrez ce qui suit dans votre fenêtre de terminal:

$ cd FreeCAD/bin
$ gdb FreeCAD

GNUdebugger will output some initializing information. The (gdb) shows GNUDebugger is running in the terminal, now input:

(gdb) handle SIG33 noprint nostop
(gdb) run

FreeCAD va maintenant démarrer. Effectuez les étapes qui provoquent le crash ou le blocage de FreeCAD, puis entrez dans la fenêtre du terminal :

(gdb) bt

Cela va générer une longue liste de ce que le programme faisait quand il s'est planté ou gelé. Incluez ceci avec votre rapport de problème.

(gdb) bt full

Afficher également les valeurs des variables locales. Ceci peut être combiné avec un nombre pour limiter le nombre d'images affichées.

Pour MacOSX

MacOSX Debugging ---->

Prerequisites:

  • logiciel lldb installé
  • une version de débogage de FreeCAD
  • un modèle FreeCAD qui provoque un crash

Étapes: Entrez ce qui suit dans la fenêtre de votre terminal:

$ cd FreeCAD/bin
$ lldb FreeCAD

LLDB will output some initializing information. The (lldb) shows the debugger is running in the terminal, now input:

(lldb) run

FreeCAD va maintenant démarrer. Effectuez les étapes qui provoquent le crash ou le blocage de FreeCAD, puis entrez dans la fenêtre du terminal:

(lldb) bt

Cela va générer une longue liste de ce que le programme faisait quand il s'est bloqué ou arrêté. Incluez ceci avec votre rapport de problème.

Python Debugging

Pour une approche plus moderne du débogage, du moins sur Windows, ici dans le forum.

winpdb

winpdb Debugging ---->

Voici un exemple d'usage de Winpdb dans FreeCAD :

Nous avons besoin du débogueur python : Winpdb. Si vous ne l'avez pas installé, vous pouvez le faire sous Ubuntu/Debian avec :

sudo apt-get install winpdb

Vous pouvez maintenant configurer le débogueur.

  1. Démarrez Winpdb.
  2. Définissez le mot de passe du débogueur sur "test" : Allez dans le menu Fichier -> Mot de passe et définissez le mot de passe.

Nous allons maintenant exécuter étape par étape un script de test python dans FreeCAD.

  1. Lancez winpdb et définissez le mot de passe (par exemple, test)
  2. Créer un fichier Python avec ce contenu
import rpdb2
rpdb2.start_embedded_debugger("test")
import FreeCAD
import Part
import Draft
print "hello"
print "hello"
import Draft
points=[FreeCAD.Vector(-3.0,-1.0,0.0),FreeCAD.Vector(-2.0,0.0,0.0)]
Draft.makeWire(points,closed=False,face=False,support=None)
  1. Démarrer FreeCAD et charger le fichier ci-dessus dans FreeCAD
  2. Appuyez sur F6 pour l'exécuter
  3. Maintenant, FreeCAD ne répondra plus car le débogueur Python attend
  4. Passez à l'interface graphique de Windpdb et cliquez sur "Attacher". Après quelques secondes, un élément "<Input>" apparaît où vous devez double-cliquer
  5. Maintenant, le script actuellement exécuté apparaît dans Winpdb.
  6. Définir une pause à la dernière ligne et appuyez sur F5
  7. Maintenant, appuyez sur F7 pour entrer dans le code Python de Draft.makeWire

Code Visual Studio (VS Code)

VS Code Debugging ---->

Prérequis :

  • Le paquet ptvsd doit être installé
    pip install ptvsd
    Page pypi

Documentation du code Visual Studio pour debugging à distance

Étapes :

  • Ajoutez le code suivant au début de votre script
import ptvsd
print("Waiting for debugger attach")
# 5678 is the default attach port in the VS Code debug configurations
ptvsd.enable_attach(address=('localhost', 5678), redirect_output=True)
ptvsd.wait_for_attach()
  • Ajoutez une configuration de débogage dans le Code Visual Studio Debug → Add Configurations…. Cela devrait ressembler à ceci :
    "configurations": [
        {
            "name": "Python: Attacher",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "localhost",
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}",
                    "remoteRoot": "."
                }
            ]
        },
  • Dans VS Code, ajoutez un point d'arrêt n'importe où.
  • Lancez le script dans FreeCAD. FreeCAD gèle en attente de la pièce jointe.
  • Dans VS Code, démarrez le débogage avec la configuration créée. Vous devriez voir les variables dans la zone du débogueur.
Arrow-left.svg Page précédente: Module Creation
Page suivante: Testing Arrow-right.svg
Arrow-left.svg Page précédente: Debugging
Page suivante: Intégration continue Arrow-right.svg

Workbench Test.svg

Introduction

L'atelier Testez n'est pas vraiment un atelier de modélisation, mais il contient un ensemble de scripts Python permettant d'effectuer différents tests sur les composants principaux de FreeCAD, afin de résoudre les problèmes. Voir aussi Debugging.

Vous pouvez lancer les tests depuis la ligne de commande.

Lancer tous les tests :

freecad --run-test 0

Exécutez uniquement quelques tests spécifiques, par exemple :

freecad --run-test TestDraft

Fonctions de test

Voici la liste des applications de test à partir de 0.15 Git 4207 :

TestAPP.All

Ajoute la fonction de test

BaseTests

Ajoute la fonction de test

UnitTests

Ajoute la fonction de test

Document

Ajoute la fonction de test

UnicodeTests

Ajoute la fonction de test

MeshTestsApp

Ajoute la fonction de test

TestDraft

Ajoute la fonction de test

TestSketcherApp

Ajoute la fonction de test

TestPartApp

Ajoute la fonction de test

TestPartDesignApp

Ajoute la fonction de test

Workbench

Ajoute la fonction de test

Menu

Ajoute la fonction de test

Menu.MenuDeleteCases

Ajoute la fonction de test

Menu.MenuCreateCases

Ajoute la fonction de test

Arrow-left.svg Page précédente: Debugging
Page suivante: Intégration continue Arrow-right.svg
Arrow-left.svg Page précédente: Intégration continue
Page suivante: Localisation Arrow-right.svg

Cet article décrit l'identification à la marque FreeCAD. Branding revient à lancer votre propre application, sur les bases de FreeCAD. Cela concerne juste votre propre exécutable ou votre écran de démarrage, jusqu'à une refonte complète du programme. Grace à l'architecture flexible de FreeCAD, il est facile d'utiliser sa base comme fondation pour votre propre programme spécifique.

Generalités

La plupart des marques (branding) se font dans MainCmd.cpp, ou, MainGui.cpp. Ces projets génèrent les fichiers exécutables de FreeCAD.

Pour faire votre propre marque (branding), il suffit de copier Main (les projets principaux) ou MainGui (les projets graphiques GUI), et donner à l'exécutable un nom qui vous est propre, pour notre exemple, FooApp.exe. Les paramètres les plus importants pour un nouveau look, ne peuvent être fait qu'en un seul endroit, dans la fonction main().

Voici la section de code qui contrôle la marque (branding) :

 int main( int argc, char ** argv )
 {
   // Name and Version of the Application
   App::Application::Config()["ExeName"] = "FooApp";
   App::Application::Config()["ExeVersion"] = "0.7";
 
   // set the banner (for loging and console)
   App::Application::Config()["CopyrightInfo"] = sBanner;
   App::Application::Config()["AppIcon"] = "FooAppIcon";
   App::Application::Config()["SplashScreen"] = "FooAppSplasher";
   App::Application::Config()["StartWorkbench"] = "Part design";
   App::Application::Config()["HiddenDockWindow"] = "Property editor";
   App::Application::Config()["SplashAlignment" ] = "Bottom|Left";
   App::Application::Config()["SplashTextColor" ] = "#000000"; // black
 
   // Inits the Application 
   App::Application::Config()["RunMode"] = "Gui";
   App::Application::init(argc,argv);
 
   Gui::BitmapFactory().addXPM("FooAppSplasher", ( const char** ) splash_screen);
 
   Gui::Application::initApplication();
   Gui::Application::runApplication();
   App::Application::destruct();
 
   return 0;
 }

La première entrée, ::Config définit le nom du programme ici, "FooApp.exe". Ce n'est pas le nom de l'exécutable qui peut être modifié en le renommant, ou par les paramètres du compilateur, mais le nom qui est affiché dans la barre des tâches sur les fenêtres, ou dans la liste des programmes sur les systèmes Unix.

Les lignes suivantes définissent les entrées de configuration de votre application "FooApp", une description de la configuration, et de ses entrées, que vous trouverez dans Start up and Configuration.

Images

Les ressources contenant les images sont compilées dans FreeCAD à l'aide de Qt's resource system. Par conséquent, vous devez écrire un fichier .qrc, un format de fichier basé sur XML qui répertorie les fichiers image sur le disque, mais également tout autre type de fichier de ressources. Pour charger les ressources compilées dans l'application, vous devez ajouter une ligne

Q_INIT_RESOURCE(FooApp);

dans la fonction main(). Sinon, si vous avez une image au format XPM, vous pouvez directement l'inclure dans votre main.cpp puis ajoutez la ligne suivante pour l'enregistrer:

Gui::BitmapFactory().addXPM("FooAppSplasher", ( const char** ) splash_screen);

Branding XML

Dans FreeCAD, une méthode est également prise en charge sans écrire de fonction main() personnalisée. Pour cette méthode, vous devez écrire un nom de fichier appelé branding.xml et le placer dans le répertoire d'installation de FreeCAD. Voici un exemple avec toutes les balises prises en charge:

 <?xml version="1.0" encoding="utf-8"?>
 <Branding>
 	<Application>FooApp</Application>
 	<WindowTitle>Foo App in title bar</WindowTitle>
 	<BuildVersionMajor>1</BuildVersionMajor>
 	<BuildVersionMinor>0</BuildVersionMinor>
 	<BuildRevision>1234</BuildRevision>
 	<BuildRevisionDate>2014/1/1</BuildRevisionDate>
 	<CopyrightInfo>(c) My copyright</CopyrightInfo>
 	<MaintainerUrl>Foo App URL</MaintainerUrl>
 	<ProgramLogo>Path to logo (appears in bottom right corner)</ProgramLogo>
 	<WindowIcon>Path to icon file</WindowIcon>
 	<ProgramIcons>Path to program icons</ProgramIcons>
 	<SplashScreen>splashscreen.png</SplashScreen>
 	<SplashAlignment>Bottom|Left</SplashAlignment>
 	<SplashTextColor>#ffffff</SplashTextColor>
 	<SplashInfoColor>#c8c8c8</SplashInfoColor>
 	<StartWorkbench>PartDesignWorkbench</StartWorkbench>
 </Branding>

Toutes les balises répertoriées sont facultatives.

Arrow-left.svg Page précédente: Intégration continue
Page suivante: Localisation Arrow-right.svg
Arrow-left.svg Page précédente: Image de marque
Page suivante: Modules Extra Python Arrow-right.svg

La localisation en général, est le processus de fourniture d'un logiciel avec une interface utilisateur en plusieurs langues. Dans FreeCAD vous pouvez définir la langue d'interface utilisateur dans le menu Édition → Préférences → Général → Onglet Général → Langue. FreeCAD utilise Qt pour activer le support de plusieurs langues. Sur les systèmes Unix/Linux, FreeCAD utilise les paramètres régionaux actuels de votre système par défaut.

Aider à la traduction de FreeCAD

Une des choses importantes que les utilisateurs peuvent apporter à FreeCAD (s’ils ne possèdent pas de compétences en programmation, par exemple) est d’aider à traduire ses différents aspects (code source, wiki, site Web, documentation, etc.) dans une autre langue. Voici les moyens de le faire.

Traduire le code source de FreeCAD

FreeCAD utilise un système de traduction en ligne tiers collaboratif appelé Crowdin. C'est un logiciel propriétaire mais gratuit pour les projets FOSS. Vous trouverez ci-dessous des instructions pour l’utiliser :

  • Aller à la page du projet de traduction de FreeCAD sur Crowdin ;
  • Connectez-vous en créant un nouveau profil, ou en utilisant un compte tiers, comme votre adresse (GitHub, GitLab, GMail etc...) ;
  • Cliquez sur la langue que vous souhaitez traduire ;
  • Commencez la traduction en cliquant sur ​​le bouton Translate à côté d'un des fichiers. Par exemple, FreeCAD.ts contient les chaînes de texte pour l'interface principale de FreeCAD ;
  • Vous pouvez voter pour les traductions existantes, ou créer une nouvelle traduction.
Si vous prenez une part active dans la traduction de FreeCAD, et que vous voulez être informé avant le lancement de la prochaine version, afin d'avoir le temps de revoir votre traduction, veuillez s'il vous plaît vous inscrire à une des équipes de traduction de FreeCAD sur Crowdin.


Traduire le wiki FreeCAD

Ce wiki héberge un contenu volumineux, dont l'essentiel sert à produire le manuel. Vous pouvez naviguer dans la documentation à partir de la Page principale, ou consulter la table des matières du guide utilisateur.

Pour pouvoir traduire le wiki, vous devez bien sûr obtenir les droits d'édition au wiki.

Il est recommandé d'avoir des connaissances de base du formatage de style wiki et des directives générales du wiki FreeCAD, car vous devrez ajuster le code de balisage lors des traductions. Vous trouverez cette information sur la page WikiPages(en).

Extension de traduction Mediawiki

Après le départ du wiki de SourceForge, Yorik a installé un plugin de traduction MediaWiki qui facilite les traductions de pages. Les avantages de l'extension de traduction sont que le titre de la page peut maintenant être traduit, qu'il garde une trace des traductions, qu'il informe si la page d'origine a été mise à jour et qu'il maintient la synchronisation des traductions avec la page anglaise d'origine.

L'outil est documenté dans MediaWiki Traduire, et fait partie du MediaWiki Language Extension Bundle.

Pour commencer rapidement la préparation d'une page pour la traduction et activer le plugin, veuillez lire l'Exemple de traduction de page. Essentiellement, une paire de balises <translate> ... </translate> doit entourer la page entière pour activer le système de traduction, et la page doit être marquée pour traduction.

Pour voir un exemple de comment l'outil de traduction fonctionne, vous pouvez visiter la Page principale. Vous verrez qu'une barre de menu de langues est automatiquement générée en haut de page. Cliquez par exemple sur le lien français, et vous serez redirigé sur WIKI: Page principale (française). Juste sous le titre, vous pourrez lire Cette page est une version traduite de la page Main Page et la traduction est complétée à XX %. (XX étant le pourcentage de traduction réalisé). Cliquez sur le lien "version traduite" pour lancer l'utilitaire de traduction pour mettre à jour, corriger ou revoir une traduction existante.

Si vous allez sur WIKI: Page principale (française), Vous remarquerez que vous ne pouvez plus éditer directement une page une fois qu'elle a été marquée pour traduction. Vous devez passer par l'outil de traduction.

Lors de l'ajout de nouveau contenu, la page anglaise devrait être créée en premier, puis traduite dans une autre langue. Si vous désirez changer ou ajouter du contenu dans une page, la modification doit en premier se faire dans la page anglaise.

Si vous ne savez pas comment procéder, n'hésitez pas à demander de l'aide dans le sous-forum Development → Wiki du forum FreeCAD ou dans le sous-forum Forums in other languages du langage concerné.

Notes importantes

Chaque utilisateur du wiki disposant des autorisations "Éditeur" peut lancer l'utilitaire de traduction et écrire, enregistrer et réviser les traductions.

Cependant, seuls les utilisateurs disposant des autorisations "Administrateur" peuvent marquer des pages pour traduction. Une page qui n'est pas marquée pour la traduction n'utilisera pas l'extension de traduction et ne sera pas correctement synchronisée avec les informations en anglais.

La barre latérale de gauche peut aussi être traduite. Veuillez suivre les instructions dédiées sur la page Barre latérale locale.

La première fois que vous basculez une page vers le nouveau système de traduction, toutes les anciennes traductions "manuelles" sont perdues. Pour récupérer une traduction, vous devez enregistrer une copie hors ligne de l'ancien texte avant le changement. Vous pouvez ensuite utiliser cet ancien texte traduit pour renseigner les unités de traduction du nouveau système. Vous pouvez également ouvrir une version antérieure de l'historique et récupérer l'ancien texte de cette manière. Cela doit être fait pour chaque langue ayant une page traduite.

Traduire la documentation de FreeCAD

Conformément au consensus général, la page de référence dans le wiki est la page anglaise, qui devrait être créée en premier. Si vous souhaitez modifier ou ajouter du contenu à une page, vous devez d'abord le faire sur la page anglaise, puis reporter la modification sur la page traduite une fois la mise à jour terminée.

Anciennes instructions de traduction

Ces instructions sont pour l'historique seulement. Les traductions doivent utiliser le nouveau système avec Mediawiki Extension de traduction décrite ci-dessus.

La première étape consiste donc à vérifier si la traduction manuelle a déjà été commencée pour votre langue (regardez dans la barre latérale gauche, sous "manuel").
Sinon, rendez-vous sur le forum et dites que vous souhaitez commencer une nouvelle traduction, nous créerons la configuration de base de la langue sur laquelle vous souhaitez travailler.
Vous devez alors obtenir l'autorisation de modification du wiki.
Si votre langue est déjà listée, voyez quelles pages n'ont toujours pas de traduction (elles seront listées en rouge). La technique est simple: allez dans une page rouge, copiez/collez le contenu de la page anglaise correspondante et commencez à traduire.
N'oubliez pas d'inclure tous les tags et modèles de la page anglaise d'origine. Certains de ces modèles auront un équivalent dans votre langue (par exemple, il existe un modèle Docnav français appelé Docnav/fr). Vous devez utiliser une barre oblique et votre code de langue dans presque tous les liens. Consultez d'autres pages déjà traduites pour voir comment elles l'ont fait.
Ajoutez une barre oblique et votre code de langue dans les catégories, comme [[Category:Developer Documentation/fr]]
Si vous avez des doutes, dirigez-vous vers les forums et demandez aux gens de vérifier ce que vous avez fait et vous dire si c'est bien fait ou non.
Quatre modèles sont couramment utilisés dans les pages de manuel. Ces 4 modèles ont des versions localisées (Modèle: Docnav/fr, Modèle: fr, etc ...)

  • Template:GuiCommand/fr: est le bloc d'informations de la commande Gui en haut à droite de la documentation de la commande.
  • Template:Docnav/fr: c'est la barre de navigation au bas des pages, montrant les pages précédentes et suivantes.
  • Template:Userdocnavi/fr : donne des liens directs vers les pages de base principales.

Page Naming Convention
Veuillez noter que, en raison des limitations de l'implémentation du moteur MediaWiki par Sourceforge, nous exigeons que vos pages conservent toutes le nom de leur homologue anglais d'origine, en ajoutant une barre oblique et votre code de langue. Par exemple, la page traduite pour À propos de FreeCAD devrait être About FreeCAD/es pour l’espagnol, About FreeCAD/pl pour le polonais, etc. saura à quoi servent ces pages. Cela facilitera la maintenance et évitera les pages perdues.
Si vous souhaitez que le modèle Docnav affiche les pages liées dans votre langue, vous pouvez utiliser les pages de redirection. Elles sont essentiellement des liens de raccourci vers la page réelle. Voici un exemple avec la page française de About FreeCAD.

  • La page About_FreeCAD/fr est la page avec le contenu
  • La page About_FreeCAD contient ce code:
 #REDIRECT [[About_FreeCAD/fr]] 
  • Dans la page About FreeCAD/fr, le code Docnav ressemblera à ceci:
{{docnav/fr|[[Online_Help_Startpage/fr|Bienvenue dans l'aide en ligne de FreeCAD]]|[[Feature_list/fr|Fonctionnalités]]}}

La page "Bienvenue sur l'aide en ligne" redirige vers l'aide en ligne Startpage/fr et la page "Fonctionnalités" redirige Feature_list/fr.

Traduire le site Web FreeCAD

La traduction du site Web FreeCAD est maintenant effectuée par le biais de Crowdin. Le fichier est nommé homepage.po.

Développement - Comment ajouter une localisation

Cette section est destinée aux développeurs qui souhaitent ajouter la localisation dans leur code.

Préparer vos propres modules ou applications pour la traduction

Voici les parties du processus de traduction de FreeCAD :

  • extraire les chaînes de texte du code source dans des fichiers *.ts
  • télécharger les fichiers *.ts dans le Crowdin FreeCAD.
  • traduire les chaînes dans Crowdin
  • extraire les nouveau fichiers ou fichiers modifiés *.ts de Crowdin
  • convertir les fichiers *.ts en fichiers *.qm et mettre à jour le fichier *.qrc de chaque module
  • mettre à jour la branche master de FreeCAD

Toutes les étapes listées ci-dessus sont exécutées par des "scripts de traduction" qui sont lancés périodiquement par un administrateur.

Préparer votre module à la traduction est très facile. D'abord, assurez-vous de créer un répertoire "translations" dans myModule/Gui/Resources. Puis ouvrez une fenêtre de terminal (ou l'équivalent Windows/OSX) dans votre répertoire "translations", et saisissez la commande suivante :

lupdate -ts myModule.ts

Ceci crée un fichier de traduction vide. Une fois cette tâche complétée, vous devez vous assurer que les scripts de traduction sont mis à jour comme dans cette pull request.

La suite se fait automatiquement, en ce qui concerne le développeur. L'administrateur fera l'extraction des chaînes de texte, les traducteurs les traduiront, puis l'administrateur extraira les traductions et mettra à jour la branche FreeCAD/master.

Préparer votre module de tierce partie ou macro pour la traduction

Les modules de tierce partie ou macros sont traduits de façon similaire, mais vous devez vous charger d'une partie du travail. Cette discussion sur le forum (en anglais) décrit les détails.

Anciennes techniques de traduction des modules

la page Ancienne méthode de localisation décrit l'utilisation d'outils de traduction tels que Qt Linguist, lupdate, lrelease, pylupdate4, etc. en détail. La plupart de ces opérations ne sont plus nécessaires pour les modules FreeCAD/master, mais peuvent s'avérer utiles pour préparer et mettre à jour des modules tiers.

Automatiser les mises à jour de translations Crowdin

Actuellement, les mainteneurs de FreeCAD utilisent l’API Crowdin via Crowdin Scripts pour extraire et transférer les traductions vers Crowdin, puis vers le dépôt Github. L'API Crowdin donne aux responsables de FreeCAD la possibilité d'automatiser certains aspects du flux de traduction du projet. Pour plus d'informations, reportez-vous à la documentation de l'API Crowdin.

Pages en relation

Arrow-left.svg Page précédente: Branding
Page suivante: Extra python modules Arrow-right.svg
Arrow-left.svg Page précédente: Localisation
Page suivante: Source documentation Arrow-right.svg

Cette page contient plusieurs modules python supplémentaires ou d'autres bouts de code qui peuvent être téléchargés gratuitement sur Internet, et ajouter des fonctionnalités à votre installation de FreeCAD.

PySide (précédemment PyQt4)

  • page officielle (PySide): http://qt-project.org/wiki/PySide
  • licence: LGPL
  • option, plusieurs modules sont nécessaires et d'autres modules peuvent être ajoutés : Draft, Arch, Ship, Plot, OpenSCAD, Spreadsheet

PySide (auparavant PyQt) est requise par tous les modules de FreeCAD et pour accéder à l'interface Qt de FreeCAD. Il est déjà livré dans dans les versions FreeCAD, et est généralement installé automatiquement par FreeCAD sur Linux, l'installation peut se faire à partir des dépôts officiels. Si ces modules (Draft, Arch, etc) sont activés après l'installation de FreeCAD, cela signifie que PySide (auparavant PyQt) est déjà installé, et vous n'avez pas besoin de faire quoi que ce soit de plus.

Remarque : PyQt4 va devenir progressivement obsolète dans FreeCAD, après la version 0.13, la préférence ira sur PySide, qui fait exactement le même travail, mais dispose d'une licence (LGPL) plus compatible avec FreeCAD.

Installation

Linux

La façon la plus simple d'installer PySide est de l'installer par le biais du gestionnaire de paquets de votre distribution. Sur les systèmes Debian / Ubuntu, le nom du package est généralement python-PySide, tandis que sur les systèmes basés sur RPM il est nommé Pyside. Les dépendances nécessaires (Qt et SIP) seront pris en charge automatiquement.

Windows

Le programme peut être téléchargé à partir PySide Downloads. Vous aurez besoin d'installer les bibliothèques Qt et SIP avant d'installer PySide (à documenter).

MacOSX

PyQt pour Mac doit être installé via homebrew ou port. Pour plus d'informations voir CompileOnMac/fr#Dépendances_de_l'installation Dépendances_de_l'installation.

Utilisation

Une fois installé, vous pouvez vérifier le bon fonctionne de l'installation, en tapant dans la console Python de FreeCAD :

import PySide

Pour accéder à l'interface de FreeCAD, tapez :

from PySide import QtCore,QtGui
FreeCADWindow = FreeCADGui.getMainWindow()

Maintenant, vous pouvez commencer l'exploration de l'interface avec la commande dir(). Vous pouvez ajouter de nouveaux éléments, comme un widget personnalisé, avec des commandes comme :

FreeCADWindow.addDockWidget(QtCore.Qt.RghtDockWidgetArea,my_custom_widget)

Travailler avec Unicode :

text = text.encode('utf-8')

Travailler avec QFileDialog et OpenFileName :

path = FreeCAD.ConfigGet("AppHomePath")
#path = FreeCAD.ConfigGet("UserAppData")
OpenName, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Read a txt file", path, "*.txt")

Travailler avec QFileDialog et SaveFileName :

path = FreeCAD.ConfigGet("AppHomePath")
#path = FreeCAD.ConfigGet("UserAppData")
SaveName, Filter = PySide.QtGui.QFileDialog.getSaveFileName(None, "Save a file txt", path, "*.txt")

Exemple de transition de PyQt4 vers PySide

PS: ces exemples d'erreurs ont été trouvées dans la transition de PyQt4 à PySide et ces corrections ont été faites, d'autres solutions sont certainement disponibles avec les exemples ci-dessus

try:
    import PyQt4                                        # PyQt4
    from PyQt4 import QtGui ,QtCore                     # PyQt4
    from PyQt4.QtGui import QComboBox                   # PyQt4
    from PyQt4.QtGui import QMessageBox                 # PyQt4
    from PyQt4.QtGui import QTableWidget, QApplication  # PyQt4
    from PyQt4.QtGui import *                           # PyQt4
    from PyQt4.QtCore import *                          # PyQt4
except Exception:
    import PySide                                       # PySide
    from PySide import QtGui ,QtCore                    # PySide
    from PySide.QtGui import QComboBox                  # PySide
    from PySide.QtGui import QMessageBox                # PySide
    from PySide.QtGui import QTableWidget, QApplication # PySide
    from PySide.QtGui import *                          # PySide
    from PySide.QtCore import *                         # PySide

Pour accéder à l'interface FreeCAD, tapez: Vous pouvez ajouter de nouveaux éléments, comme un widget personnalisé, avec des commandes comme :

myNewFreeCADWidget = QtGui.QDockWidget()          # create a new dockwidget
myNewFreeCADWidget.ui = Ui_MainWindow()           # myWidget_Ui()             # load the Ui script
myNewFreeCADWidget.ui.setupUi(myNewFreeCADWidget) # setup the ui
try:
    app = QtGui.qApp                              # PyQt4 # the active qt window, = the freecad window since we are inside it
    FCmw = app.activeWindow()                     # PyQt4 # the active qt window, = the freecad window since we are inside it
    FCmw.addDockWidget(QtCore.Qt.RightDockWidgetArea,myNewFreeCADWidget) # add the widget to the main window
except Exception:
    FCmw = FreeCADGui.getMainWindow()             # PySide # the active qt window, = the freecad window since we are inside it 
    FCmw.addDockWidget(QtCore.Qt.RightDockWidgetArea,myNewFreeCADWidget) # add the widget to the main window

Travailler avec Unicode :

try:
    text = unicode(text, 'ISO-8859-1').encode('UTF-8')  # PyQt4
except Exception:
    text = text.encode('utf-8')                         # PySide

Travailler avec QFileDialog et OpenFileName :

OpenName = ""
try:
    OpenName = QFileDialog.getOpenFileName(None,QString.fromLocal8Bit("Lire un fichier FCInfo ou txt"),path,"*.FCInfo *.txt") # PyQt4
except Exception:
    OpenName, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Lire un fichier FCInfo ou txt", path, "*.FCInfo *.txt")#PySide

Travailler avec QFileDialog et SaveFileName :

SaveName = ""
try:
    SaveName = QFileDialog.getSaveFileName(None,QString.fromLocal8Bit("Sauver un fichier FCInfo"),path,"*.FCInfo") # PyQt4
except Exception:
    SaveName, Filter = PySide.QtGui.QFileDialog.getSaveFileName(None, "Sauver un fichier FCInfo", path, "*.FCInfo")# PySide

Travailler avec MessageBox:

def errorDialog(msg):
    diag = QtGui.QMessageBox(QtGui.QMessageBox.Critical,u"Error Message",msg )
    try:
        diag.setWindowFlags(PyQt4.QtCore.Qt.WindowStaysOnTopHint) # PyQt4 # this function sets the window before
    except Exception:    
        diag.setWindowFlags(PySide.QtCore.Qt.WindowStaysOnTopHint)# PySide # this function sets the window before
#    diag.setWindowModality(QtCore.Qt.ApplicationModal)       # function has been disabled to promote "WindowStaysOnTopHint"
    diag.exec_()

Travailler avec setProperty (PyQt4) et setValue (PySide)

self.doubleSpinBox.setProperty("value", 10.0)  # PyQt4

remplacer par :

self.doubleSpinBox.setValue(10.0)  # PySide

Travailler avec setToolTip

self.doubleSpinBox.setToolTip(_translate("MainWindow", "Coordinate placement Axis Y", None))  # PyQt4

remplacer par :

self.doubleSpinBox.setToolTip(_fromUtf8("Coordinate placement Axis Y"))  # PySide

ou

self.doubleSpinBox.setToolTip(u"Coordinate placement Axis Y.")# PySide

Documentation

Plus de tutoriels sur PyQt4 (y compris sur la façon de construire des interfaces avec Qt Designer pour utiliser avec python) :

  • API PyQt4 - La référence officielle sur l'API de PyQt4

Pivy

Pivy a besoin de plusieurs modules pour accéder à la vue 3D de FreeCAD. Pour les fenêtres, pivy est déjà fourni dans l'installateur de FreeCAD pour Linux, il est généralement installé automatiquement lorsque vous installez FreeCAD partir d'un référentiel officiel. Sur MacOSX, malheureusement, vous aurez besoin de compiler Pivy vous même.

Installation

Prérequis

Je crois, qu'avant de compiler Pivy vous devez avoir Coin et SoQt d'installés.

J'ai trouvé que pour la compilation sur Mac, il suffisait d'installer le Coin3 binary package.
La tentative d'installation de Coin sur MacPorts était problématique : j'ai essayé d'ajouter un grand nombre de paquets X Windows, et, finalement, tout c'est terminé avec une erreur de script !

Pour Fedora, j'ai trouvé un RPM avec Coin3.

SoQt, compilé à partir des sources fonctionne très bien sur Mac et Linux.

Debian & Ubuntu

Depuis Debian Squeeze et Ubuntu Lucid, Pivy est disponible directement à partir des dépôts officiels, et, nous permet d'économiser beaucoup de tracas.
En attendant, vous pouvez soit télécharger l'un des packages que nous avons fait (pour Debian et Ubuntu karmic), disponibles sur les pages de téléchargements , ou, vous pouvez le compiler vous-même.

La meilleure façon de compiler facilement Pivy, est de prendre le debian source package pour Pivy, et, faire un package avec debuild.
C'est le même code source que sur le site officiel de Pivy, mais, les gens de Debian ont ajoutés plusieurs bug-fixing. Il compile également très bien sur : Ubuntu Karmic ... télécharger .orig.gz et .diff.gz, décompressez le tout, puis appliquez .diff à la source :
allez dans le dossier source de Pivy décompressé, et appliquez le patch .diff :

patch -p1 < ../pivy_0.5.0~svn765-2.diff

alors

debuild

pour avoir Pivy, correctement compilé, avec un package officiellement installable. Ensuite, il suffit d'installer le package avec gdebi.

Autres distributions Linux

D'abord, téléchargez les dernières sources du project's repository :

hg clone http://hg.sim.no/Pivy/default Pivy

En Mars 2012, la dernière version était la pivy-0.5.

Ensuite, vous avez besoin d'un outil appelé SWIG pour générer le code C++ pour les Python bindings. Pivy-0.5 rapports qui a été testé seulement avec SWIG 1.3.31, 1.3.33, 1.3.35 et 1.3.40. Ainsi, vous pouvez télécharger une archive source pour l'une de ces anciennes versions de SWIG.
Puis, décompressez-le, et, faites en ligne de commande (en tant que root) :

./configure
make
make install (or checkinstall if you use it)

Il faut quelques secondes pour la compilation.

Alternativement, vous pouvez essayer avec une compilation plus récent SWIG. En Mars 2012, la version référentielle typique était 2.0.4.
Pivy a un problème de compilation avec les versions inférieures 2.0.4 de SWIG sur Mac OS (voir ci-dessous), mais semble compiler correctement sur Fedora Core 15.

Après cela, allez dans le source Pivy et tapez :

python setup.py build

pour créer les fichiers sources. Notez que cette génération de fichiers peut produire des milliers de mises en garde, mais j'espère qu'il n'y aura pas d'erreurs.

Ceci est probablement obsolète, mais vous risquez de rencontrer une erreur de compilation, ou, un "const char*" ne peut pas être converti en un "char*".
Pour corriger cela, il vous suffit d'écrire une "const", dans les lignes appropriées, avant la génération. Il y a six lignes à corriger.

Après cela, installez (en tant que root) :

python setup.py install (or checkinstall python setup.py install)

Ça y est, pivy est installé.

Mac OS

Ces instructions peuvent ne pas être complètes. Quelque chose plus ou moins comme cela a fonctionné pour OS 10.7 de Mars 2012. J'utilise MacPorts pour les dépôts, mais d'autres options devraient également fonctionner.

En ce qui concerne linux, téléchargez les dernières sources :

hg clone http://hg.sim.no/Pivy/default Pivy

Si vous n'avez pas hg, vous pouvez l'obtenir à partir MacPorts :

port install mercurial

Puis, comme ci-dessus vous avez besoin SWIG.
Faites :

port install swig

J'ai trouvé que j'avais besoin aussi de faire :

port install swig-python

En Mars 2012, MacPorts SWIG est la version 2.0.4. Comme il est indiqué ci-dessus pour Linux, il vaudrait mieux télécharger une version plus ancienne. SWIG 2.0.4 semble avoir un bug qui empêche la compilation de Pivy.
Regardez le premier message dans ce : digest

Cela peut être corrigé, en modifiant les 2 emplacements source et déréférencer : *arg4, *arg5 à la place de arg4, arg5.
Maintenant nous pouvons compiler Pivy:

python setup.py build
sudo python setup.py install

Windows

En supposant que vous utilisiez Visual Studio 2005 ou une version ultérieure, vous devrez ouvrir une invite de commande avec Visual Studio 2005 Command prompt dans le menu Outils.
Si l'interpréteur Python n'est pas encore dans le chemin système (PATH), faites :

set PATH=path_to_python_2.5;%PATH%

Pour que Pivy soit fonctionnel, vous devriez télécharger les dernières sources à partir du référentiel du projet :

svn co https://svn.coin3d.org/repos/Pivy/trunk Pivy

Ensuite, vous avez besoin d'un outil appelé SWIG pour générer le code C++ pour les Python bindings. Il est recommandé d'utiliser la version 1.3.25 de SWIG, pas la dernière version, parceque, Pivy ne fonctionne pas correctement avec la version 1.3.25. Télécharger le binaire pour la version 1.3.25 de Swig.
Puis décompressez-le et à partir de la ligne de commande, ajoutez le chemin (path) du système

set PATH=path_to_swig_1.3.25;%PATH%

et définir le chemin approprié à COINDIR :

set COINDIR=path_to_coin

Sous Windows, le fichier de configuration Pivy attend SoWin au lieu de SoQt par défaut. Je n'ai pas trouvé de façon évidente pour compiler avec SoQt, alors, j'ai modifié le fichier setup.py directement.
A la ligne 200 il suffit de retirer la partie sowin : ('gui._sowin', 'sowin-config', 'pivy.gui.') (ne pas enlever la parenthèse fermante ! ).

Après cela, allez dans le source de pivy et tapez :

python setup.py build

qui crée les fichiers source. Vous pouvez rencontrer une erreur de compilation, cause, plusieurs fichiers d'en-tête n'ont pas été trouvés.
Dans ce cas, réglez la variable INCLUDE comme ceci :

set INCLUDE=%INCLUDE%;path_to_coin_include_dir

et si les en-têtes soqt, ne sont pas au même endroit que les en-têtes Coin, faites aussi ceci :

set INCLUDE=%INCLUDE%;path_to_soqt_include_dir

et finalement, pour les en-têtes Qt faites :

set INCLUDE=%INCLUDE%;path_to_qt4\include\Qt

Si vous utilisez Express Edition of Visual Studio, vous pouvez obtenir une exception Python keyerror.
Dans ce cas, vous devez modifier de petites choses dans msvccompiler.py, qui se trouve, dans votre installation Python.

Aller à la ligne 122 et remplacez la ligne :

vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version

par

vsbase = r"Software\Microsoft\VCExpress\%0.1f" % version

Puis réessayez.
Si vous obtenez une deuxième erreur comme :

error: Python was built with Visual Studio 2003;...

vous devez également remplacer la ligne 128 comme ceci :

self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")

par

self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv2.0")

Réessayez encore une fois.
Si vous obtenez de nouveau une erreur comme :

error: Python was built with Visual Studio version 8.0, and extensions need to be built with the same version of the compiler, but it isn't installed.

alors vous devriez vérifier les variables d'environnement DISTUTILS_USE_SDK et MSSDK avec :

echo %DISTUTILS_USE_SDK%
echo %MSSDK%

Si ce n'est pas toujours pas arrangé, il suffit de définir à 1 :

set DISTUTILS_USE_SDK=1
set MSSDK=1

Maintenant, vous pouvez rencontrer une erreur de compilation, ou un const char* ne peut pas être converti en un char*.
Pour corriger cela il vous suffit d'écrire un const avant, dans les lignes appropriées, il y a six lignes à corriger.
Après copiez le répertoire généré par Pivy dans un endroit où l'interpréteur Python de FreeCAD peut le trouver.

Utilisation

Pour vérifier si pivy est correctement installé :

import pivy

Pour avoir accès à Pivy à partir de la scénographique de FreeCAD, procédez comme ceci:

from pivy import coin
App.newDocument() # Open a document and a view 
view = Gui.ActiveDocument.ActiveView 
FCSceneGraph = view.getSceneGraph() # returns a pivy Python object that holds a SoSeparator, the main "container" of the Coin scenegraph
FCSceneGraph.addChild(coin.SoCube()) # add a box to scene

Vous pouvez maintenant explorer la FCSceneGraph avec la commande dir().

Documentation

Malheureusement, la documentation sur Pivy est "pour le moment" presque inexistante sur le net. Mais vous pouvez trouver de la documentation très utile sur Coin, car Pivy a simplement traduit les fonctions, Coin, des nœuds et des méthodes en Python, les noms sont conservés (mêmes noms) ainsi que les propriétés ne sont différentes que par la syntaxe entre le C et Python :

Vous pouvez également consulter le fichier Draft.py dans le dossier FreeCAD Mod/Draft, car Pivy est fortement utilisé.

pyCollada

  • homepage: http://pycollada.github.com
  • license: BSD
  • option, est nécessaire pour permettre l'importation et l'exportation de fichiers Collada (.DAE)

pyCollada est une bibliothèque Python qui permet aux programmes de lire et d'écrire des fichiers Collada (*.DAE). Lorsque pyCollada est installé sur votre système, FreeCAD (introduced in version 0.13) le détecte et ajoute les options d'importation et d'exportation, qui permettent l'ouverture et l'enregistrement de fichiers au format Collada.

Installation

Pycollada n'est généralement pas encore disponible dans les dépôts des distributions Linux, mais puisqu'il est fait uniquement en Python, il ne nécessite pas de compilation, et est facile à installer.
Vous avez 2 façons de l'installer, soit directement à partir du pycollada git repository officiel, ou avec l'outil easy_install.

Linux

Dans les deux cas, vous aurez besoin des paquetages suivants, installés d'avance sur votre système :

python-lxml 
python-numpy
python-dateutil
Depuis le dépôt git (pycollada git repository)
git clone git://github.com/pycollada/pycollada.git pycollada
cd pycollada
sudo python setup.py install
Avec easy_install (easy_install)

En supposant que vous avez déjà installé complètement Python, l'utilitaire easy_install doit être déjà présent :

easy_install pycollada

Vous devez vous assurer que pycollada, est correctement installé, en utilisant la commande suivante dans la console Python :

import collada

Si la commande ne retourne aucun message d'erreur, alors tout est OK.

Windows

Pycollada est inclus sur Windows depuis la version 0.15 et dans les versions de développement de FreeCAD, donc aucune étape supplémentaire n'est nécessaire.

Mac OS

Si vous utilisez l'accumulation des Homebrew FreeCAD vous pouvez installer pycollada dans votre système Python en utilisant pip.

Si vous devez installer pip:

$ sudo easy_install pip

Installer pycollada:

$ sudo pip install pycollada

Si vous utilisez une version binaire de FreeCAD, vous pouvez dire pip installez pycollada dans le site-packages à l'intérieur FreeCAD.app:

$ pip install --target="/Applications/FreeCAD.app/Contents/lib/python2.7/site-packages" pycollada

or after downloading the pycollada code

$ export PYTHONPATH=/Applications/FreeCAD\ 0.16.6706.app/Contents/lib/python2.7/site-packages:$PYTHONPATH
$ python setup.py install --prefix=/Applications/FreeCAD\ 0.16.6706.app/Contents

IfcOpenShell

IFCOpenShell, est une bibliothèque actuellement en développement, ce qui permet d'importer (et bientôt d'exporter) Industry foundation Classes (*.Fichiers IFC).

Ceci est une extension pour le format STEP, et, devient la norme dans les workflows BIM. Lorsque ifcopenshell est correctement installé sur votre système, le text-top=Arch_Module Module Arch de FreeCAD le détectera, et, l'utilisera pour importer des fichiers IFC. Étant donné qu'ifcopenshell est basé sur OpenCasCade, comme FreeCAD, la qualité de l'importation est très élevée, en produisant une géométrie de solides de haute qualité.

Installation

Étant donné que 'ifcopenshell est assez nouveau, vous devrez probablement le compiler vous-même.

Linux

Vous aurez besoin de deux ou trois paquets de développement, installés sur votre système afin de rassembler les ifcopenshell :

liboce-*-dev
python-dev
swig

mais, étant donné que FreeCAD exige tout, vous pouvez compiler FreeCAD, vous n'aurez aucune dépendance supplémentaire pour compiler IfcOpenShell.

Prenez le dernier code source ici :

git clone https://github.com/IfcOpenShell/IfcOpenShell.git

Le processus de création est très simple :

mkdir ifcopenshell-build
cd ifcopenshell-build
cmake ../IfcOpenShell/cmake

ou, si vous utilisez oce au lieu d'opencascade :

cmake -DOCC_INCLUDE_DIR=/usr/include/oce ../ifcopenshell/cmake

Étant donné que ifcopenshell est fait principalement pour Blender, il utilise python3 par défaut. Pour l'utiliser à l'intérieur de FreeCAD, vous devez le compiler avec la même version de Python qui est utilisé dans FreeCAD. Vous devrez peut-être forcer les paramètres avec la version de Python et cmake (réglez la version de Python avec la vôtre) :

cmake -DOCC_INCLUDE_DIR=/usr/include/oce -DPYTHON_INCLUDE_DIR=/usr/include/python2.7 -DPYTHON_LIBRARY=/usr/lib/python2.7.so ../ifcopenshell/cmake

Alors :

make
sudo make install

Vous pouvez vérifier que ifcopenshell, a été correctement installé en tapant dans la console Python :

import ifcopenshell

Si la commande ne retourne aucun message d'erreur, alors tout est OK.

Windows

Note: les installateurs officiels FreeCAD obtenus à partir de la page du site Web/github de FreeCAD contiennent déjà ifcopenshell.

Documentation copiée à partir du fichier README IfcOpenShell

Les utilisateurs sont priés d'utiliser le fichier .sln de Visual Studio qui se trouve dans win/folder.

Pour les utilisateurs de Windows une version pré-construite Open CASCADE est disponible sur le site d'OpenCascade. Téléchargez, et, installez cette version dans le chemin d'accès d'Open CASCADE, et, des fichiers de la bibliothèque de MS Visual Studio C++.

Pour créer le IfcPython wrapper, SWIG doit être installé. Téléchargez la dernière version de swigwin. Après avoir extrait le fichier .zip, veuillez ajouter le dossier à la variable d'environnement PATH. Python doit être installé, veuillez fournir les chemins d'accès des fichiers include, et, bibliothèque pour Visual Studio.

Liens

Tutoriel Import/Export IFC - compiling IfcOpenShell

ODA Converter (précédemment Teigha Converter)

Le convertisseur ODA Converter est un petit utilitaire disponible gratuitement qui permet de convertir plusieurs versions de fichiers DWG et DXF. FreeCAD peut l'utiliser pour permettre l'importation et l'exportation de fichiers DWG, en convertissant les fichiers DWG au format DXF de manière transparente, puis utiliser son importateur DXF standard pour importer le contenu du fichier. Les restrictions de l'importateur DXF s'appliquent.

Installation

S'installe sur toutes les plateformes, par l'installation du paquet approprié disponible à https://www.opendesign.com/guestfiles/oda_file_converter. Après l'installation, si l'utilitaire n'est pas trouvé automatiquement par FreeCAD, vous devrez configurer manuellement le chemin de l'exécutable du convertisseur via le menu Édition → Préférences → Importer-Exporter → DWG et renseignez le champs "Chemin d’accès du convertisseur de fichier Teiga".

Arrow-left.svg Page précédente: Localisation
Page suivante: Source documentation Arrow-right.svg

Credits

FreeCAD Users Contributors.svg

<translate> FreeCAD would not be what it is without the generous contributions of many people. Here's an overview of the people and companies who contributed to FreeCAD over time. For credits for the third party libraries see the Third Party Libraries page.

Development

Project managers

Lead developers of the FreeCAD project: </translate>

<translate>

Main developers

People who work regularly on the FreeCAD code (retrieved from https://github.com/FreeCAD/FreeCAD/graphs/contributors): </translate>

<translate>

Other coders

Other people who contributed code to the FreeCAD project: </translate>

  • Barleyman
  • Berthold Grupp
  • dbtayl
  • Dmitry Chigrin
  • ezzieyguywuf
  • fandaL
  • Georg Wiora
  • Graeme van der Vlugt
  • itain
  • j-dowsett
  • Jacques-Antoine Gaudin
  • jcc242
  • jmaustpc
  • Joachim Zettler
  • jobermayr
  • Johan3DV
  • jonnor
  • keithsloan52
  • Ken Cline
  • Mandeep Singh
  • marktaff
  • Martin Burbaum
  • maurerpe
  • ovginkel
  • peterl94
  • plaes
  • poutine70
  • TheMarkster
  • qingfengxia
  • Remigiusz Fiedler (DXF-parser)
  • SebKuzminsky
  • tomate44
  • triplus
  • usakhelo

<translate>

Companies

Companies which donated code or developer time: </translate>

<translate>

Forum moderators

People in charge of the FreeCAD forum (retrieved from http://forum.freecadweb.org/memberlist.php?mode=team): </translate>

<translate>

Community

People from the community who put a lot of efforts in helping the FreeCAD project either by being active on the forum, keeping a blog about FreeCAD, making video tutorials, packaging FreeCAD for Windows/Linux/MacOS X, writing a FreeCAD book... (listed by alphabetical order) (retrieved from http://forum.freecadweb.org/memberlist.php?mode=&sk=d&sd=d#memberlist) </translate>

<translate>

Documentation writers

People who wrote the documentation on this wiki: </translate>

<translate>

Translators

People who helped to translate the FreeCAD application (retrieved from https://crowdin.com/project/freecad): </translate>

<translate>

Addons developers

Developers of FreeCAD addons (retrieved from https://github.com/FreeCAD/FreeCAD-addons): </translate>

<translate> </translate>