Macro Dump Objects/it: Difference between revisions

From FreeCAD Documentation
(Created page with "==Descrizione== Il codice Dump Object enumera tutti gli oggetti contenuti nel documento corrente. Quindi genera un rapporto che elenca ogni oggetto, poi una sintesi che fornis...")
(Updating to match new version of source page)
 
(30 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<languages/>
{{Macro/it|Icon=Macro_Dump_Objects|Name=Macro Dump Objects|Name/it=Dump Objects|Description=Questa macro genera un elenco di tutti gli oggetti del documento corrente. L'elenco può apparire nella finestra dei Rapporti o in una finestra indipendente.|Author=Piffpoof}}


<div class="mw-translate-fuzzy">
{{Macro/it
|Name=Macro Dump Objects
|Translate=Elenca oggetti
|Description=Questa macro genera un elenco di tutti gli oggetti del documento corrente. L'elenco può apparire nella finestra dei Rapporti o in una finestra indipendente.
|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]
}}
</div>

<div class="mw-translate-fuzzy">
Durante lo sviluppo di modelli complessi è facile perdere traccia di quali sono gli oggetti effettivamente presenti dato che alcuni possono essere nascosti, coperti o trasparenti. Inoltre con un gran numero di oggetti diventa necessario conservarne la traccia per gestire il sistema di denominazione.
Durante lo sviluppo di modelli complessi è facile perdere traccia di quali sono gli oggetti effettivamente presenti dato che alcuni possono essere nascosti, coperti o trasparenti. Inoltre con un gran numero di oggetti diventa necessario conservarne la traccia per gestire il sistema di denominazione.
</div>


[[File:DumpObjectsScreenSnapshot.jpg|500px]]
[[File:DumpObjectsScreenSnapshot.jpg|500px]]


==Description==

<div class="mw-translate-fuzzy">
==Descrizione==
==Descrizione==
Il codice Dump Object enumera tutti gli oggetti contenuti nel documento corrente. Quindi genera un rapporto che elenca ogni oggetto, poi una sintesi che fornisce il numero totale di istanze di ogni Classe, seguito dal numero totale di classi e infine il numero totale di oggetti. L'output del rapporto può essere indirizzato alla vista Report o ad una finestra indipendente. La finestra è non-modale e rimane aperta fino a quando non viene chiusa dall'utente. Ogni finestra contiene nella barra del titolo la data e l'ora in cui è stata generata, quindi si può confrontare il contenuto di più finestre, ad esempio, prima e dopo l'esecuzione di una parte di codice.
Il codice Dump Object enumera tutti gli oggetti contenuti nel documento corrente. Quindi genera un rapporto che elenca ogni oggetto, poi una sintesi che fornisce il numero totale di istanze di ogni Classe, seguito dal numero totale di classi e infine il numero totale di oggetti. L'output del rapporto può essere indirizzato alla vista Report o ad una finestra indipendente. La finestra è non-modale e rimane aperta fino a quando non viene chiusa dall'utente. Ogni finestra contiene nella barra del titolo la data e l'ora in cui è stata generata, quindi si può confrontare il contenuto di più finestre, ad esempio, prima e dopo l'esecuzione di una parte di codice.
</div>


Di default sono elencati tutti gli oggetti, come opzione si può indicare anche il posizionamento di ogni oggetto. Inoltre, per gli schizzi si può elencare ogni segmento della geometria.
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==
==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.
<div class="mw-translate-fuzzy">
==Installazione==
Tutto il codice per dumpObject.FCMacro è contenuto nella macro. L'installazione consiste nel copiare il suo codice nella appropriata directory delle Macro. Si attiva invocando dumpObject dal menu Macro. In alternativa, può essere eseguita dalla console.
* per informazioni su come installare il codice delle macro vedere la pagina [[How to install macros/it|Come installare le macro]]
* per informazioni su come installarla abbinata a un pulsante in una barra degli strumenti vedere la pagina [[Customize_Toolbars/it|Personalizzare la barra degli strumenti]]
</div>


==Usage==
==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


<div class="mw-translate-fuzzy">
Depending on the parameters selected in the first window, the report will be displayed on the Report view or in a window.
==Uso==
The information will show all objects in the current document. Some of the benefits to be expected are the detection of:
Selezionare il documento di cui si desidera analizzare gli oggetti per poi avviare la macro in uno di questi modi:
* dal menu Macro
* dalla console Python
* dalla barra degli strumenti
</div>


A seconda dei parametri selezionati nella prima finestra, il rapporto viene visualizzato nella vista Report o in una finestra.
* irregularities in object names (e.g. spelling errors or default names generated by FreeCAD)
Le informazioni mostrano tutti gli oggetti del documento corrente. Alcuni dei benefici attesi sono l'individuazione di:
* duplicate objects

* objects with duplicate names (where FreeCAD has had to make the second object name unique)
* irregolarità nei nomi di oggetti, ad esempio errori di ortografia o nomi predefiniti generati da FreeCAD
* unexpected objects
* oggetti duplicati
* unexpected object Placements (when the Show Positions option is selected)
* oggetti con nomi duplicati (dove FreeCAD ha dovuto creare il secondo nome oggetto unico)
* unexpected segments in the Sketch Geometry (when the Show Sketcher Segments option is selected)
* oggetti inaspettati
* posizionamenti inattesi di oggetti (quando è selezionata l'opzione Show Positions)
* segmenti inattesi nella geometria dello schizzo (quando è selezionata l'opzione Show Sketcher Segments)


==User Interface==
==User Interface==

The first window will take input which configures the Object Dump:
<div class="mw-translate-fuzzy">
==Interfaccia utente==
La prima finestra è quella che serve per configurare Object Dump:
</div>


[[File:DumpObjectsGui1.jpg]]
[[File:DumpObjectsGui1.jpg]]


La seconda finestra è quella che contiene il rapporto sugli oggetti del documento corrente:

The second window will be the report on the objects in the current document:



[[File:DumpObjectsGui2.jpg]]
[[File:DumpObjectsGui2.jpg]]


==Options==
==Options==

* output may be directed to one of:
<div class="mw-translate-fuzzy">
** the Report view
==Opzioni==
**a non-modal window
* l'output può essere diretto verso:
* segments in the Geometry for each Sketch may be listed
** la vista Report
* Placement specifics may be listed for objects
** una finestra non-modale
* si possono elencare i segmenti della geometria di ogni schizzo
* si possono elencare le specifiche di posizionamento degli oggetti
</div>


==Remarks==
==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.


<div class="mw-translate-fuzzy">
==Links==
==Osservazioni==
none (so far)
Anche se testata con molti tipi di oggetti in FreeCAD, ci sono probabilmente alcuni oggetti che sono inattesi, in questo caso dovrebbe elencarli genericamente.
</div>


==Script==
==Script==

{{Code|code=
Toolbar Icon

[[Image:Macro_Dump_Objects.png]]

'''Macro_Dump_Objects.FCMacro'''

{{MacroCode|code=
#
#
# Dump Object
# Dump Object
# v 0.3 - 14/01/2023 conversion to PySide2
# v 0.2
# 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
#
__title__ = "Dump_Objects"
__author__ = "Piffpoof"
__url__ = "https://wiki.freecadweb.org/Macro_Dump_Objects"
__version__ = "0.3"
__date__ = "2023/01/14" #YYYY/MM/DD
#


from PySide import QtGui, QtCore
# import statements
from datetime import datetime
from PySide2 import QtWidgets, QtGui, QtCore
from PySide2.QtWidgets import * #QDialog , QLineEdit, QPushButton, QApplication
from datetime import datetime # datestamp on output window
from os.path import expanduser # output directory for CSV
import math
# UI Class definitions


class configureMacro(QtWidgets.QDialog):
# Class definitions
""""""
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 = QtWidgets.QCheckBox("Show Sketcher Segments?", self)
self.cbss.move(20,20)
self.cbp = QtWidgets.QCheckBox("Show Positions?", self)
self.cbp.move(220,20)
self.pathTypeLbl = QtWidgets.QLabel("Select Report Destination:", self)
self.pathTypeLbl.move(20, 70)
# cancel button
cancelButton = QtWidgets.QPushButton('Cancel', self)
cancelButton.clicked.connect(self.onCancel)
cancelButton.move(10, 100)
# button #1
button1 = QtWidgets.QPushButton(choice1, self)
button1.clicked.connect(self.onBtn1)
button1.move(120, 100)
# button #2
button2 = QtWidgets.QPushButton(choice2, self)
button2.clicked.connect(self.onBtn2)
button2.move(235, 100)
# button #3
button3 = QtWidgets.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 configureMacro(QtGui.QDialog):
class DisplayText(QtWidgets.QWidget):
""""""
""""""
def __init__(self):
def __init__(self, textToDisplay):
self.text = textToDisplay
super(configureMacro, self).__init__()
super(DisplayText, self).__init__()
self.initUI()
def initUI(self):
self.initUI(textToDisplay)
def initUI(self, textToDisplay):
self.result = None
"""Constructor"""
# set up display only field for selected path type
self.textToDisplay = textToDisplay
self.cbss = QtGui.QCheckBox("Show Sketcher Segments?", self)
# some window dimensions
self.cbss.move(20,20)
self.windowHome = screenWidth * 0.05
self.cbp = QtGui.QCheckBox("Show Positions?", self)
self.windowWidth = screenWidth * 0.9
self.cbp.move(220,20)
self.windowHeight = 400
self.pathTypeLbl = QtGui.QLabel("Select Report Destination:", self)
self.fieldMargin = 40
self.pathTypeLbl.move(20, 70)
# some column titles
# cancel button
columnLabels = QtWidgets.QLabel(formatPrintLine("Type / WB","Shape","User Supplied Label","Name"))
cancelButton = QtGui.QPushButton('Cancel', self)
columnLabels.setFont('Courier')
cancelButton.clicked.connect(self.onCancel)
# set up text editing widget
cancelButton.move(10, 100)
text_editor = QtWidgets.QTextEdit(self)
# button #1
#self.setCentralWidget(self.text_editor)
button1 = QtGui.QPushButton(choice1, self)
text_editor.setFont('Courier')
button1.clicked.connect(self.onBtn1)
text_editor.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
button1.move(120, 100)
text_editor.move(self.fieldMargin,self.fieldMargin)
# button #2
text_editor.move(0,self.fieldMargin)
button2 = QtGui.QPushButton(choice2, self)
text_editor.resize(self.windowWidth-(2*self.fieldMargin),self.windowHeight-(2*self.fieldMargin))
button2.clicked.connect(self.onBtn2)
text_editor.resize(self.windowWidth,self.windowHeight-(2*self.fieldMargin))
button2.move(275, 100)
text_editor.append(self.textToDisplay)
# define window xLoc,yLoc,xDim,yDim
# set up the layout
self.setGeometry( 250, 250, 400, 150)
vBox = QtWidgets.QVBoxLayout()
self.setWindowTitle("Select a Report Destination")
vBox.addWidget(columnLabels)
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
vBox.addWidget(text_editor)
self.show()
self.setLayout(vBox)
def onCancel(self):
# define window xLoc,yLoc,xDim,yDim
self.result = "cancelled"
self.setGeometry( self.windowHome, self.windowHome, self.windowWidth, self.windowHeight)
self.close()
self.setWindowTitle("Object Dump of '" + FreeCADGui.ActiveDocument.Document.Label + "' at " + str(datetime.now()))
def onBtn1(self):
self.show()
self.result = choice1
#----------------------------------------------------------------------
self.close()
def onBtn2(self):
def onOk(self):
self.close()
self.result = choice2
self.close()


# Class definitions
class DisplayText(QtGui.QWidget):
#class DisplayText(QtGui.QMainWindow):
""""""
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)
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()


# Function Definitions
# define functions


def countObjects():
def countObjects():
printList = list()
printList = list()
objectTypeTable = {}
objectTypeTable = {}
# build up dictionary of different classes and keep a count
# build up dictionary of different classes and keep a count
for obj in FreeCAD.ActiveDocument.Objects:
for obj in FreeCAD.ActiveDocument.Objects:
if objectTypeTable.has_key(obj.TypeId):
if objectTypeTable.__contains__(obj.TypeId):
objectTypeTable[obj.TypeId] = objectTypeTable[obj.TypeId]+1
objectTypeTable[obj.TypeId] = objectTypeTable[obj.TypeId]+1
else:
else:
objectTypeTable[obj.TypeId] = 1
objectTypeTable[obj.TypeId] = 1
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":
printList.append(formatPrintLine("Sketch", "", str(obj.Label)))
printList.append(formatPrintLine("Sketch", "", str(obj.Label)))
if showSketcherSegmentsFlag:
if showSketcherSegmentsFlag:
for i in obj.Geometry:
for i in obj.Geometry:
printList.append(formatPrintLine("", " -segment", str(i)))
printList.append(formatPrintLine("", " -segment", str(i)))
elif wb == "Part":
elif wb == "Part":
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)))
elif obj.TypeId == "Part::Feature":
else: # print shapes not in list above
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 == "Part::Part2DObjectPython":
elif wb == "PartDesign":
printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name)))
if showPlacementFlag:
elif wb == "PartDesign":
placementString = str(obj.Placement)
if showPlacementFlag:
if shape in ("Pad", "Feature", "Fillet", "Part2DObjectPython"):
placementString = str(obj.Placement)
printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name)))
if shape in ("Pad", "Fillet"):
else: # print shapes not in list above
printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name)))
printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name)))
elif obj.TypeId == "Part::Feature":
elif obj.TypeId == "App::DocumentObjectGroup":
printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name)))
printList.append(formatPrintLine("Group", "", str(obj.Label)))
elif obj.TypeId == "Part::Part2DObjectPython":
elif obj.TypeId == "Image::ImagePlane":
printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name)))
printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name)))
elif obj.TypeId == "App::DocumentObjectGroup":
else: # print workbench shapes not in lists above
printList.append(formatPrintLine("Group", "", str(obj.Label)))
printList.append(formatPrintLine(str(obj.TypeId), str(obj.Label), str(obj.Name)))
elif obj.TypeId == "Image::ImagePlane":
if showPlacementFlag and len(placementString)!=0:
printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name)))
printList.append(formatPrintLineMax("", " -placement", placementString))
else:
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("")
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))
for k, v in sortedByTags.items():
for k, v in sortedByTags.items():
printList.append(formatPrintLineSum(k,v))
printList.append(formatPrintLineSum(k,v))
printList.append("")
printList.append("")
objectClassCount = 0; objectTotalCount = 0
objectClassCount = 0; objectTotalCount = 0
for i in objectTypeTable:
for i in objectTypeTable:
objectTotalCount = objectTotalCount + objectTypeTable[i]
objectTotalCount = objectTotalCount + objectTypeTable[i]
objectCLassCount = len(objectTypeTable)
objectCLassCount = len(objectTypeTable)
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


