import json import os import FreeCAD as App FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d" def shape_snapshot(obj): shape = obj.Shape bounds = shape.BoundBox return { "name": obj.Name, "typeId": obj.TypeId, "valid": bool(shape.isValid()), "shapeType": shape.ShapeType, "solids": len(shape.Solids), "faces": len(shape.Faces), "edges": len(shape.Edges), "vertices": len(shape.Vertexes), "volume": round(float(shape.Volume), 9), "area": round(float(shape.Area), 9), "bounds": [ round(float(value), 9) for value in (bounds.XMin, bounds.YMin, bounds.ZMin, bounds.XMax, bounds.YMax, bounds.ZMax) ], } def measure_snapshot(document): measure = document.getObject("AreaProbe") box = document.getObject("AreaBox") return { "objectSet": [{"name": obj.Name, "typeId": obj.TypeId} for obj in document.Objects], "source": { **shape_snapshot(box), "length": round(float(box.Length.Value), 9), "width": round(float(box.Width.Value), 9), "height": round(float(box.Height.Value), 9), }, "measure": { "name": measure.Name, "typeId": measure.TypeId, "areaTypeId": measure.getTypeIdOfProperty("Area"), "elementsTypeId": measure.getTypeIdOfProperty("Elements"), "area": {"raw": str(measure.Area), "numeric": round(float(measure.Area.Value), 9), "unit": str(measure.Area.Unit)}, "elements": [ {"object": obj.Name, "typeId": obj.TypeId, "subElements": list(sub_elements)} for obj, sub_elements in measure.Elements ], "propertyStatus": [str(item) for item in measure.getPropertyStatus("Area")], "editorMode": [str(item) for item in measure.getEditorMode("Area")], "state": [str(item) for item in measure.State], "statusString": str(measure.getStatusString()), "shape": {"applicable": hasattr(measure, "Shape")}, }, } def create_native(path): document = App.newDocument("PropertyAreaRoundtrip") try: box = document.addObject("Part::Box", "AreaBox") box.Length = 10 box.Width = 5 box.Height = 2 measure = document.addObject("Measure::MeasureArea", "AreaProbe") measure.Elements = [(box, ["Face1"])] document.recompute() document.saveAs(path) finally: App.closeDocument(document.Name) reopened = App.openDocument(path) try: reopened.recompute() return measure_snapshot(reopened) finally: App.closeDocument(reopened.Name) def verify_native(path, resaved_path): document = App.openDocument(path) try: document.recompute() reopened = measure_snapshot(document) document.saveAs(resaved_path) finally: App.closeDocument(document.Name) resaved_document = App.openDocument(resaved_path) try: resaved_document.recompute() resaved = measure_snapshot(resaved_document) finally: App.closeDocument(resaved_document.Name) return {"reopened": reopened, "resaved": resaved} mode = os.environ.get("FREECAD_PROPERTY_AREA_ROUNDTRIP_MODE", "") path = os.environ.get("FREECAD_PROPERTY_AREA_ROUNDTRIP_PATH", "") resaved_path = os.environ.get("FREECAD_PROPERTY_AREA_ROUNDTRIP_RESAVED_PATH", "") if mode == "create": result = create_native(path) elif mode == "verify": result = verify_native(path, resaved_path) else: raise RuntimeError("FREECAD_PROPERTY_AREA_ROUNDTRIP_MODE must be create or verify") print("FREECAD_PROPERTY_AREA_ROUNDTRIP_RESULT=" + json.dumps({ "schemaVersion": 1, "status": "pass", "baselineId": "freecad-1.1.1-property-area-roundtrip", "freecadVersion": ".".join(str(value) for value in App.Version()[:3]), "gitCommit": FREECAD_COMMIT, "mode": mode, "result": result, }, sort_keys=True))