FreeCAD: Workbench Refactor
This commit is contained in:
parent
037827669a
commit
a58dcdafb1
386 changed files with 997 additions and 64533 deletions
|
@ -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
|
|
@ -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
|
55
freecad_workbench/cad_generation/usecases/export_usecase.py
Normal file
55
freecad_workbench/cad_generation/usecases/export_usecase.py
Normal 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
|
|
@ -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}
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue