Description |
---|
This macro generates lists of properties of the selected object in different forms in Wiki format. Macro version: 0.15 Last modified: 2021-09 Author: Evgeniy |
Author |
Evgeniy |
Download |
None |
Links |
Macros recipes How to install macros How to customize toolbars |
Macro Version |
0.15 |
Date last modified |
2021-09 |
FreeCAD Version(s) |
None |
Default shortcut |
None |
See also |
Basic version of this macro, Part Feature |
This macro generates lists of properties of the selected object in different forms in Wiki format. The list is printed to the Report view of FreeCAD. This macro can be used to simplify working with this Wiki with some restrictions. The property lists published in Wiki usually contain only unique parameters. Parameters inherited from parent objects are not published.
This script automatically removes inherited parameters from the list. But due to the software limitations of FreeCAD, it cannot delete absolutely all inherited parameters, so the lists generated by this script should be carefully checked before publishing.
Each object created in FreeCAD is inherited from the parent object. The structure of these relationships is shown in the diagram below.
You can read more about this on the page: Part Feature
Do not delete spaces between lines. This is necessary to simplify the translation. Each line separated by a space will be considered a separate part for translation. When creating texts, always remember that large monolithic fragments of text are difficult for translators to translate.
The macro will generate a report depending on which button you clicked.
Note that the order of the lines in the parameter editor may differ from the order of the lines made by the generator.
Only Unique Properties | Inherits+Unique Properties | All Properties |
---|---|---|
PropertiesViewDataSphere
|
PropertiesView<!-- Data<!-- Sphere
|
PropertiesViewDisplay Options
Object Style
The default value is 28.5 degrees, or 0.5 radians. The smaller the value the smoother the appearance in the 3D view, and the finer the mesh that will be exported.
in the 3D view (tessellation). Lower values indicate better quality. The value is in percent of object's size.
Selection
Object: On top only if the whole object is selected Element: On top only if some sub-element of the object is selected
Data
Attachment
Base
Sphere
|
...
#! python # -*- coding: utf-8 -*- # (c) 2021 <Evgeniy> LGPL from FreeCAD import Qt import re, FreeCAD from PySide import QtCore, QtGui def clear_report_view(): main_window=Gui.getMainWindow() #console=main_window.findChild(QtGui.QPlainTextEdit, "Python console") #console.clear() report_view=main_window.findChild(QtGui.QTextEdit, "Report view") report_view.clear() def printsr(text,show_report): if show_report: print(text) # Based on https://github.com/FreeCAD/FreeCAD/blob/5d49bf78de785a536f941f1a6d06d432582a95d3/src/App/PropertyFile.h # and https://github.com/FreeCAD/FreeCAD/blob/5d49bf78de785a536f941f1a6d06d432582a95d3/src/App/PropertyContainerPyImp.cpp status_dictionary={ 0:"Touched", # touched property #1:"Immutable", # can't modify property #2:"ReadOnly", # for property editor #3:"Hidden", # for property editor #4:"Transient", # for property container save #5:"MaterialEdit", # to turn ON PropertyMaterial edit #6:"NoMaterialListEdit", # to turn OFF PropertyMaterialList edit #7:"Output", # same effect as Prop_Output #8:"LockDynamic", # prevent being removed from dynamic property #9:"NoModify", # prevent causing Gui::Document::setModified() #10:"PartialTrigger", # allow change in partial doc 11:"NoRecompute", # touch owner for recompute on property change 12:"Single", # for save/load of floating point numbers 13:"Ordered", # for PropertyLists whether the order of the elements is relevant for the container using it 14:"EvalOnRestore", # In case of expression binding, evaluate the expression on restore and touch the object on value change. # The following bits are corresponding to PropertyType set when the # property added. These types are meant to be static, and cannot be # changed in runtime. It is mirrored here to save the linear search # required in PropertyContainer::getPropertyType() 21:"Dynamic", # indicating the property is dynamically added 22:"NoPersist", # corresponding to Prop_NoPersist 23:"NoRecompute", # corresponding to Prop_NoRecompute 24:"ReadOnly", # corresponding to Prop_ReadOnly 25:"Transient", # corresponding to Prop_Transient 26:"Hidden", # corresponding to Prop_Hidden 27:"Output", # corresponding to Prop_Output } def print_obj_properties(obj,typ,blacklist,show_inherits): prop={} i=1 inherits = "" for pr in obj.PropertiesList: typeid = (obj.getTypeIdOfProperty(pr) or "").replace("App::Property","") # Get all possible status variants stat = obj.getPropertyStatus(pr) or ("") if stat != (""): for st in stat: # get status without name from dictionary if isinstance(st, int): stat.insert(stat.index(st),status_dictionary[st]) stat.remove(st) # remove symbols ['] from str by regexp and trim spaces stat = re.sub(r"[\[\]\']","",str(stat)).strip() # Uncomment this two strings to make the list look like the list of parameters from the editor #if 'Hidden' in stat: # continue else: stat = "" if blacklist == None or (blacklist != None and pr not in blacklist): prop[str(i)] = pr,obj.getGroupOfProperty(pr),typeid,obj.getDocumentationOfProperty(pr),stat i+=1 else: inherits += pr + " inherited from class " + blacklist[pr] + "\n" if inherits != "" and show_inherits: # angle brackets is masked as \x3C and \x3E to this code can be published in the wiki print("\n\x3C!--\n"+inherits+"--\x3E") sorted_prop = sorted(prop.items(), key=lambda x: x[1][1]) title="" for pr in sorted_prop: if title != pr[1][1]: title = pr[1][1] print("\n"+"{{TitleProperty|"+title+"}}") # use ternary operator "|"+pr[1][4] if pr[1][4]!="" else "" to ignore status field if it not exists print("\n"+"* {{Property"+typ+"|"+pr[1][0]+"|"+pr[1][2]+("|"+pr[1][4] if pr[1][4]!="" else "")+"}}: "+pr[1][3]) # Add propertyes to blacklist if it not presentet in it yet def add_to_blacklist(data_blacklist,view_blacklist,obj_type,temp_obj_name,show_report): printsr("Class: '"+obj_type+"'",show_report) # Make tempory object obj = FreeCAD.activeDocument().addObject(obj_type,temp_obj_name) name = obj.Name # Get Data parametrs printsr("Data parameters list:",show_report) for pr in obj.PropertiesList: if not show_report or pr not in data_blacklist: data_blacklist[pr]=obj_type atr = str(obj.getPropertyStatus(pr)).replace("[]","") typeid = (obj.getTypeIdOfProperty(pr) or "").replace("App::Property","") printsr(pr+" ("+typeid+") "+atr,show_report) # Get View parameters if it is possible obj = Gui.activeDocument().getObject(name) try: test = obj.PropertiesList printsr("View parameters list:",show_report) for pr in obj.PropertiesList: if not show_report or pr not in view_blacklist: view_blacklist[pr]=obj_type atr = str(obj.getPropertyStatus(pr)).replace("[]","") typeid = (obj.getTypeIdOfProperty(pr) or "").replace("App::Property","") printsr(pr+" ("+typeid+") "+atr,show_report) except: printsr("This class not support View parameters.",show_report) # Remove object FreeCAD.activeDocument().removeObject(name) printsr("",show_report) return data_blacklist,view_blacklist def fill_blacklists(show_report): data_blacklist={} view_blacklist={} # Interfaces are not supported #data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"App::OriginGroupExtension","Temp",show_report) #data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"Part::AttachExtension","Temp",show_report) #data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"Sketcher::PropertyConstrainList","Temp",show_report) data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"App::DocumentObject","Temp",show_report) data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"App::GeoFeature","Temp",show_report) data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"App::Part","Temp",show_report) data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"Mesh::Feature","Temp",show_report) data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"Fem::FemMeshObject","Temp",show_report) data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"Path::Feature","Temp",show_report) data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"Part::Part2DObject","Temp",show_report) # Part::Primitive is not possible to create #data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"Part::Primitive","Temp",show_report) data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"PartDesign::Feature","Temp",show_report) data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"Part::BodyBase","Temp",show_report) data_blacklist,view_blacklist = add_to_blacklist(data_blacklist,view_blacklist,"PartDesign::Body","Temp",show_report) if show_report: print("List of all not unique properties of Data:\n"+str(data_blacklist)+"\n\nList of all not unique properties of View:\n"+str(view_blacklist)+"\n") return data_blacklist,view_blacklist sel = FreeCADGui.Selection.getSelection() if len(sel) != 1: msgbox = QtGui.QMessageBox(QtGui.QMessageBox.Question, u'Properties Generator', """You must select only one object in tree view!""") msgbox.exec_() else: # Show dialog for select type of report msgbox = QtGui.QMessageBox(QtGui.QMessageBox.Question, u'Properties Generator', """Select type of report Only Main - print only unique properties of main classes with types. All Properties - print all properties of selected object. Inherits+Unique Properties - print unique properties with inherits report. Only Unique Properties - print only unique properties of selected object. """) msgbox.setStandardButtons(QtGui.QMessageBox.Cancel) #|QtGui.QMessageBox.Ok only_main = msgbox.addButton("Only Main", QtGui.QMessageBox.AcceptRole) all_properties = msgbox.addButton("All Properties", QtGui.QMessageBox.AcceptRole) unique_prop_inherits = msgbox.addButton("Inherits+Unique Properties ", QtGui.QMessageBox.AcceptRole) unique_properties = msgbox.addButton("Only Unique Properties", QtGui.QMessageBox.AcceptRole) msgbox.exec_() res = msgbox.clickedButton() # Clear Report view clear_report_view() if res == only_main : data_blacklist,view_blacklist=fill_blacklists(True) if res == unique_properties or res == all_properties or res == unique_prop_inherits : name = sel[0].Name act_obj = Gui.activeDocument().getObject(name) data_blacklist={} view_blacklist={} if res == unique_properties or res == unique_prop_inherits: data_blacklist,view_blacklist=fill_blacklists(False) print("\n"+"==Properties==") print("\n"+"===View===") print_obj_properties(act_obj,"View",view_blacklist, res == unique_prop_inherits) print("\n"+"===Data===") act_obj = FreeCAD.activeDocument().getObject(name) print_obj_properties(act_obj,"Data",data_blacklist, res == unique_prop_inherits)
The discussion on the forum: https://forum.freecadweb.org/viewtopic.php?f=21&t=61998