from helper.is_solid import is_object_solid import FreeCAD as App import Spreadsheet def createSpreadsheet(): if App.ActiveDocument.getObject("BoM_List") == None: sheet = App.activeDocument().addObject('Spreadsheet::Sheet', 'BoM_List') sheet.set('A1', 'п.п.') sheet.set('B1', 'Наименование детали') sheet.set('C1', 'Количество') else: sheet = App.ActiveDocument.getObject("BoM_List") App.ActiveDocument.BoM_List.clear('A1:ZZ16384') sheet.set('A1', 'п.п.') sheet.set('B1', 'Наименование детали') sheet.set('C1', 'Количество') return (sheet) class SolidBodiesParcer: _asmThere = [] def __init__(self) -> None: if (self._asmThere.__len__() == 0): self.initParse() pass def initParse(self): for el in App.ActiveDocument.RootObjects: if (is_object_solid(el) and hasattr(el, 'Group')): self.getSubPartsLink(el.Group, el.Label) def getSubPartsLink(self, group, label): groupLink = {label: []} for el in group: if (is_object_solid(el)): groupLink[label].append( {'label': el.Label, 'isGroup': hasattr(el, 'Group'), 'solid': el}) for el in groupLink[label]: if ('isGroup' in el): if (el['isGroup'] == False): self._asmThere.append(el['solid'].Label) if (el['isGroup']): self.getSubPartsLink(el['solid'].Group, el['label']), return groupLink def uniquePartsSort(labelParts): uniquePartsLabels = {} for el in labelParts: for k in labelParts: if (App.ActiveDocument.getObjectsByLabel(str(el))[0].Shape.isPartner(App.ActiveDocument.getObjectsByLabel(str(k))[0].Shape)): if uniquePartsLabels.get(el) == None: uniquePartsLabels[el] = k sortedParts = {} for k, v in uniquePartsLabels.items(): if sortedParts.get(v) == None: sortedParts[v] = [k] else: sortedParts[v].append(k) return sortedParts def countForUniques(sortedParts): countedParts = {} for k in sortedParts: countedParts[k] = len(sortedParts[k]) return countedParts def fillInBoMList(sheet, countedParts): a = 1 for label, count in countedParts.items(): a += 1 b = label c = count sheet.set('A' + str(a), str(a-1)) sheet.set('B' + str(a), str(b)) sheet.set('C' + str(a), str(c)) total_count = sum(countedParts.values()) sheet.set('B'+str(a+1), 'Итого') sheet.set('C' + str(a+1), str(total_count)) def run_BoM_list(): createSpreadsheet() sheet = App.ActiveDocument.getObject("BoM_List") labelParts = SolidBodiesParcer()._asmThere sortedParts = uniquePartsSort(labelParts) countedParts = countForUniques(sortedParts) fillInBoMList(sheet, countedParts)