205 lines
6.5 KiB
Python
205 lines
6.5 KiB
Python
![]() |
|
||
|
|
||
|
from typing import List
|
||
|
import FreeCAD as App
|
||
|
import Part
|
||
|
import Mesh
|
||
|
import Part
|
||
|
import MeshPart
|
||
|
import os
|
||
|
import json
|
||
|
import FreeCADGui as Gui
|
||
|
|
||
|
class FS:
|
||
|
def readJSON(path: str):
|
||
|
return json.loads((open(path)).read())
|
||
|
|
||
|
def writeFile(data, filePath, fileName):
|
||
|
file_to_open = filePath + fileName
|
||
|
|
||
|
f = open(file_to_open, 'w', encoding='utf-8',
|
||
|
errors='ignore')
|
||
|
f.write(data)
|
||
|
f.close()
|
||
|
def createFolder(path: str):
|
||
|
if (not os.path.exists(path)):
|
||
|
return os.mkdir(path)
|
||
|
|
||
|
|
||
|
|
||
|
class SimpleCopyPartModel:
|
||
|
id = None
|
||
|
copyLink = None
|
||
|
label = None
|
||
|
part = None
|
||
|
|
||
|
def getPart(self):
|
||
|
return self.part
|
||
|
|
||
|
def __init__(self, part) -> None:
|
||
|
try:
|
||
|
from random import randrange
|
||
|
self.id = str(randrange(1000000))
|
||
|
childObj = part
|
||
|
print(part)
|
||
|
__shape = Part.getShape(
|
||
|
childObj, '', needSubElement=False, refine=False)
|
||
|
obj = App.ActiveDocument.addObject('Part::Feature', self.id)
|
||
|
obj.Shape = __shape
|
||
|
self.part = obj
|
||
|
self.label = obj.Label
|
||
|
App.ActiveDocument.recompute()
|
||
|
except Exception as e:
|
||
|
print(e)
|
||
|
|
||
|
def remove(self):
|
||
|
App.ActiveDocument.removeObject(self.label)
|
||
|
|
||
|
class MeshPartModel:
|
||
|
id = None
|
||
|
mesh = None
|
||
|
|
||
|
def __init__(self, part) -> None:
|
||
|
try:
|
||
|
from random import randrange
|
||
|
self.id = 'mesh' + str(randrange(1000000))
|
||
|
document = App.ActiveDocument
|
||
|
mesh = document.addObject("Mesh::Feature", self.id)
|
||
|
shape = Part.getShape(part, "")
|
||
|
mesh.Mesh = MeshPart.meshFromShape(
|
||
|
Shape=shape, LinearDeflection=20, AngularDeflection=0.1, Relative=False)
|
||
|
mesh.Label = self.id
|
||
|
self.mesh = mesh
|
||
|
except Exception as e:
|
||
|
print(e)
|
||
|
pass
|
||
|
|
||
|
def remove(self):
|
||
|
try:
|
||
|
App.ActiveDocument.removeObject(self.mesh.Label)
|
||
|
except Exception as e:
|
||
|
print(e)
|
||
|
|
||
|
|
||
|
|
||
|
class JoinMeshModel:
|
||
|
id = None
|
||
|
mesh = None
|
||
|
|
||
|
def __init__(self, meshesPartModels: list['MeshPartModel']) -> None:
|
||
|
meshes = []
|
||
|
from random import randrange
|
||
|
for el in meshesPartModels:
|
||
|
meshes.append(el.mesh.Mesh)
|
||
|
|
||
|
self.id = 'MergedMesh' + str(randrange(1000000))
|
||
|
doc = App.ActiveDocument
|
||
|
merged_mesh = Mesh.Mesh()
|
||
|
for el in meshes:
|
||
|
merged_mesh.addMesh(el)
|
||
|
|
||
|
new_obj = doc.addObject("Mesh::Feature", self.id)
|
||
|
new_obj.Mesh = merged_mesh
|
||
|
new_obj.ViewObject.DisplayMode = "Flat Lines"
|
||
|
self.mesh = new_obj
|
||
|
|
||
|
def remove(self):
|
||
|
try:
|
||
|
App.ActiveDocument.removeObject(self.id)
|
||
|
except Exception as e:
|
||
|
print(e)
|
||
|
|
||
|
|
||
|
class ExportAssemblyThemAllUseCase:
|
||
|
|
||
|
def call(self, path:str, assemblys:list[str]):
|
||
|
assembly = assemblys
|
||
|
asmStructure = {}
|
||
|
inc = 0
|
||
|
for el in assembly:
|
||
|
if (inc != 0):
|
||
|
asmStructure[inc] = {
|
||
|
"child": el,
|
||
|
"parents": assembly[0:inc]
|
||
|
}
|
||
|
inc += 1
|
||
|
objectsFreeCad = App.ActiveDocument.Objects
|
||
|
asmSolids = {}
|
||
|
for k, v in asmStructure.items():
|
||
|
assemblyParentList = v['parents']
|
||
|
assemblyChild = v['child']
|
||
|
for el in assemblyParentList:
|
||
|
for solid in objectsFreeCad:
|
||
|
if (el == solid.Label):
|
||
|
if (asmSolids.get(k) is None):
|
||
|
|
||
|
asmSolids[k] = {'parents': [], 'child': list(
|
||
|
filter(lambda x: x.Label == assemblyChild, objectsFreeCad))[0]}
|
||
|
|
||
|
asmSolids[k]['parents'].append(solid)
|
||
|
|
||
|
inc = 0
|
||
|
for k, v in asmSolids.items():
|
||
|
geometry = {"0": [], "1": []}
|
||
|
if (k != 0):
|
||
|
App.activeDocument().addObject("Part::Compound", "Compound")
|
||
|
|
||
|
copyLinks = list(
|
||
|
map(lambda el: SimpleCopyPartModel(el), v['parents']))
|
||
|
|
||
|
if copyLinks != None:
|
||
|
App.activeDocument().Compound.Links = list(
|
||
|
map(lambda el: el.getPart(), copyLinks))
|
||
|
|
||
|
object = App.activeDocument().getObject('Compound')
|
||
|
boundBox = object.Shape.BoundBox
|
||
|
geometry['0'].append(boundBox.XMax)
|
||
|
geometry['0'].append(boundBox.YMax)
|
||
|
geometry['0'].append(boundBox.ZMax)
|
||
|
|
||
|
boundBoxChild = v['child'].Shape.BoundBox
|
||
|
geometry['1'].append(boundBoxChild.XMax)
|
||
|
geometry['1'].append(boundBoxChild.YMax)
|
||
|
geometry['1'].append(boundBoxChild.ZMax)
|
||
|
meshParents = []
|
||
|
|
||
|
for el in v['parents']:
|
||
|
meshParents.append(MeshPartModel(el))
|
||
|
joinMesh = JoinMeshModel(meshParents)
|
||
|
for el in meshParents:
|
||
|
el.remove()
|
||
|
import importOBJ
|
||
|
importOBJ.export(joinMesh.mesh, path + str(1) + '.obj')
|
||
|
joinMesh.remove()
|
||
|
importOBJ.export(v['child'], path + str(0) + '.obj')
|
||
|
FS.writeFile(json.dumps(geometry), path, 'translation.json')
|
||
|
|
||
|
App.ActiveDocument.removeObject("Compound")
|
||
|
for el in copyLinks:
|
||
|
el.remove()
|
||
|
App.activeDocument().recompute()
|
||
|
inc += 1
|
||
|
|
||
|
def main():
|
||
|
|
||
|
env = FS.readJSON('./env.json')
|
||
|
env.get('cadDoc')
|
||
|
aspDir = env.get('aspDir')
|
||
|
sequences = FS.readJSON(env.get('sequences')).get('sequences')
|
||
|
App.openDocument(env.get('cadDoc'))
|
||
|
for sequencyNumber in range(len(sequences)):
|
||
|
FS.createFolder(aspDir + 'assemblys/')
|
||
|
mainFolder = aspDir + 'assemblys/' + str(sequencyNumber) + '/'
|
||
|
FS.createFolder(mainFolder)
|
||
|
for subSequenceNumber in range(len(sequences[sequencyNumber])):
|
||
|
if(subSequenceNumber != 0):
|
||
|
subFolder = aspDir + 'assemblys/' + \
|
||
|
str(sequencyNumber) + '/' + str(subSequenceNumber) + '/'
|
||
|
|
||
|
FS.createFolder(subFolder)
|
||
|
ExportAssemblyThemAllUseCase().call(path=subFolder,assemblys=sequences[sequencyNumber][0:subSequenceNumber+1])
|
||
|
|
||
|
App.closeDocument(App.ActiveDocument.Name)
|
||
|
freecadQTWindow = Gui.getMainWindow()
|
||
|
freecadQTWindow.close()
|
||
|
main()
|