forked from youen/assembly_handbook
Added system to export part list in CSV file
Added possibility to set material and/or weight of each part Part weight is calculated from volume and density if the material is configured
This commit is contained in:
parent
731b203c5e
commit
b63643b153
@ -103,6 +103,9 @@ class AssemblyHandbookWorkbench(Gui.Workbench):
|
|||||||
|
|
||||||
self.importModule('ahb_cmd_view_refresh')
|
self.importModule('ahb_cmd_view_refresh')
|
||||||
toolbox.append("AHB_view_refresh")
|
toolbox.append("AHB_view_refresh")
|
||||||
|
|
||||||
|
self.importModule('ahb_cmd_export_parts_list')
|
||||||
|
toolbox.append("AHB_export_parts_list")
|
||||||
|
|
||||||
if self.dev:
|
if self.dev:
|
||||||
self.importModule('ahb_cmd_reload')
|
self.importModule('ahb_cmd_reload')
|
||||||
|
106
ahb_cmd_export_parts_list.py
Normal file
106
ahb_cmd_export_parts_list.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import FreeCADGui as Gui
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
import ahb_utils
|
||||||
|
from ahb_material import Material
|
||||||
|
|
||||||
|
class PartInfo:
|
||||||
|
def __init__(self, document, obj):
|
||||||
|
self.document = document
|
||||||
|
self.reference = obj.Label
|
||||||
|
|
||||||
|
if len(self.reference) == 3 and self.reference[0:1] in ['L', 'M', 'T', 'R', 'E']:
|
||||||
|
self.reference = 'TB_' + self.reference
|
||||||
|
|
||||||
|
self.material = 'Unknown'
|
||||||
|
try:
|
||||||
|
self.material = obj.Assembly_handbook_Material
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.size = [obj.Shape.BoundBox.XLength, obj.Shape.BoundBox.YLength, obj.Shape.BoundBox.ZLength] # in mm
|
||||||
|
self.volume = obj.Shape.Volume # in mm3
|
||||||
|
self.mass = -1 # in g (negative means unknown mass)
|
||||||
|
density = -1 # in g/cm3
|
||||||
|
material = Material.Get(self.material)
|
||||||
|
if material is not None:
|
||||||
|
density = material.density
|
||||||
|
if density >= 0: self.mass = density * (self.volume / 1000)
|
||||||
|
try:
|
||||||
|
part_mass = obj.Assembly_handbook_Weight
|
||||||
|
if part_mass >= 0:
|
||||||
|
self.mass = part_mass
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
self.count = 0
|
||||||
|
|
||||||
|
class AHB_ExportPartsList:
|
||||||
|
def GetResources(self):
|
||||||
|
return {"MenuText": "Export parts list (CSV)",
|
||||||
|
"ToolTip": "Exports all parts of the selected assembly in CSV format",
|
||||||
|
"Pixmap": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
def IsActive(self):
|
||||||
|
obj = Gui.Selection.getSelection()
|
||||||
|
if len(obj) == 1:
|
||||||
|
obj = obj[0]
|
||||||
|
return obj.TypeId == 'App::Part' and 'AssemblyType' in obj.PropertiesList
|
||||||
|
return False
|
||||||
|
|
||||||
|
def Activated(self):
|
||||||
|
all_parts = {}
|
||||||
|
|
||||||
|
rootAssembly = Gui.Selection.getSelection()[0]
|
||||||
|
|
||||||
|
def add_part(part):
|
||||||
|
#print(part.Label + " (" + part.LinkedObject.Label + ")")
|
||||||
|
try:
|
||||||
|
info = all_parts[part.LinkedObject]
|
||||||
|
except:
|
||||||
|
info = PartInfo(part.LinkedObject.Document.Name, part.LinkedObject)
|
||||||
|
all_parts[part.LinkedObject] = info
|
||||||
|
|
||||||
|
info.count += 1
|
||||||
|
|
||||||
|
def process_group(group):
|
||||||
|
for part in group.Group:
|
||||||
|
if not part.Visibility:
|
||||||
|
continue
|
||||||
|
|
||||||
|
isPartLink = part.TypeId == 'App::Link' or (part.TypeId == 'Part::FeaturePython' and hasattr(part, 'LinkedObject'))
|
||||||
|
partType = None
|
||||||
|
isSinglePart = None
|
||||||
|
try:
|
||||||
|
partType = part.Type
|
||||||
|
isSinglePart = part.Assembly_handbook_IsSinglePart
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if isPartLink:
|
||||||
|
if isSinglePart != True and (partType == 'Assembly' or (part.Group[1].Label == 'Constraints' and part.Group[2].Label == 'Variables' and part.Group[3].Label == 'Configurations')):
|
||||||
|
process_group(part.LinkedObject)
|
||||||
|
else:
|
||||||
|
add_part(part)
|
||||||
|
else:
|
||||||
|
if part.TypeId != 'App::DocumentObjectGroup' and part.TypeId != 'Spreadsheet::Sheet' and partType != 'App::PropertyContainer':
|
||||||
|
print("??? " + part.Label)
|
||||||
|
pass
|
||||||
|
|
||||||
|
print("Exporting all parts contained in assembly: " + rootAssembly.Label + "...")
|
||||||
|
process_group(rootAssembly)
|
||||||
|
|
||||||
|
file_name = rootAssembly.Document.FileName.replace('.FCStd', '') + '_list.csv'
|
||||||
|
with open(file_name, "w") as f:
|
||||||
|
f.write("Document, Reference, Material, SizeX (mm), SizeY (mm), SizeZ (mm), Volume (cm3), Mass (g), Count\n")
|
||||||
|
for part in all_parts.values():
|
||||||
|
mass_str = ''
|
||||||
|
if part.mass >= 10:
|
||||||
|
mass_str = str(int(part.mass + 0.5))
|
||||||
|
elif part.mass >= 0:
|
||||||
|
mass_str = str(int(part.mass*10 + 0.5) / 10.0)
|
||||||
|
f.write(part.document + ", " + part.reference + "," + part.material + "," + str(int(part.size[0]+0.5)) + "," + str(int(part.size[1]+0.5)) + "," + str(int(part.size[2]+0.5)) + "," + str(int(part.volume/100+0.5)/10.0) + "," + mass_str + ", " + str(part.count) + "\n")
|
||||||
|
print("Part list exported to " + file_name)
|
||||||
|
|
||||||
|
from ahb_command import AHB_CommandWrapper
|
||||||
|
AHB_CommandWrapper.addGuiCommand('AHB_export_parts_list', AHB_ExportPartsList())
|
22
ahb_material.py
Normal file
22
ahb_material.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
class Material:
|
||||||
|
def __init__(self, ID, density):
|
||||||
|
self.ID = ID
|
||||||
|
self.density = density
|
||||||
|
|
||||||
|
DB = []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def GetMaterialIDs():
|
||||||
|
result = []
|
||||||
|
for m in Material.DB:
|
||||||
|
result.append(m.ID)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def Get(ID):
|
||||||
|
for m in Material.DB:
|
||||||
|
if m.ID == ID: return m
|
||||||
|
return None
|
||||||
|
|
||||||
|
Material.DB.append(Material('Stainless steel', density = 8.00))
|
||||||
|
Material.DB.append(Material('Aluminium', density = 2.71))
|
@ -7,6 +7,8 @@ import TechDraw, TechDrawGui
|
|||||||
from PySide import QtGui, QtCore
|
from PySide import QtGui, QtCore
|
||||||
TDG = TechDrawGui
|
TDG = TechDrawGui
|
||||||
|
|
||||||
|
from ahb_material import Material
|
||||||
|
|
||||||
class CursorItem(QtGui.QGraphicsItem):
|
class CursorItem(QtGui.QGraphicsItem):
|
||||||
def __init__(self, parent = None, view = None):
|
def __init__(self, parent = None, view = None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -792,13 +794,32 @@ class TechDrawExtensions:
|
|||||||
|
|
||||||
def initializeDocument(self, doc):
|
def initializeDocument(self, doc):
|
||||||
def doInit():
|
def doInit():
|
||||||
|
main_part = None
|
||||||
try:
|
try:
|
||||||
for obj in doc.Objects:
|
for obj in doc.Objects:
|
||||||
if obj.TypeId == 'TechDraw::DrawPage':
|
if obj.TypeId == 'TechDraw::DrawPage':
|
||||||
self.onPageLoaded(obj)
|
self.onPageLoaded(obj)
|
||||||
|
|
||||||
|
main_part = doc.getObjectsByLabel(doc.Name)
|
||||||
|
if len(main_part) == 1:
|
||||||
|
main_part = main_part[0]
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if main_part is not None:
|
||||||
|
current_material = 'Unknown'
|
||||||
|
if 'Assembly_handbook_Material' in main_part.PropertiesList:
|
||||||
|
current_material = main_part.Assembly_handbook_Material
|
||||||
|
else:
|
||||||
|
main_part.addProperty("App::PropertyEnumeration", "Assembly_handbook_Material", "Assembly_handbook")
|
||||||
|
material_list = ['Unknown'] + Material.GetMaterialIDs()
|
||||||
|
main_part.Assembly_handbook_Material = material_list
|
||||||
|
main_part.Assembly_handbook_Material = material_list.index(current_material) if current_material in material_list else 0
|
||||||
|
|
||||||
|
if 'Assembly_handbook_Weight' not in main_part.PropertiesList:
|
||||||
|
main_part.addProperty("App::PropertyFloat", "Assembly_handbook_Weight", "Assembly_handbook", 'Part weight in grams. Set a negative number if weight is unknown.')
|
||||||
|
main_part.Assembly_handbook_Weight = -1
|
||||||
|
|
||||||
QTimer.singleShot(0, doInit)
|
QTimer.singleShot(0, doInit)
|
||||||
|
|
||||||
def onPageLoaded(self, page):
|
def onPageLoaded(self, page):
|
||||||
|
Loading…
Reference in New Issue
Block a user