204 lines
8.0 KiB
Python
204 lines
8.0 KiB
Python
import json
|
|
import os
|
|
import sys
|
|
|
|
import FreeCAD as App
|
|
import FreeCADGui as Gui
|
|
import Part
|
|
import Sketcher
|
|
|
|
|
|
path = os.environ.get("FREECAD_FCSTD_PATH", "")
|
|
object_name = os.environ.get("FREECAD_FCSTD_OBJECT", "Box")
|
|
if not path:
|
|
raise RuntimeError("FREECAD_FCSTD_PATH must point to an FCStd file.")
|
|
|
|
if os.environ.get("FREECAD_FCSTD_CREATE") == "1":
|
|
generated = App.newDocument("GuiOracleGenerator")
|
|
generated_object = generated.addObject(os.environ.get("FREECAD_FCSTD_CREATE_TYPEID", "Part::Feature"), object_name)
|
|
for property_name, property_value in json.loads(os.environ.get("FREECAD_FCSTD_CREATE_PROPERTIES", "{}")).items():
|
|
setattr(generated_object, property_name, property_value)
|
|
generated_brep_path = os.environ.get("FREECAD_BREP_PATH", "")
|
|
if generated_brep_path:
|
|
generated_shape = Part.Shape()
|
|
generated_shape.read(generated_brep_path)
|
|
generated_object.Shape = generated_shape
|
|
generated_view = Gui.getDocument(generated.Name).getObject(object_name)
|
|
generated_view.Visibility = False
|
|
generated_view.Transparency = 35
|
|
generated_view.LineColor = (0x11 / 255.0, 0x22 / 255.0, 0x33 / 255.0)
|
|
generated_view.PointColor = (0x44 / 255.0, 0x55 / 255.0, 0x66 / 255.0)
|
|
generated_view.Deviation = 0.2
|
|
generated.recompute()
|
|
generated.saveAs(path)
|
|
App.closeDocument(generated.Name)
|
|
|
|
if not os.path.isfile(path):
|
|
raise RuntimeError("FREECAD_FCSTD_PATH does not exist.")
|
|
|
|
document = App.openDocument(path)
|
|
obj = document.getObject(object_name)
|
|
if obj is None:
|
|
raise RuntimeError(f"FCStd object does not exist: {object_name}")
|
|
if os.environ.get("FREECAD_FCSTD_RECOMPUTE") == "1":
|
|
document.recompute()
|
|
view = Gui.getDocument(document.Name).getObject(object_name)
|
|
if view is None:
|
|
raise RuntimeError(f"FCStd ViewObject does not exist: {object_name}")
|
|
|
|
resave_path = os.environ.get("FREECAD_FCSTD_RESAVE_PATH", "")
|
|
if resave_path:
|
|
document.saveAs(resave_path)
|
|
|
|
shape_result = {
|
|
"shapeNull": None,
|
|
"shapeValid": None,
|
|
"solidCount": None,
|
|
"faceCount": None,
|
|
"volume": None,
|
|
"boundingBox": None,
|
|
"shapeError": None,
|
|
}
|
|
if hasattr(obj, "Shape"):
|
|
try:
|
|
shape_result.update({
|
|
"shapeNull": bool(obj.Shape.isNull()),
|
|
"shapeValid": bool(obj.Shape.isValid()) if not obj.Shape.isNull() else None,
|
|
"solidCount": len(obj.Shape.Solids),
|
|
"faceCount": len(obj.Shape.Faces),
|
|
"volume": float(obj.Shape.Volume),
|
|
"boundingBox": {
|
|
"min": [float(obj.Shape.BoundBox.XMin), float(obj.Shape.BoundBox.YMin), float(obj.Shape.BoundBox.ZMin)],
|
|
"max": [float(obj.Shape.BoundBox.XMax), float(obj.Shape.BoundBox.YMax), float(obj.Shape.BoundBox.ZMax)],
|
|
},
|
|
})
|
|
except Exception as error:
|
|
shape_result["shapeError"] = str(error)
|
|
|
|
direct_brep_result = None
|
|
direct_brep_path = os.environ.get("FREECAD_BREP_PATH", "")
|
|
if direct_brep_path:
|
|
direct_brep_result = {"valid": None, "solidCount": None, "faceCount": None, "volume": None, "error": None}
|
|
try:
|
|
direct_shape = Part.Shape()
|
|
direct_shape.read(direct_brep_path)
|
|
direct_brep_result.update({
|
|
"valid": bool(direct_shape.isValid()),
|
|
"solidCount": len(direct_shape.Solids),
|
|
"faceCount": len(direct_shape.Faces),
|
|
"volume": float(direct_shape.Volume),
|
|
})
|
|
except Exception as error:
|
|
direct_brep_result["error"] = str(error)
|
|
|
|
property_result = {}
|
|
for property_name in filter(None, os.environ.get("FREECAD_FCSTD_PROPERTIES", "").split(",")):
|
|
try:
|
|
property_value = getattr(obj, property_name)
|
|
if hasattr(property_value, "Value"):
|
|
property_result[property_name] = float(property_value.Value)
|
|
elif hasattr(property_value, "Name"):
|
|
property_result[property_name] = property_value.Name
|
|
else:
|
|
property_result[property_name] = property_value
|
|
except Exception as error:
|
|
property_result[property_name] = {"error": str(error)}
|
|
|
|
sketch_result = {
|
|
"geometryCount": None,
|
|
"constraintCount": None,
|
|
"constructionGeometry": None,
|
|
"constraintNames": None,
|
|
"constraintTypes": None,
|
|
"externalGeometryCount": None,
|
|
"externalGeoCount": None,
|
|
"externalTypes": None,
|
|
"externalLinks": None,
|
|
"externalStates": None,
|
|
"mapMode": None,
|
|
"attachmentSupport": None,
|
|
"attachmentOffset": None,
|
|
}
|
|
if hasattr(obj, "GeometryCount") and hasattr(obj, "ConstraintCount"):
|
|
try:
|
|
sketch_result.update({
|
|
"geometryCount": int(obj.GeometryCount),
|
|
"constraintCount": int(obj.ConstraintCount),
|
|
"constructionGeometry": [index for index in range(int(obj.GeometryCount)) if obj.getConstruction(index)],
|
|
"constraintNames": [str(constraint.Name) for constraint in obj.Constraints],
|
|
"constraintTypes": [str(constraint.Type) for constraint in obj.Constraints],
|
|
})
|
|
except Exception as error:
|
|
sketch_result["error"] = str(error)
|
|
if hasattr(obj, "ExternalGeometry") and hasattr(obj, "ExternalGeo"):
|
|
try:
|
|
external_links = []
|
|
for linked_object, sub_elements in obj.ExternalGeometry:
|
|
external_links.append({
|
|
"objectName": str(linked_object.Name),
|
|
"subElements": [str(sub_element) for sub_element in sub_elements],
|
|
})
|
|
sketch_result.update({
|
|
"externalGeometryCount": len(obj.ExternalGeometry),
|
|
"externalGeoCount": len(obj.ExternalGeo),
|
|
"externalTypes": [int(value) for value in obj.ExternalTypes],
|
|
"externalLinks": external_links,
|
|
"externalStates": [
|
|
{
|
|
"ref": str(facade.Ref),
|
|
"id": int(facade.Id),
|
|
"geometryType": type(geometry).__name__,
|
|
"flags": sum(
|
|
(1 << index) if facade.testFlag(flag) else 0
|
|
for index, flag in enumerate(("Defining", "Frozen", "Detached", "Missing", "Sync"))
|
|
),
|
|
}
|
|
for geometry in obj.ExternalGeo
|
|
for facade in (Sketcher.ExternalGeometryFacade(geometry),)
|
|
if facade.Ref
|
|
],
|
|
})
|
|
except Exception as error:
|
|
sketch_result["externalError"] = str(error)
|
|
if hasattr(obj, "MapMode") and hasattr(obj, "AttachmentSupport") and hasattr(obj, "AttachmentOffset"):
|
|
try:
|
|
attachment_links = []
|
|
for linked_object, sub_elements in obj.AttachmentSupport:
|
|
attachment_links.append({
|
|
"objectName": str(linked_object.Name),
|
|
"subElements": [str(sub_element) for sub_element in sub_elements],
|
|
})
|
|
offset = obj.AttachmentOffset
|
|
sketch_result.update({
|
|
"mapMode": str(obj.MapMode),
|
|
"attachmentSupport": attachment_links,
|
|
"attachmentOffset": {
|
|
"position": [float(offset.Base.x), float(offset.Base.y), float(offset.Base.z)],
|
|
"axis": [float(offset.Rotation.Axis.x), float(offset.Rotation.Axis.y), float(offset.Rotation.Axis.z)],
|
|
"angle": float(offset.Rotation.Angle),
|
|
},
|
|
})
|
|
except Exception as error:
|
|
sketch_result["attachmentError"] = str(error)
|
|
|
|
result = {
|
|
"schemaVersion": 1,
|
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
|
"guiUp": bool(getattr(App, "GuiUp", False)),
|
|
"objectName": object_name,
|
|
"visibility": bool(view.Visibility),
|
|
"transparency": int(view.Transparency),
|
|
"lineColor": [float(value) for value in view.LineColor],
|
|
"pointColor": [float(value) for value in view.PointColor],
|
|
"shapeColor": [float(value) for value in view.ShapeColor],
|
|
"deviation": float(view.Deviation),
|
|
"directBrep": direct_brep_result,
|
|
"properties": property_result,
|
|
**sketch_result,
|
|
**shape_result,
|
|
}
|
|
App.closeDocument(document.Name)
|
|
print("FREECAD_FCSTD_GUI_RESULT=" + json.dumps(result, sort_keys=True, separators=(",", ":")))
|
|
sys.stdout.flush()
|
|
sys.exit(0)
|