framework/geometric_feasibility_predicate/repository/freecad_repository.py

171 lines
5.4 KiB
Python

import FreeCAD as App
from typing import List
from extensions.list import CoreList
from models.vector_model import VectorModel
class FreeCadRepository:
"""Class for handling FreeCAD related functionality"""
_solids = []
def openDocument(self, path: str):
App.open("" + path)
def closeIfOpenDocument(self):
"""
If there is an open document being processed in FreeCAD, it may be closed
"""
try:
if App.ActiveDocument is not None:
App.ActiveDocument.clearDocument()
except Exception as e:
print(e)
def getAllLabelsSolids(self) -> List[str]:
"""Returns a list of solid part labels
Returns:
List[str]: part labels
"""
return list(map(lambda el: el.Label, self.getAllSolids()))
def isAllObjectsSolids(self) -> List[str]:
"""Get all non-solid objects
Returns:
List[str]:
"""
result = []
for part in App.ActiveDocument.Objects:
if self.is_object_solid(part) is False:
result.append(part.Label)
return result
def objectSetPosition(self, solid, cadVector):
solid.Placement.Base = cadVector
pass
def objectGetPosition(self, solid) -> VectorModel:
return VectorModel(cadVector=solid.Placement.Base)
def isObjectIntersections(self, part) -> str:
result = []
for solid in self.getAllSolids():
if solid.ID != part.ID:
collisionResult: int = int(part.Shape.distToShape(solid.Shape)[0])
if collisionResult == 0:
result.append(solid.Label)
if result.__len__() == 0:
return None
return result
def objectHasTouches(self, part, solidBodyPadding: float) -> List[str]:
try:
positionVector = self.objectGetPosition(part)
result = CoreList()
result.append(self.isObjectIntersections(part=part))
if solidBodyPadding != 0 and solidBodyPadding != None:
result.append(
self.axis_movement_and_intersections_observer(
positionVector=positionVector,
alongAxis="x",
solidBodyPadding=solidBodyPadding,
part=part,
)
)
result.append(
self.axis_movement_and_intersections_observer(
positionVector=positionVector,
alongAxis="y",
solidBodyPadding=solidBodyPadding,
part=part,
)
)
result.append(
self.axis_movement_and_intersections_observer(
positionVector=positionVector,
alongAxis="z",
solidBodyPadding=solidBodyPadding,
part=part,
)
)
spreadArr = result.spreadArray()
if spreadArr.isConstrainsString():
return spreadArr.getAllString()
return None
except Exception as error:
print(error)
return None
def axis_movement_and_intersections_observer(
self,
positionVector: VectorModel,
alongAxis: str,
solidBodyPadding: float,
part,
) -> bool:
result = CoreList()
# UP
positionVector.__setattr__(
alongAxis,
positionVector.__getattribute__(alongAxis) + solidBodyPadding,
)
self.objectSetPosition(part, positionVector.toFreeCadVector())
# result.onlyUniqueElementAppend(self.isObjectIntersections(part=part))
result.extend(self.isObjectIntersections(part=part))
# RESET UP CHANGES
positionVector.__setattr__(
alongAxis,
positionVector.__getattribute__(alongAxis) - solidBodyPadding,
)
self.objectSetPosition(part, positionVector.toFreeCadVector())
# DOWN
positionVector.__setattr__(
alongAxis,
positionVector.__getattribute__(alongAxis) - solidBodyPadding,
)
self.objectSetPosition(part, positionVector.toFreeCadVector())
# CHECK DOWN INTERSECTIONS
# result.onlyUniqueElementAppend(self.isObjectIntersections(part=part))
result.extend(self.isObjectIntersections(part=part))
# RESET DOWN CHANGES
positionVector.__setattr__(
alongAxis,
positionVector.__getattribute__(alongAxis) + solidBodyPadding,
)
self.objectSetPosition(part, positionVector.toFreeCadVector())
if result.__len__() == 0:
return None
return result.onlyUnique()
def getAllSolids(self):
_solids = []
for part in App.ActiveDocument.Objects:
if self.is_object_solid(part):
_solids.append(part)
return _solids
def is_object_solid(self, obj):
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, "Solids"):
return False
if len(obj.Shape.Solids) == 0:
return False
return True