Je ne suis pas du tout un pro de FreeCad, mais j'avoue que j'apprécie beaucoup la notion de dessin paramétré.
J'ouvre systématiquement un spreadsheet pour y placer toutes les valeurs qui me permettent de faire du "paramétré".
j'organise ma spreadSheet avec une colonne un texte qui me permet de savoir de quelle valeur je parle, dans la colonne suivante, il y a la valeur. Un alias automatiquement créé à partir de la description me permet de l'utiliser facilement
Je me suis fait une macro pour générer automatiquement les allias dans les cellules immédiatement à droite des cellules sélectionnées.
Attention, cette macro est largement améliorable du point de vue propreté du code. Je progresse grâce au forum et notamment openBain. Il faudra donc que je revienne sur cette macro. Cela dit, je crois qu'il en existe une similaire dans la bibliothèque de macro FreeCad.
Paramètres de mon cube
Longueur cube 1 par exemple va générer un alias 'longueurCube1' sur la cellule immédiatement à sa droite
Il faut sélectionner une ou plusieurs cellules dont on veut extraire les textes pour créer les alias avant de lancer la macro.
Code: Select all
# -*- coding: utf-8 -*-
### On fait les imports qui vont bien
import FreeCAD as App
import FreeCADGui as Gui
from PySide import QtGui
separateur=" " # classiquement mettre " " ainsi les blancs seront remplacés par nouveauCaract
nouveauCaract='' #Mettre par exemple "_" pour que les séparateurs soit remplacés par "_". Mettre "" pour ne pas avoir de séparateur
majuscule=True #mettre à True si on veut que "Diametre du cercle" devienne "DiametreDuCercle"
changeTexteCellule=False # le texte ne sera changé que si changeTexteCellule est à True. Cela ne change rien pour l'allias lui-même
premierCaractereEnMinuscule=True #Force le premier caractère à être en minuscule
# liste des caractères devant être remplacés par un équivalent. par exemple 'é' sera remplacé par 'e'
caracEquivalents =[ ['é','e'],['è','e'],['à','a'],['@','a'],['&','e'],['ç','c'],['²','2'],["'",''] ]
def remplaceCartatParEquivalent(caractere):
# remplace un caractère par sn équivalent sil existe
caracResult=caractere
for couple in caracEquivalents:
if (couple[0]==caractere):
caracResult=couple[1]
break
return caracResult
def remplaceCararcDansMot(mot):
#remplace tous les caractères du mot par son équivalent s'il existe
motResult=mot
for caract in mot:
a=remplaceCartatParEquivalent(caract)
motResult=motResult.replace(caract,a)
return motResult
def traitementChaineSource(chaineSource,separateur,nouveauCaract,majuscule):
# Si séparateur vaut ' ' et nouveauCaract vaut '_', et majuscule vaut True
# transforme "Diametre du cylindre" en "Diametre_Du_Cylindre"
chaineResult=''
first=True
carctDeSeparation=''
for mots in chaineSource.split(separateur):
mots=remplaceCararcDansMot(mots)
if (not (first)):
carctDeSeparation=nouveauCaract
if (majuscule):
chaineResult=chaineResult+nouveauCaract+mots[:1].upper()+mots[1:]
# On utilise "[:1]" au lieu de "[0]", car ce dernier plante en cas de chaine vide (ce qui arrive si la cellule est vide)
else:
chaineResult=chaineResult+nouveauCaract+mots
if premierCaractereEnMinuscule :
chaineResult=chaineResult[:1].lower()+chaineResult[1:]
return chaineResult
def trouveSheet(fenetreActive):
# renvoit le spreadSheet si c'est la fenêtre active
#aw=fenetreActive
#aw = Gui.getMainWindow().centralWidget().activeSubWindow() # On stocke la fenêtre active
sheet = App.ActiveDocument.getObjectsByLabel(fenetreActive.windowTitle()) # On essaye de trouver la feuille correspondant à la fenêtre à partir du nom de la fenêtre
if len(sheet) == 0 and fenetreActive.windowTitle()[-3:] == '[*]': # Si aucune feuille correspondante n'a été trouvée...
# ... On sait que FreeCAD ajoute au nom de la fenêtre les caractères "[*]" quand la feuille a été modifiée ...
# ... et seulement dans le cas ou la feuille n'a jamais été renommée (!!!!!) ...
sheet = App.ActiveDocument.getObjectsByLabel(fenetreActive.windowTitle()[:-3]) # ... Donc on réessaye sans les 3 derniers caractères
if len(sheet) != 1: # Si aucune feuille n'a été trouvée (ou plusieurs feuilles ont été trouvées)
App.Console.PrintError("Can't find sheet : {}\n".format(fenetreActive.windowTitle())) # On imprime une erreur dans la rapport
return ''
else:
sheet = sheet[0] # La feuille est la seule qui a été trouvée par la recherche précédente
return sheet
aw = Gui.getMainWindow().centralWidget().activeSubWindow() # On stocke la fenêtre active
sheet=trouveSheet(aw)
if (sheet!=''):
sel_items = aw.widget().findChild(QtGui.QTableView).selectedIndexes() # On récupère la liste complète de toutes les cellules sélectionnées
proceed = True # Un petit drapeau qui indiquera si on doit vraiment procéder
for item in sel_items: # On parcourt les cellules sélectionnées
if item.column() != sel_items[0].column(): # Si une des cellules n'est pas dans la même colonne que la première
### On affiche un dialogue demandant à l'utilisateur s'il est sûr de son coup
if QtGui.QMessageBox.warning(Gui.getMainWindow(),
"Warning","""Selected cells aren't all in the same column.
Proceed anyway ?""",
QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel) == QtGui.QMessageBox.Cancel: # Si l'utilisateur annule
proceed = False # On ne procèdera pas aux changements
break # Pas la peine de continuer à analyser les colonnes à partir du moment ou au moins 2 ne sont pas sur la même colonne
if proceed: # Si on doit continuer à procéder
### On définit une fonction qui renverra l'identifiant de la cellule à partir de ses numéros de ligne (r) et colonne (c)
### Les numéros commencent à 0 pour la première ligne/colonne
### On gère correctement les colonnes avec un identifiant à 2 lettres
cellName = lambda r,c:'{}{}{}'.format(chr(c//26 + 64) if c//26 > 0 else '', chr(c%26+65), r+1)
for item in sel_items: # On parcourt les cellules sélectionnées
cell = cellName(item.row(),item.column()) # On récupère l'identifiant de la cellule
next_cell = cellName(item.row(), item.column()+1) # On récupère l'identifiant de la cellule voisine à droite
activeCellContenu=sheet.getContents(cell)
# traitement de la chaine de caractère contenue dans la cellule
activeCellContenu=traitementChaineSource(activeCellContenu,separateur,nouveauCaract,majuscule)
if changeTexteCellule:# si le paramètre changeTexteCellule est à True alors on remplace le texte de la cellule
sheet.set(cell, activeCellContenu)
alias=activeCellContenu
try: # Bloc try pour récupérer les erreurs
sheet.setAlias(next_cell, alias) # On attribue l'alias à la cellule voisine de droite
except ValueError: # Si une erreur "ValueError" est déclenchée (ce qui arrive quand l'alias n'est pas valide)
App.Console.PrintWarning("Can't set alias for cell {} : {} isn't valid\n".format(next_cell, alias)) # On prévient l'utilisateur dans le rapport