import hashlib import json import xml.etree.ElementTree as ET import FreeCAD as App import Robot FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d" def quantity_snapshot(value): return { "raw": str(value), "numeric": round(float(value.Value), 9), "unit": str(value.Unit), } def trajectory_snapshot(obj): content = obj.Trajectory.Content root = ET.fromstring(content) waypoints = [] for waypoint in root.findall("Waypoint"): waypoints.append({ "name": waypoint.attrib["name"], "type": waypoint.attrib["type"], "position": [round(float(waypoint.attrib[key]), 9) for key in ("Px", "Py", "Pz")], "velocity": round(float(waypoint.attrib["vel"]), 9), "acceleration": round(float(waypoint.attrib["acc"]), 9), "continuous": waypoint.attrib["cont"] == "1", "tool": int(waypoint.attrib["tool"]), "base": int(waypoint.attrib["base"]), }) return { "contentSha256": hashlib.sha256(content.encode("utf-8")).hexdigest(), "waypointCount": len(waypoints), "length": round(float(obj.Trajectory.Length), 9), "duration": round(float(obj.Trajectory.Duration), 9), "waypoints": waypoints, } def semantic_snapshot(obj): return { "value": quantity_snapshot(obj.Acceleration), "propertyStatus": [str(item) for item in obj.getPropertyStatus("Acceleration")], "editorMode": [str(item) for item in obj.getEditorMode("Acceleration")], "source": {"name": obj.Source.Name, "typeId": obj.Source.TypeId}, "useAcceleration": bool(obj.UseAcceleration), "trajectory": trajectory_snapshot(obj), "shape": {"applicable": hasattr(obj, "Shape")}, "objectState": [str(item) for item in obj.State], "statusString": str(obj.getStatusString()), "mustExecute": bool(obj.MustExecute), } def object_snapshot(document): return [{"name": obj.Name, "typeId": obj.TypeId} for obj in document.Objects] def run(): document = App.newDocument("PropertyAccelerationMutation") try: source = document.addObject("Robot::TrajectoryObject", "SourceTrajectory") trajectory = source.Trajectory trajectory = trajectory.insertWaypoints(App.Placement(App.Vector(1.0, 2.0, 3.0), App.Rotation())) trajectory = trajectory.insertWaypoints(App.Placement(App.Vector(4.0, 6.0, 3.0), App.Rotation())) source.Trajectory = trajectory obj = document.addObject("Robot::TrajectoryDressUpObject", "AccelerationProbe") obj.Source = source obj.UseAcceleration = True initial_recompute = int(document.recompute()) before = semantic_snapshot(obj) source_before = trajectory_snapshot(source) objects_before = object_snapshot(document) obj.Acceleration = "500 mm/s^2" touched_after_edit = { "value": quantity_snapshot(obj.Acceleration), "objectState": [str(item) for item in obj.State], "mustExecute": bool(obj.MustExecute), } edit_recompute = int(document.recompute()) edited = semantic_snapshot(obj) source_edited = trajectory_snapshot(source) obj.Acceleration = "1000 mm/s^2" restore_recompute = int(document.recompute()) restored = semantic_snapshot(obj) source_restored = trajectory_snapshot(source) objects_restored = object_snapshot(document) return { "schemaVersion": 1, "status": "pass", "baselineId": "freecad-1.1.1-property-acceleration-mutation", "freecadVersion": ".".join(str(value) for value in App.Version()[:3]), "gitCommit": FREECAD_COMMIT, "object": {"name": obj.Name, "typeId": obj.TypeId}, "property": {"name": "Acceleration", "typeId": obj.getTypeIdOfProperty("Acceleration")}, "recompute": { "initial": initial_recompute, "edit": edit_recompute, "restore": restore_recompute, }, "touchedAfterEdit": touched_after_edit, "before": before, "edited": edited, "restored": restored, "source": { "before": source_before, "edited": source_edited, "restored": source_restored, "preserved": source_before == source_edited == source_restored, }, "document": { "objectsBefore": objects_before, "objectsRestored": objects_restored, "objectsPreserved": objects_before == objects_restored, }, "classification": { "propertyChanged": before["value"] != edited["value"], "trajectoryChanged": before["trajectory"] != edited["trajectory"], "propertyRestored": before["value"] == restored["value"], "trajectoryRestored": before["trajectory"] == restored["trajectory"], "semanticStateRestored": before == restored, "geometry": "not-applicable-no-shape-property", }, } finally: App.closeDocument(document.Name) print("FREECAD_PROPERTY_ACCELERATION_MUTATION_RESULT=" + json.dumps(run(), sort_keys=True))