FreeCAD: Workbench Refactor

This commit is contained in:
Mark Voltov 2024-04-14 18:54:47 +00:00 committed by Igor Brylyov
parent 037827669a
commit a58dcdafb1
386 changed files with 997 additions and 64533 deletions

View file

@ -0,0 +1,59 @@
import FreeCAD as App
def is_object_solid(obj):
"""If obj is solid return True"""
if not isinstance(obj, App.DocumentObject):
return False
if hasattr(obj, 'Group'):
return False
if not hasattr(obj, 'Shape'):
return False
# if not hasattr(obj.Shape, 'Mass'):
# return False
if not hasattr(obj.Shape, 'Solids'):
return False
if len(obj.Shape.Solids) == 0:
return False
return True
#парсит сборку, создавая список деталей и сборочных единиц
class AssemblyParseUseCase:
_parts = []
_asm = []
def getAsm(self):
return self._asm
def __init__(self) -> None:
if (self._asm.__len__() == 0):
self.initParse()
pass
def initParse(self):
for el in App.ActiveDocument.Objects:
if (is_object_solid(el)):
self._asm.append(el.Label)
def toJson(self):
return str(self._asm).replace('\'', "\"")
def getSubPartsLink(self, group):
groupLink = {}
for el in group:
if (is_object_solid(el)):
if str(el.Shape).find('Solid') != -1:
if groupLink.get(el.Label) == None:
groupLink[el.Label] = []
for i in el.Group:
if str(i).find('Pad') != -1:
groupLink[el.Label].append(i)
if groupLink.__len__() == 0:
return None
return groupLink
def getLinkedProperty(self):
return self._asm

View file

@ -0,0 +1,119 @@
from typing import List
import FreeCAD as App
import Part
from model.join_mesh_model import JoinMeshModel
from model.mesh_part_model import MeshPartModel
from helper.file_system_repository import FileSystemRepository
from helper.is_solid import is_object_solid
from model.simple_copy_part_model import SimpleCopyPartModel
from model.files_generator import FolderGenerator
from usecases.assembly_parse_usecase import AssemblyParseUseCase
import os
import json
#подготавливает необходимое для работы assemble them all состояние папок
class ExportAssemblyThemAllUseCase:
def call(self, path):
assembly = AssemblyParseUseCase().getAsm()
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)
os.makedirs(
path + FolderGenerator.ASSEMBlY.value + "/" + "0000" + str(k)
)
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
+ FolderGenerator.ASSEMBlY.value
+ "/"
+ "0000"
+ str(k)
+ "/"
+ str(1)
+ ".obj",
)
joinMesh.remove()
importOBJ.export(
v["child"],
path
+ FolderGenerator.ASSEMBlY.value
+ "/"
+ "0000"
+ str(k)
+ "/"
+ str(0)
+ ".obj",
)
FileSystemRepository.writeFile(
json.dumps(geometry),
path
+ FolderGenerator.ASSEMBlY.value
+ "/"
+ "0000"
+ str(k)
+ "/",
"translation.json",
)
App.ActiveDocument.removeObject("Compound")
for el in copyLinks:
el.remove()
App.activeDocument().recompute()
inc += 1

View file

@ -0,0 +1,55 @@
# import importDAE
import Mesh
import FreeCAD as App
from model.files_generator import FolderGenerator
from helper.is_solid import is_object_solid
from enum import Enum
class EXPORT_TYPES(Enum):
STL = "STL"
DAO = "DAO"
OBJ = "OBJ"
#делает Илья
class ExportUseCase:
def call(path: str, type: EXPORT_TYPES):
meshes = {}
for el in App.ActiveDocument.Objects:
if is_object_solid(el):
match type.value:
case EXPORT_TYPES.STL.value:
Mesh.export(
[el],
path
+ "/"
+ FolderGenerator.SDF.value
+ "/"
+ FolderGenerator.MESHES.value
+ "/"
+ el.Label
+ ".stl",
)
meshes[el.Label] = (
"/" + FolderGenerator.MESHES.value + "/" + el.Label + ".stl"
)
case EXPORT_TYPES.OBJ.value:
import importOBJ
importOBJ.export(
[el],
path
+ "/"
+ FolderGenerator.SDF.value
+ "/"
+ FolderGenerator.MESHES.value
+ "/"
+ el.Label
+ ".obj",
)
meshes[el.Label] = (
"/" + FolderGenerator.MESHES.value + "/" + el.Label + ".obj"
)
return meshes