def formatPrintLineSum(a,b):
def formatPrintLineSum(a,b):
return printLineFormatter(2, a, str(b), "", "")
return printLineFormatter(2, a, str(b), "", "")


def formatPrintLineMax(a,b,c):
def formatPrintLineMax(a,b,c):
return printLineFormatter(1, a, b, "", "")
return printLineFormatter(1, a, b, "", "")


def formatPrintLine(a,b,c, *args):
def formatPrintLine(a,b,c, *args):
d = ""
d = ""
if len(args)==1:
if len(args)==1:
d = args[0]
d = args[0]
return printLineFormatter(0, a, b, c, d)
return printLineFormatter(0, a, b, c, d)


def printLineFormatter(flag,a,b,c,d):
def printLineFormatter(flag,a,b,c,d):
# flag = 0 standard print, spread values over 4 columns
# flag = 0 standard print, spread values over 4 columns
# 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 flag==0:
if csvFlag:
aa = a[:f1]
pfs2 = printFormatString2csv
bb = b[:f2]
pfs3 = printFormatString3csv
cc = c[:f3]
pfs4 = printFormatString4csv
dd = d[:f4]
else:
return printFormatString4.format(aa,bb,cc,dd)
pfs2 = printFormatString2
elif flag==1:
pfs3 = printFormatString3
aa = a[:f1]
pfs4 = printFormatString4
bb = b[:f2]
if flag==0:
cc = c[:f3+f4]
dd = d[:f4]
aa = a[:f1]
bb = b[:f2]
return printFormatString3.format(aa,bb,cc)
cc = c[:f3]
else:
aa = a[:f1+f2]
dd = d[:f4]
return pfs4.format(aa,bb,cc,dd)
bb = b[:f3+f4]
elif flag==1:
return printFormatString2.format(aa,bb)
aa = a[:f1]
bb = b[:f2]
cc = c[:f3+f4]
dd = d[:f4]
return pfs3.format(aa,bb,cc)
else:
print(a)
aa = a[:f1+f2]
bb = b[:f3+f4]
return pfs2.format(aa,bb)


