Browse Source
Added possibility to set material and/or weight of each part Part weight is calculated from volume and density if the material is configuredmaster
Youen
2 years ago
4 changed files with 152 additions and 0 deletions
@ -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()) |
@ -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)) |
Loading…
Reference in new issue