View file

@ -0,0 +1,58 @@
import FreeCAD as App
from helper.is_solid import is_object_solid
class GeometryUseCase:
def call() -> dict:
labels = []
Error = False
for el in App.ActiveDocument.Objects:
try:
if is_object_solid(el):
labels.append(el.Label)
geometry = {
"euler": {
"x": None,
"y": None,
"z": None
},
"position": {
"x": None,
"y": None,
"z": None
},
"rotation": {
"x": None,
"y": None,
"z": None
},
"center": {
"x": None,
"y": None,
"z": None
},
}
boundBox = el.Shape.BoundBox
geometry["center"]["x"] = boundBox.Center.x
geometry["center"]["y"] = boundBox.Center.y
geometry["center"]["z"] = boundBox.Center.z
geometry["position"]['x'] = boundBox.XMax
geometry["position"]['y'] = boundBox.YMax
geometry["position"]['z'] = boundBox.ZMax
rotation = el.Placement.Rotation
geometry["rotation"]['x'] = rotation.Axis.z
geometry["rotation"]['y'] = rotation.Axis.y
geometry["rotation"]['z'] = rotation.Axis.z
euler = el.Placement.Rotation.toEuler()
geometry["euler"]['x'] = euler[0]
geometry["euler"]['y'] = euler[1]
geometry["euler"]['z'] = euler[2]
except Exception as e:
print(e)
# App.Console.PrintMessage("Clicked on position: ("+str(pos[0])+", "+str(pos[1])+")\n")
return {"geometry": geometry, "labels": labels, "label": el.Label}

View file

@ -0,0 +1,70 @@
import FreeCAD as App
from model.sdf_geometry_model import SdfGeometryModel
from helper.is_solid import is_object_solid
class SdfGeometryUseCase:
ShapePropertyCheck = ['Mass', 'MatrixOfInertia', 'Placement', ]
PartPropertyCheck = ['Shape']
def call(self, stlPaths: dict) -> list[SdfGeometryModel]:
materialSolid = {}
for el in App.ActiveDocument.Objects:
if str(el) == '<App::MaterialObjectPython object>':
friction = el.Material.get('SlidingFriction')
for i in el.References:
materialSolid[i[0].Label] = friction
geometry = []
try:
for el in App.ActiveDocument.Objects:
if is_object_solid(el):
mass = el.Shape.Mass
inertia = el.Shape.MatrixOfInertia
pos = el.Shape.Placement
inertia = el.Shape.MatrixOfInertia
name = el.Label
delimiter = 1000000
ixx = str(inertia.A11 / delimiter)
ixy = str(inertia.A12 / delimiter)
ixz = str(inertia.A13 / delimiter)
iyy = str(inertia.A22 / delimiter)
iyz = str(inertia.A23 / delimiter)
izz = str(inertia.A33 / delimiter)
massSDF = str(mass / delimiter)
posX = str(pos.Base[0] / delimiter)
posY = str(pos.Base[1] / delimiter)
posZ = str(pos.Base[2] / delimiter)
eulerX = str(pos.Rotation.toEuler()[0])
eulerY = str(pos.Rotation.toEuler()[1])
eulerZ = str(pos.Rotation.toEuler()[2])
centerMassX = str(el.Shape.CenterOfMass[0])
centerMassY = str(el.Shape.CenterOfMass[1])
centerMassZ = str(el.Shape.CenterOfMass[2])
geometry.append(
SdfGeometryModel(
stl=stlPaths.get(el.Label),
name=name,
ixx=ixx,
ixz=ixz,
ixy=ixy,
iyy=iyy,
iyz=iyz,
izz=izz,
massSDF=massSDF,
posX=posX,
posY=posY,
posZ=posZ,
eulerX=eulerX,
eulerY=eulerY,
eulerZ=eulerZ,
friction=materialSolid.get(el.Label) or '',
centerMassX=centerMassX,
centerMassY=centerMassY,
centerMassZ=centerMassZ
)
)
except Exception as e:
print(e)
return geometry