# Constant definitions
# constants
# set some field widths
# set some field widths
screenWidth = QtGui.QDesktopWidget().screenGeometry().width()
screenWidth = QtWidgets.QDesktopWidget().screenGeometry().width()
global f1, f2, f3, f4
global f1, f2, f3, f4
# f1 = 15; f2 = 25; f3 = 45; f4 = 25 # 110 columns in 1000 pixels
# 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
f1 = math.floor(15*screenWidth/1000); f2 = math.floor(25*screenWidth/1000); f3 = math.floor(45*screenWidth/1000); f4 = math.floor(25*screenWidth/1000)
# 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 = "Report View"; choice2 = "Window"
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:
# ask if to window or to Report View...
# ask if to window or to Report View...
form = configureMacro()
form = configureMacro()
form.exec_()
form.exec_()
showSketcherSegmentsFlag = False
showSketcherSegmentsFlag = False
if form.cbss.isChecked():
if form.cbss.isChecked():
showSketcherSegmentsFlag = True
showSketcherSegmentsFlag = True
showPlacementFlag = False
showPlacementFlag = False
if form.cbp.isChecked():
if form.cbp.isChecked():
showPlacementFlag = True
showPlacementFlag = True
if form.result == choice2:
printList = countObjects()
csvFlag = True
if form.result == choice1: # report to Report View
showSketcherSegmentsFlag = False
print printFormatString4.format( "", "", "(User Supplied)", "")
showPlacementFlag = False
print printFormatString4.format( "Type", "Shape", "Label", "Name")
summarySeparator = summarySeparatorCsv
print ""
for line in printList:
printList = countObjects()
if form.result == choice1: # report to Report View
print line + "\n"
mainWindow = FreeCADGui.getMainWindow()
if form.result == choice2: # report to window
dockWidgets = mainWindow.findChildren(QtWidgets.QDockWidget)
#----------------------------------------------------------------------
reportViewFlag = False
longPrintLine = ""
for line in printList:
for dw in dockWidgets:
if dw.objectName() == "Report view":
longPrintLine = longPrintLine + line + "\n"
reportViewFlag = True
form = DisplayText(longPrintLine)
if reportViewFlag:
print( printFormatString4.format( "", "", "(User Supplied)", ""))
print( printFormatString4.format( "Type", "Shape", "Label", "Name"))
print( "")
for line in printList:
print( line + "\n")
else:
QtWidgets.QMessageBox.information(None,"","Please use 'Menu->View->Views->Report view' to open the 'Report view'")
if form.result == choice2: # report to CSV file
filePath = QtWidgets.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
#OS: Windows 10 Version 2009
#Word size: 64-bit
#Word size of FreeCAD: 64-bit
#Version: 0.14.3703 (Git)
#Version: 0.21.0.31513 (Git)
#Build type: Release
#Branch: releases/FreeCAD-0-14
#Branch: master
#Hash: c6edd47334a3e6f209e493773093db2b9b4f0e40
#Hash: b2ab8edba4bfd71681e639f8c3f1105066bed4c7
#Python version: 2.7.5
#Python 3.10.8, Qt 5.15.4, Coin 4.0.0, Vtk 9.1.0, OCC 7.6.3
#Qt version: 4.8.6
#Coin version: 3.1.3
#SoQt version: 1.5.0
#OCC version: 6.7.0
#
#
#thus ends the macro...

}}
}}

