Files
Web_FreeCAD_Bitbybit/scripts/freecad-fcstd-gui-probe.py

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)