Macro Dump Objects: Difference between revisions
No edit summary |
(Use {{MacroCode}}) |
||
(22 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
<languages/> |
|||
{{Macro|Icon=Macro_Dump_Objects|Name=Macro_Dump_Objects|Description=This macro generates a listing of all objects in the current document - the list can be in a window or on the Report view.|Author=PiffPoof}} |
|||
<translate> |
|||
<!--T:1--> |
<!--T:1--> |
||
{{Macro |
|||
[[File:DumpObjectsScreenSnapshot.jpg|500px]] |
|||
|Name=Macro Dump Objects |
|||
|Description=This macro generates a listing of all objects in the current document - the list can be in a window or on the Report view. |
|||
|Author=Piffpoof |
|||
|Version=1.0 |
|||
|Date=2015-03-02 |
|||
|FCVersion= <= 0.17 |
|||
|Download=[https://www.freecadweb.org/wiki/images/2/2e/Macro_Dump_Objects.png ToolBar Icon] |
|||
}} |
|||
<!--T:2--> |
|||
When developing complex object models it is easy to loose track of exactly which objects are present as some may be hidden, obscured or transparent. Additionally with a large number of objects a naming system becomes necessary to keep track of the objects. |
When developing complex object models it is easy to loose track of exactly which objects are present as some may be hidden, obscured or transparent. Additionally with a large number of objects a naming system becomes necessary to keep track of the objects. |
||
<!--T:3--> |
|||
[[File:DumpObjectsScreenSnapshot.jpg|500px]] |
|||
==Description== <!--T:4--> |
|||
The Dump Object code takes the current document and enumerates all the objects. A report is then generated listing each object, then a summary giving the total number of instances of each Class, followed by the total number of Classes and finally the total number of objects. The output may be directed to the Report view or to a window. The window is non-modal and will stay open until closed by the user. Each window has the time of the object dump in it's title bar, so the contents of multiple windows can be compared, say before and after a piece of code running. |
The Dump Object code takes the current document and enumerates all the objects. A report is then generated listing each object, then a summary giving the total number of instances of each Class, followed by the total number of Classes and finally the total number of objects. The output may be directed to the Report view or to a window. The window is non-modal and will stay open until closed by the user. Each window has the time of the object dump in it's title bar, so the contents of multiple windows can be compared, say before and after a piece of code running. |
||
<!--T:5--> |
|||
The default operation lists all objects, optionally the placement of each object can be listed. Also for Sketches, each segment of the Geometry can be listed. |
The default operation lists all objects, optionally the placement of each object can be listed. Also for Sketches, each segment of the Geometry can be listed. |
||
==Installation== <!--T: |
==Installation== <!--T:6--> |
||
All the code for dumpObject.FCMacro is in one macro. So installation is comprised of copying the code to the appropriate Macro directory and invoking dumpObject from the Macro menu. Alternatively it may be run from the console. |
All the code for dumpObject.FCMacro is in one macro. So installation is comprised of copying the code to the appropriate Macro directory and invoking dumpObject from the Macro menu. Alternatively it may be run from the console. |
||
* see [[How to install macros]] for information on how to install this macro code |
|||
* see [[Customize Toolbars]] for information how to install as a button on a toolbar |
|||
==Usage== <!--T: |
==Usage== <!--T:7--> |
||
Select the document you wish to dump objects for, then start the macro from one of: |
Select the document you wish to dump objects for, then start the macro from one of: |
||
* the Macro menu |
* the Macro menu |
||
Line 21: | Line 35: | ||
* from a Toolbar |
* from a Toolbar |
||
<!--T:8--> |
|||
Depending on the parameters selected in the first window, the report will be displayed on the Report view or in a window. |
Depending on the parameters selected in the first window, the report will be displayed on the Report view or in a window. |
||
The information will show all objects in the current document. Some of the benefits to be expected are the detection of: |
The information will show all objects in the current document. Some of the benefits to be expected are the detection of: |
||
<!--T:9--> |
|||
* irregularities in object names (e.g. spelling errors or default names generated by FreeCAD) |
* irregularities in object names (e.g. spelling errors or default names generated by FreeCAD) |
||
* duplicate objects |
* duplicate objects |
||
Line 31: | Line 47: | ||
* unexpected segments in the Sketch Geometry (when the Show Sketcher Segments option is selected) |
* unexpected segments in the Sketch Geometry (when the Show Sketcher Segments option is selected) |
||
==User Interface== <!--T: |
==User Interface== <!--T:10--> |
||
The first window will take input which configures the Object Dump: |
The first window will take input which configures the Object Dump: |
||
<!--T: |
<!--T:11--> |
||
[[File:DumpObjectsGui1.jpg]] |
|||
[[File:DumpObjectsGui1.jpg|200px]] |
|||
<!--T:8--> |
|||
<!--T:12--> |
|||
The second window will be the report on the objects in the current document: |
The second window will be the report on the objects in the current document: |
||
<!--T:9--> |
|||
<!--T:13--> |
|||
[[File:DumpObjectsScreenSnapshot.jpg|500px]] |
|||
[[File:DumpObjectsGui2.jpg]] |
|||
==Options== <!--T:10--> |
|||
==Options== <!--T:14--> |
|||
* output may be directed to one of: |
* output may be directed to one of: |
||
** the Report view |
** the Report view |
||
Line 55: | Line 68: | ||
* Placement specifics may be listed for objects |
* Placement specifics may be listed for objects |
||
==Remarks== <!--T: |
==Remarks== <!--T:15--> |
||
Although tested with many object types in FreeCAD, there probably are some objects that it does not expect, in that case it should list them generically. |
Although tested with many object types in FreeCAD, there probably are some objects that it does not expect, in that case it should list them generically. |
||
==Links== <!--T: |
==Links== <!--T:16--> |
||
none (so far) |
none (so far) |
||
==Script== <!--T: |
==Script== <!--T:17--> |
||
</translate> |
|||
ToolBar Icon [[Image:Macro_Dump_Objects.png]] |
|||
{{Code|code= |
|||
'''Macro_Dump_Objects.FCMacro''' |
|||
{{MacroCode|code= |
|||
# |
# |
||
# Dump Object |
# Dump Object |
||
# v 0.2 - added report to CSV file |
|||
# v 0.1 - added report to window |
|||
# v 0.0 - report to Report view |
|||
# |
# |
||
#*********************************************************************************** |
#*********************************************************************************** |
||
# routine to dump object space for Geometric model in the currently active file |
# routine to dump object space for Geometric model in the currently active file |
||
# |
|||
# import statements |
|||
from PySide import QtGui, QtCore |
from PySide import QtGui, QtCore |
||
from datetime import datetime |
from datetime import datetime # datestamp on output window |
||
from os.path import expanduser # output directory for CSV |
|||
# Class definitions |
# UI Class definitions |
||
class configureMacro(QtGui.QDialog): |
class configureMacro(QtGui.QDialog): |
||
Line 101: | Line 123: | ||
button2 = QtGui.QPushButton(choice2, self) |
button2 = QtGui.QPushButton(choice2, self) |
||
button2.clicked.connect(self.onBtn2) |
button2.clicked.connect(self.onBtn2) |
||
button2.move( |
button2.move(235, 100) |
||
# button #3 |
|||
button3 = QtGui.QPushButton(choice3, self) |
|||
button3.clicked.connect(self.onBtn3) |
|||
button3.move(327, 100) |
|||
# define window xLoc,yLoc,xDim,yDim |
# define window xLoc,yLoc,xDim,yDim |
||
self.setGeometry( 250, 250, |
self.setGeometry( 250, 250, 435, 150) |
||
self.setWindowTitle("Select a Report Destination") |
self.setWindowTitle("Select a Report Destination") |
||
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) |
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) |
||
Line 115: | Line 141: | ||
def onBtn2(self): |
def onBtn2(self): |
||
self.result = choice2 |
self.result = choice2 |
||
self.close() |
|||
def onBtn3(self): |
|||
self.result = choice3 |
|||
self.close() |
self.close() |
||
class DisplayText(QtGui.QWidget): |
class DisplayText(QtGui.QWidget): |
||
#class DisplayText(QtGui.QMainWindow): |
|||
"""""" |
"""""" |
||
def __init__(self, textToDisplay): |
def __init__(self, textToDisplay): |
||
Line 158: | Line 186: | ||
self.close() |
self.close() |
||
# Class definitions |
|||
# define functions |
|||
# Function Definitions |
|||
def countObjects(): |
def countObjects(): |
||
Line 171: | Line 201: | ||
wb = obj.TypeId[0:obj.TypeId.find("::")] |
wb = obj.TypeId[0:obj.TypeId.find("::")] |
||
shape = obj.TypeId[obj.TypeId.find("::")+2:] |
shape = obj.TypeId[obj.TypeId.find("::")+2:] |
||
#print wb + "---" + shape |
|||
placementString = "" |
placementString = "" |
||
if obj.TypeId == "Sketcher::SketchObject": |
if obj.TypeId == "Sketcher::SketchObject": |
||
Line 180: | Line 211: | ||
if showPlacementFlag: |
if showPlacementFlag: |
||
placementString = str(obj.Placement) |
placementString = str(obj.Placement) |
||
if shape in ("Cylinder", "Cut", "Box", "Fuse", "Loft", "Feature", "Part2DObjectPython"): |
if shape in ("Cylinder", "Cut", "Box", "Fuse", "Loft", "Feature", "FeaturePython", "Part2DObjectPython"): |
||
printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name))) |
printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name))) |
||
else: # print shapes not in list above |
|||
elif obj.TypeId == "Part::Feature": |
|||
printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name))) |
|||
elif obj.TypeId == "Part::Part2DObjectPython": |
|||
printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name))) |
printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name))) |
||
elif wb == "PartDesign": |
elif wb == "PartDesign": |
||
if showPlacementFlag: |
if showPlacementFlag: |
||
placementString = str(obj.Placement) |
placementString = str(obj.Placement) |
||
if shape in ("Pad", "Fillet"): |
if shape in ("Pad", "Feature", "Fillet", "Part2DObjectPython"): |
||
printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name))) |
printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name))) |
||
else: # print shapes not in list above |
|||
elif obj.TypeId == "Part::Feature": |
|||
printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name))) |
|||
elif obj.TypeId == "Part::Part2DObjectPython": |
|||
printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name))) |
printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name))) |
||
elif obj.TypeId == "App::DocumentObjectGroup": |
elif obj.TypeId == "App::DocumentObjectGroup": |
||
Line 199: | Line 226: | ||
elif obj.TypeId == "Image::ImagePlane": |
elif obj.TypeId == "Image::ImagePlane": |
||
printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name))) |
printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name))) |
||
else: # print workbench shapes not in lists above |
|||
else: |
|||
printList.append(formatPrintLine(str(obj.TypeId), str(obj.Label), str(obj.Name))) |
printList.append(formatPrintLine(str(obj.TypeId), str(obj.Label), str(obj.Name))) |
||
if showPlacementFlag and len(placementString)!=0: |
if showPlacementFlag and len(placementString)!=0: |
||
Line 205: | Line 232: | ||
printList.append("") |
printList.append("") |
||
printList.append( |
printList.append(summarySeparator) |
||
from collections import OrderedDict |
from collections import OrderedDict |
||
sortedByTags = OrderedDict(sorted(objectTypeTable.items(), key=lambda x: x[1], reverse=True)) |
sortedByTags = OrderedDict(sorted(objectTypeTable.items(), key=lambda x: x[1], reverse=True)) |
||
Line 217: | Line 244: | ||
printList.append(formatPrintLineSum("Object Class Total is ", str(objectCLassCount))) |
printList.append(formatPrintLineSum("Object Class Total is ", str(objectCLassCount))) |
||
printList.append(formatPrintLineSum("Object Total is ", str(objectTotalCount))) |
printList.append(formatPrintLineSum("Object Total is ", str(objectTotalCount))) |
||
printList.append( |
printList.append(summarySeparator) |
||
return printList |
return printList |
||
Line 236: | Line 263: | ||
# flag = 1 printing verbose things like Sketch details or Placements, combine columns 3 & 4 |
# flag = 1 printing verbose things like Sketch details or Placements, combine columns 3 & 4 |
||
# flag = 2 printing the summary lines, combine columns 1 & 2 |
# flag = 2 printing the summary lines, combine columns 1 & 2 |
||
suffix = "" |
|||
if csvFlag: |
|||
pfs2 = printFormatString2csv |
|||
pfs3 = printFormatString3csv |
|||
pfs4 = printFormatString4csv |
|||
else: |
|||
pfs2 = printFormatString2 |
|||
pfs3 = printFormatString3 |
|||
pfs4 = printFormatString4 |
|||
if flag==0: |
if flag==0: |
||
aa = a[:f1] |
aa = a[:f1] |
||
Line 241: | Line 277: | ||
cc = c[:f3] |
cc = c[:f3] |
||
dd = d[:f4] |
dd = d[:f4] |
||
return |
return pfs4.format(aa,bb,cc,dd) |
||
elif flag==1: |
elif flag==1: |
||
aa = a[:f1] |
aa = a[:f1] |
||
Line 247: | Line 283: | ||
cc = c[:f3+f4] |
cc = c[:f3+f4] |
||
dd = d[:f4] |
dd = d[:f4] |
||
return |
return pfs3.format(aa,bb,cc) |
||
else: |
else: |
||
aa = a[:f1+f2] |
aa = a[:f1+f2] |
||
bb = b[:f3+f4] |
bb = b[:f3+f4] |
||
return |
return pfs2.format(aa,bb) |
||
# Constant definitions |
|||
# constants |
|||
# set some field widths |
# set some field widths |
||
screenWidth = QtGui.QDesktopWidget().screenGeometry().width() |
screenWidth = QtGui.QDesktopWidget().screenGeometry().width() |
||
Line 261: | Line 297: | ||
# and some print format strings |
# and some print format strings |
||
global printFormatString2, printFormatString3, printFormatString4 |
global printFormatString2, printFormatString3, printFormatString4 |
||
global printFormatString2csv, printFormatString3csv, printFormatString4csv |
|||
printFormatString2 = "{0:<"+str(f1+f2)+"} {1:<"+str(f3)+"}" |
printFormatString2 = "{0:<"+str(f1+f2)+"} {1:<"+str(f3)+"}" |
||
printFormatString2csv = "{0}, {1}" |
|||
printFormatString3 = "{0:<"+str(f1)+"} {1:<"+str(f2)+"} {2:<"+str(f3+f4)+"}" |
printFormatString3 = "{0:<"+str(f1)+"} {1:<"+str(f2)+"} {2:<"+str(f3+f4)+"}" |
||
printFormatString3csv = "{0}, {1}, {2}" |
|||
printFormatString4 = "{0:<"+str(f1)+"} {1:<"+str(f2)+"} {2:<"+str(f3)+"} {3:<"+str(f4)+"}" |
printFormatString4 = "{0:<"+str(f1)+"} {1:<"+str(f2)+"} {2:<"+str(f3)+"} {3:<"+str(f4)+"}" |
||
printFormatString4csv = "{0}, {1}, {2}, {3}" |
|||
# some button labels that are check in the code |
|||
# some button labels that are checked in the code |
|||
global choice1, choice2 |
|||
choice1 |
global choice1, choice2, choice3, csvFlag |
||
choice1 = "Report View"; choice2 = "CSV File"; choice3 = "Window" |
|||
csvFlag = False |
|||
summarySeparator = "=======================================================" |
|||
summarySeparatorCsv = "-------------------------------------------------------" |
|||
# code *********************************************************************************** |
# code *********************************************************************************** |
||
if FreeCAD.ActiveDocument != None: |
if FreeCAD.ActiveDocument != None: |
||
Line 279: | Line 321: | ||
if form.cbp.isChecked(): |
if form.cbp.isChecked(): |
||
showPlacementFlag = True |
showPlacementFlag = True |
||
if form.result == choice2: |
|||
csvFlag = True |
|||
showSketcherSegmentsFlag = False |
|||
showPlacementFlag = False |
|||
summarySeparator = summarySeparatorCsv |
|||
printList = countObjects() |
printList = countObjects() |
||
if form.result == choice1: # report to Report View |
if form.result == choice1: # report to Report View |
||
mainWindow = FreeCADGui.getMainWindow() |
|||
print printFormatString4.format( "", "", "(User Supplied)", "") |
|||
dockWidgets = mainWindow.findChildren(QtGui.QDockWidget) |
|||
print printFormatString4.format( "Type", "Shape", "Label", "Name") |
|||
reportViewFlag = False |
|||
print "" |
|||
for dw in dockWidgets: |
|||
if dw.objectName() == "Report view": |
|||
reportViewFlag = True |
|||
if reportViewFlag: |
|||
print printFormatString4.format( "", "", "(User Supplied)", "") |
|||
print printFormatString4.format( "Type", "Shape", "Label", "Name") |
|||
print "" |
|||
for line in printList: |
|||
print line + "\n" |
|||
else: |
|||
QtGui.QMessageBox.information(None,"","Please use 'Menu->View->Views->Report view' to open the 'Report view'") |
|||
if form.result == choice2: # report to CSV file |
|||
filePath = QtGui.QFileDialog.getSaveFileName(parent=None,caption="Save CSV file as",dir=expanduser("~"),filter="*.csv") |
|||
file = open(filePath[0],"w") |
|||
for line in printList: |
for line in printList: |
||
file.write(line + "\n") |
|||
file.close() |
|||
if form.result == choice2: # report to window |
|||
if form.result == choice3: # report to window |
|||
#---------------------------------------------------------------------- |
#---------------------------------------------------------------------- |
||
longPrintLine = "" |
longPrintLine = "" |
||
Line 304: | Line 366: | ||
#OCC version: 6.7.0 |
#OCC version: 6.7.0 |
||
# |
# |
||
#thus ends the macro... |
|||
}} |
}} |
||
{{clear}} |
Revision as of 00:28, 8 May 2020
Description |
---|
This macro generates a listing of all objects in the current document - the list can be in a window or on the Report view. Macro version: 1.0 Last modified: 2015-03-02 FreeCAD version: <= 0.17 Download: ToolBar Icon Author: Piffpoof |
Author |
Piffpoof |
Download |
ToolBar Icon |
Links |
Macros recipes How to install macros How to customize toolbars |
Macro Version |
1.0 |
Date last modified |
2015-03-02 |
FreeCAD Version(s) |
<= 0.17 |
Default shortcut |
None |
See also |
None |
When developing complex object models it is easy to loose track of exactly which objects are present as some may be hidden, obscured or transparent. Additionally with a large number of objects a naming system becomes necessary to keep track of the objects.
Description
The Dump Object code takes the current document and enumerates all the objects. A report is then generated listing each object, then a summary giving the total number of instances of each Class, followed by the total number of Classes and finally the total number of objects. The output may be directed to the Report view or to a window. The window is non-modal and will stay open until closed by the user. Each window has the time of the object dump in it's title bar, so the contents of multiple windows can be compared, say before and after a piece of code running.
The default operation lists all objects, optionally the placement of each object can be listed. Also for Sketches, each segment of the Geometry can be listed.
Installation
All the code for dumpObject.FCMacro is in one macro. So installation is comprised of copying the code to the appropriate Macro directory and invoking dumpObject from the Macro menu. Alternatively it may be run from the console.
- see How to install macros for information on how to install this macro code
- see Customize Toolbars for information how to install as a button on a toolbar
Usage
Select the document you wish to dump objects for, then start the macro from one of:
- the Macro menu
- from the Python console
- from a Toolbar
Depending on the parameters selected in the first window, the report will be displayed on the Report view or in a window. The information will show all objects in the current document. Some of the benefits to be expected are the detection of:
- irregularities in object names (e.g. spelling errors or default names generated by FreeCAD)
- duplicate objects
- objects with duplicate names (where FreeCAD has had to make the second object name unique)
- unexpected objects
- unexpected object Placements (when the Show Positions option is selected)
- unexpected segments in the Sketch Geometry (when the Show Sketcher Segments option is selected)
User Interface
The first window will take input which configures the Object Dump:
The second window will be the report on the objects in the current document:
Options
- output may be directed to one of:
- the Report view
- a non-modal window
- segments in the Geometry for each Sketch may be listed
- Placement specifics may be listed for objects
Remarks
Although tested with many object types in FreeCAD, there probably are some objects that it does not expect, in that case it should list them generically.
Links
none (so far)
Script
Macro_Dump_Objects.FCMacro
# # Dump Object # v 0.2 - added report to CSV file # v 0.1 - added report to window # v 0.0 - report to Report view # #*********************************************************************************** # routine to dump object space for Geometric model in the currently active file # # import statements from PySide import QtGui, QtCore from datetime import datetime # datestamp on output window from os.path import expanduser # output directory for CSV # UI Class definitions class configureMacro(QtGui.QDialog): """""" def __init__(self): super(configureMacro, self).__init__() self.initUI() def initUI(self): self.result = None # set up display only field for selected path type self.cbss = QtGui.QCheckBox("Show Sketcher Segments?", self) self.cbss.move(20,20) self.cbp = QtGui.QCheckBox("Show Positions?", self) self.cbp.move(220,20) self.pathTypeLbl = QtGui.QLabel("Select Report Destination:", self) self.pathTypeLbl.move(20, 70) # cancel button cancelButton = QtGui.QPushButton('Cancel', self) cancelButton.clicked.connect(self.onCancel) cancelButton.move(10, 100) # button #1 button1 = QtGui.QPushButton(choice1, self) button1.clicked.connect(self.onBtn1) button1.move(120, 100) # button #2 button2 = QtGui.QPushButton(choice2, self) button2.clicked.connect(self.onBtn2) button2.move(235, 100) # button #3 button3 = QtGui.QPushButton(choice3, self) button3.clicked.connect(self.onBtn3) button3.move(327, 100) # define window xLoc,yLoc,xDim,yDim self.setGeometry( 250, 250, 435, 150) self.setWindowTitle("Select a Report Destination") self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) self.show() def onCancel(self): self.result = "cancelled" self.close() def onBtn1(self): self.result = choice1 self.close() def onBtn2(self): self.result = choice2 self.close() def onBtn3(self): self.result = choice3 self.close() class DisplayText(QtGui.QWidget): """""" def __init__(self, textToDisplay): self.text = textToDisplay super(DisplayText, self).__init__() self.initUI(textToDisplay) def initUI(self, textToDisplay): """Constructor""" self.textToDisplay = textToDisplay # some window dimensions self.windowHome = screenWidth * 0.05 self.windowWidth = screenWidth * 0.9 self.windowHeight = 400 self.fieldMargin = 40 # some column titles columnLabels = QtGui.QLabel(formatPrintLine("Type / WB","Shape","User Supplied Label","Name")) columnLabels.setFont('Courier') # set up text editing widget text_editor = QtGui.QTextEdit(self) #self.setCentralWidget(self.text_editor) text_editor.setFont('Courier') text_editor.setLineWrapMode(QtGui.QTextEdit.NoWrap) text_editor.move(self.fieldMargin,self.fieldMargin) text_editor.move(0,self.fieldMargin) text_editor.resize(self.windowWidth-(2*self.fieldMargin),self.windowHeight-(2*self.fieldMargin)) text_editor.resize(self.windowWidth,self.windowHeight-(2*self.fieldMargin)) text_editor.append(self.textToDisplay) # set up the layout vBox = QtGui.QVBoxLayout() vBox.addWidget(columnLabels) vBox.addWidget(text_editor) self.setLayout(vBox) # define window xLoc,yLoc,xDim,yDim self.setGeometry( self.windowHome, self.windowHome, self.windowWidth, self.windowHeight) self.setWindowTitle("Object Dump of '" + FreeCADGui.ActiveDocument.Document.Label + "' at " + str(datetime.now())) self.show() #---------------------------------------------------------------------- def onOk(self): self.close() # Class definitions # Function Definitions def countObjects(): printList = list() objectTypeTable = {} # build up dictionary of different classes and keep a count for obj in FreeCAD.ActiveDocument.Objects: if objectTypeTable.has_key(obj.TypeId): objectTypeTable[obj.TypeId] = objectTypeTable[obj.TypeId]+1 else: objectTypeTable[obj.TypeId] = 1 wb = obj.TypeId[0:obj.TypeId.find("::")] shape = obj.TypeId[obj.TypeId.find("::")+2:] #print wb + "---" + shape placementString = "" if obj.TypeId == "Sketcher::SketchObject": printList.append(formatPrintLine("Sketch", "", str(obj.Label))) if showSketcherSegmentsFlag: for i in obj.Geometry: printList.append(formatPrintLine("", " -segment", str(i))) elif wb == "Part": if showPlacementFlag: placementString = str(obj.Placement) if shape in ("Cylinder", "Cut", "Box", "Fuse", "Loft", "Feature", "FeaturePython", "Part2DObjectPython"): printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name))) else: # print shapes not in list above printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name))) elif wb == "PartDesign": if showPlacementFlag: placementString = str(obj.Placement) if shape in ("Pad", "Feature", "Fillet", "Part2DObjectPython"): printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name))) else: # print shapes not in list above printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name))) elif obj.TypeId == "App::DocumentObjectGroup": printList.append(formatPrintLine("Group", "", str(obj.Label))) elif obj.TypeId == "Image::ImagePlane": printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name))) else: # print workbench shapes not in lists above printList.append(formatPrintLine(str(obj.TypeId), str(obj.Label), str(obj.Name))) if showPlacementFlag and len(placementString)!=0: printList.append(formatPrintLineMax("", " -placement", placementString)) printList.append("") printList.append(summarySeparator) from collections import OrderedDict sortedByTags = OrderedDict(sorted(objectTypeTable.items(), key=lambda x: x[1], reverse=True)) for k, v in sortedByTags.items(): printList.append(formatPrintLineSum(k,v)) printList.append("") objectClassCount = 0; objectTotalCount = 0 for i in objectTypeTable: objectTotalCount = objectTotalCount + objectTypeTable[i] objectCLassCount = len(objectTypeTable) printList.append(formatPrintLineSum("Object Class Total is ", str(objectCLassCount))) printList.append(formatPrintLineSum("Object Total is ", str(objectTotalCount))) printList.append(summarySeparator) return printList def formatPrintLineSum(a,b): return printLineFormatter(2, a, str(b), "", "") def formatPrintLineMax(a,b,c): return printLineFormatter(1, a, b, "", "") def formatPrintLine(a,b,c, *args): d = "" if len(args)==1: d = args[0] return printLineFormatter(0, a, b, c, d) def printLineFormatter(flag,a,b,c,d): # flag = 0 standard print, spread values over 4 columns # flag = 1 printing verbose things like Sketch details or Placements, combine columns 3 & 4 # flag = 2 printing the summary lines, combine columns 1 & 2 suffix = "" if csvFlag: pfs2 = printFormatString2csv pfs3 = printFormatString3csv pfs4 = printFormatString4csv else: pfs2 = printFormatString2 pfs3 = printFormatString3 pfs4 = printFormatString4 if flag==0: aa = a[:f1] bb = b[:f2] cc = c[:f3] dd = d[:f4] return pfs4.format(aa,bb,cc,dd) elif flag==1: aa = a[:f1] bb = b[:f2] cc = c[:f3+f4] dd = d[:f4] return pfs3.format(aa,bb,cc) else: aa = a[:f1+f2] bb = b[:f3+f4] return pfs2.format(aa,bb) # Constant definitions # set some field widths screenWidth = QtGui.QDesktopWidget().screenGeometry().width() global f1, f2, f3, f4 # f1 = 15; f2 = 25; f3 = 45; f4 = 25 # 110 columns in 1000 pixels f1 = 15*screenWidth/1000; f2 = 25*screenWidth/1000; f3 = 45*screenWidth/1000; f4 = 25*screenWidth/1000 # and some print format strings global printFormatString2, printFormatString3, printFormatString4 global printFormatString2csv, printFormatString3csv, printFormatString4csv printFormatString2 = "{0:<"+str(f1+f2)+"} {1:<"+str(f3)+"}" printFormatString2csv = "{0}, {1}" printFormatString3 = "{0:<"+str(f1)+"} {1:<"+str(f2)+"} {2:<"+str(f3+f4)+"}" printFormatString3csv = "{0}, {1}, {2}" printFormatString4 = "{0:<"+str(f1)+"} {1:<"+str(f2)+"} {2:<"+str(f3)+"} {3:<"+str(f4)+"}" printFormatString4csv = "{0}, {1}, {2}, {3}" # some button labels that are checked in the code global choice1, choice2, choice3, csvFlag choice1 = "Report View"; choice2 = "CSV File"; choice3 = "Window" csvFlag = False summarySeparator = "=======================================================" summarySeparatorCsv = "-------------------------------------------------------" # code *********************************************************************************** if FreeCAD.ActiveDocument != None: # ask if to window or to Report View... form = configureMacro() form.exec_() showSketcherSegmentsFlag = False if form.cbss.isChecked(): showSketcherSegmentsFlag = True showPlacementFlag = False if form.cbp.isChecked(): showPlacementFlag = True if form.result == choice2: csvFlag = True showSketcherSegmentsFlag = False showPlacementFlag = False summarySeparator = summarySeparatorCsv printList = countObjects() if form.result == choice1: # report to Report View mainWindow = FreeCADGui.getMainWindow() dockWidgets = mainWindow.findChildren(QtGui.QDockWidget) reportViewFlag = False for dw in dockWidgets: if dw.objectName() == "Report view": reportViewFlag = True if reportViewFlag: print printFormatString4.format( "", "", "(User Supplied)", "") print printFormatString4.format( "Type", "Shape", "Label", "Name") print "" for line in printList: print line + "\n" else: QtGui.QMessageBox.information(None,"","Please use 'Menu->View->Views->Report view' to open the 'Report view'") if form.result == choice2: # report to CSV file filePath = QtGui.QFileDialog.getSaveFileName(parent=None,caption="Save CSV file as",dir=expanduser("~"),filter="*.csv") file = open(filePath[0],"w") for line in printList: file.write(line + "\n") file.close() if form.result == choice3: # report to window #---------------------------------------------------------------------- longPrintLine = "" for line in printList: longPrintLine = longPrintLine + line + "\n" form = DisplayText(longPrintLine) # #OS: Mac OS X #Word size: 64-bit #Version: 0.14.3703 (Git) #Branch: releases/FreeCAD-0-14 #Hash: c6edd47334a3e6f209e493773093db2b9b4f0e40 #Python version: 2.7.5 #Qt version: 4.8.6 #Coin version: 3.1.3 #SoQt version: 1.5.0 #OCC version: 6.7.0 # #thus ends the macro...