{{clear}}
{{clear}}
<languages/>

Latest revision as of 17:41, 14 January 2023

Other languages:

Elenca oggetti

Descrizione
Questa macro genera un elenco di tutti gli oggetti del documento corrente. L'elenco può apparire nella finestra dei Rapporti o in una finestra indipendente.

Versione macro: 1.0
Ultima modifica: 2015-03-02
Versione FreeCAD: <= 0.17
Download: ToolBar Icon
Autore: Piffpoof
Autore
Piffpoof
Download
ToolBar Icon
Link
Versione macro
1.0
Data ultima modifica
2015-03-02
Versioni di FreeCAD
<= 0.17
Scorciatoia
Nessuna
Vedere anche
Nessuno

Durante lo sviluppo di modelli complessi è facile perdere traccia di quali sono gli oggetti effettivamente presenti dato che alcuni possono essere nascosti, coperti o trasparenti. Inoltre con un gran numero di oggetti diventa necessario conservarne la traccia per gestire il sistema di denominazione.

Description

Descrizione

Il codice Dump Object enumera tutti gli oggetti contenuti nel documento corrente. Quindi genera un rapporto che elenca ogni oggetto, poi una sintesi che fornisce il numero totale di istanze di ogni Classe, seguito dal numero totale di classi e infine il numero totale di oggetti. L'output del rapporto può essere indirizzato alla vista Report o ad una finestra indipendente. La finestra è non-modale e rimane aperta fino a quando non viene chiusa dall'utente. Ogni finestra contiene nella barra del titolo la data e l'ora in cui è stata generata, quindi si può confrontare il contenuto di più finestre, ad esempio, prima e dopo l'esecuzione di una parte di codice.

Di default sono elencati tutti gli oggetti, come opzione si può indicare anche il posizionamento di ogni oggetto. Inoltre, per gli schizzi si può elencare ogni segmento della geometria.

Installation

Installazione

Tutto il codice per dumpObject.FCMacro è contenuto nella macro. L'installazione consiste nel copiare il suo codice nella appropriata directory delle Macro. Si attiva invocando dumpObject dal menu Macro. In alternativa, può essere eseguita dalla console.

Usage

Uso

Selezionare il documento di cui si desidera analizzare gli oggetti per poi avviare la macro in uno di questi modi:

  • dal menu Macro
  • dalla console Python
  • dalla barra degli strumenti

A seconda dei parametri selezionati nella prima finestra, il rapporto viene visualizzato nella vista Report o in una finestra. Le informazioni mostrano tutti gli oggetti del documento corrente. Alcuni dei benefici attesi sono l'individuazione di:

  • irregolarità nei nomi di oggetti, ad esempio errori di ortografia o nomi predefiniti generati da FreeCAD
  • oggetti duplicati
  • oggetti con nomi duplicati (dove FreeCAD ha dovuto creare il secondo nome oggetto unico)
  • oggetti inaspettati
  • posizionamenti inattesi di oggetti (quando è selezionata l'opzione Show Positions)
  • segmenti inattesi nella geometria dello schizzo (quando è selezionata l'opzione Show Sketcher Segments)

User Interface

Interfaccia utente

La prima finestra è quella che serve per configurare Object Dump:

La seconda finestra è quella che contiene il rapporto sugli oggetti del documento corrente:

Options

Opzioni

  • l'output può essere diretto verso:
    • la vista Report
    • una finestra non-modale
  • si possono elencare i segmenti della geometria di ogni schizzo
  • si possono elencare le specifiche di posizionamento degli oggetti

Remarks

Osservazioni

Anche se testata con molti tipi di oggetti in FreeCAD, ci sono probabilmente alcuni oggetti che sono inattesi, in questo caso dovrebbe elencarli genericamente.

Script

Toolbar Icon

Macro_Dump_Objects.FCMacro

#
#                       Dump Object
#                       v 0.3 - 14/01/2023 conversion to PySide2
#                       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
#
__title__   = "Dump_Objects"
__author__  = "Piffpoof"
__url__     = "https://wiki.freecadweb.org/Macro_Dump_Objects"
__version__ = "0.3"
__date__    = "2023/01/14"    #YYYY/MM/DD
#

# import statements
from PySide2 import QtWidgets, QtGui, QtCore
from PySide2.QtWidgets import * #QDialog , QLineEdit, QPushButton, QApplication
from datetime import datetime       # datestamp on output window
from os.path import expanduser      # output directory for CSV
import math
# UI Class definitions

class configureMacro(QtWidgets.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           = QtWidgets.QCheckBox("Show Sketcher Segments?", self)
        self.cbss.move(20,20)
        self.cbp            = QtWidgets.QCheckBox("Show Positions?", self)
        self.cbp.move(220,20)
        self.pathTypeLbl    = QtWidgets.QLabel("Select Report Destination:", self)
        self.pathTypeLbl.move(20, 70)
        # cancel button
        cancelButton = QtWidgets.QPushButton('Cancel', self)
        cancelButton.clicked.connect(self.onCancel)
        cancelButton.move(10, 100)
        # button #1
        button1 = QtWidgets.QPushButton(choice1, self)
        button1.clicked.connect(self.onBtn1)
        button1.move(120, 100)
        # button #2
        button2 = QtWidgets.QPushButton(choice2, self)
        button2.clicked.connect(self.onBtn2)
        button2.move(235, 100)
        # button #3
        button3 = QtWidgets.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(QtWidgets.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 = QtWidgets.QLabel(formatPrintLine("Type / WB","Shape","User Supplied Label","Name"))
        columnLabels.setFont('Courier')
        # set up text editing widget
        text_editor = QtWidgets.QTextEdit(self)
        #self.setCentralWidget(self.text_editor)
        text_editor.setFont('Courier')
        text_editor.setLineWrapMode(QtWidgets.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 = QtWidgets.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.__contains__(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:
        print(a)
        aa = a[:f1+f2]
        bb = b[:f3+f4]
        return pfs2.format(aa,bb)

# Constant definitions
# set some field widths
screenWidth = QtWidgets.QDesktopWidget().screenGeometry().width()
global f1, f2, f3, f4
# f1 = 15; f2 = 25; f3 = 45; f4 = 25 # 110 columns in 1000 pixels
f1 = math.floor(15*screenWidth/1000); f2 = math.floor(25*screenWidth/1000); f3 = math.floor(45*screenWidth/1000); f4 = math.floor(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(QtWidgets.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:
            QtWidgets.QMessageBox.information(None,"","Please use 'Menu->View->Views->Report view' to open the 'Report view'")
    if form.result == choice2: # report to CSV file
        filePath = QtWidgets.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: Windows 10 Version 2009
#Word size of FreeCAD: 64-bit
#Version: 0.21.0.31513 (Git)
#Build type: Release
#Branch: master
#Hash: b2ab8edba4bfd71681e639f8c3f1105066bed4c7
#Python 3.10.8, Qt 5.15.4, Coin 4.0.0, Vtk 9.1.0, OCC 7.6.3
#
#thus ends the macro...