feat: establish reproducible FreeCAD web compatibility baseline
This commit is contained in:
125
scripts/freecad-partdesign-profile-oracle.py
Normal file
125
scripts/freecad-partdesign-profile-oracle.py
Normal file
@@ -0,0 +1,125 @@
|
||||
import json
|
||||
|
||||
import FreeCAD as App
|
||||
import Part
|
||||
import Sketcher
|
||||
|
||||
|
||||
LENGTH = 10.0
|
||||
TOLERANCE = 1e-7
|
||||
|
||||
|
||||
def line(start, end):
|
||||
return Part.LineSegment(App.Vector(start[0], start[1], 0), App.Vector(end[0], end[1], 0))
|
||||
|
||||
|
||||
def add_loop(sketch, points, closed=True):
|
||||
segment_count = len(points) if closed else len(points) - 1
|
||||
sketch.addGeometry([line(points[index], points[(index + 1) % len(points)]) for index in range(segment_count)], False)
|
||||
|
||||
|
||||
def object_status(feature):
|
||||
try:
|
||||
status_string = feature.getStatusString()
|
||||
except Exception:
|
||||
status_string = ""
|
||||
return {
|
||||
"state": [str(value) for value in feature.State],
|
||||
"statusString": str(status_string),
|
||||
}
|
||||
|
||||
|
||||
def run_case(case_id, expected, setup):
|
||||
document = App.newDocument("ProfileOracle_" + case_id.replace("-", "_"))
|
||||
try:
|
||||
body = document.addObject("PartDesign::Body", "Body")
|
||||
sketch = document.addObject("Sketcher::SketchObject", "Sketch")
|
||||
body.addObject(sketch)
|
||||
sketch.MapMode = "Deactivated"
|
||||
setup(sketch)
|
||||
document.recompute()
|
||||
|
||||
pad = document.addObject("PartDesign::Pad", "Pad")
|
||||
pad.Profile = sketch
|
||||
pad.Length = LENGTH
|
||||
body.addObject(pad)
|
||||
recompute_result = document.recompute()
|
||||
shape_null = bool(pad.Shape.isNull())
|
||||
volume = 0.0 if shape_null else float(pad.Shape.Volume)
|
||||
solids = 0 if shape_null else len(pad.Shape.Solids)
|
||||
accepted = not shape_null and volume > TOLERANCE and solids >= 1
|
||||
observed = "accepted" if accepted else "rejected"
|
||||
return {
|
||||
"id": case_id,
|
||||
"expected": expected,
|
||||
"observed": observed,
|
||||
"passed": observed == expected,
|
||||
"recomputeResult": bool(recompute_result),
|
||||
"shapeNull": shape_null,
|
||||
"solidCount": int(solids),
|
||||
"volume": volume,
|
||||
**object_status(pad),
|
||||
}
|
||||
except Exception as error:
|
||||
return {
|
||||
"id": case_id,
|
||||
"expected": expected,
|
||||
"observed": "rejected",
|
||||
"passed": expected == "rejected",
|
||||
"errorType": type(error).__name__,
|
||||
"error": str(error),
|
||||
}
|
||||
finally:
|
||||
App.closeDocument(document.Name)
|
||||
|
||||
|
||||
OUTER = [(0, 0), (6, 0), (6, 6), (0, 6)]
|
||||
HOLE = [(2, 2), (2, 4), (4, 4), (4, 2)]
|
||||
|
||||
|
||||
def closed_profile(sketch):
|
||||
add_loop(sketch, OUTER)
|
||||
|
||||
|
||||
def multi_ring_profile(sketch):
|
||||
add_loop(sketch, HOLE)
|
||||
add_loop(sketch, OUTER)
|
||||
|
||||
|
||||
def open_profile(sketch):
|
||||
add_loop(sketch, OUTER, False)
|
||||
|
||||
|
||||
def self_intersecting_profile(sketch):
|
||||
add_loop(sketch, [(0, 0), (4, 4), (0, 4), (4, 0)])
|
||||
|
||||
|
||||
def disjoint_profile(sketch):
|
||||
add_loop(sketch, OUTER)
|
||||
add_loop(sketch, [(8, 8), (9, 8), (9, 9), (8, 9)])
|
||||
|
||||
|
||||
cases = [
|
||||
run_case("closed", "accepted", closed_profile),
|
||||
run_case("multi-ring", "accepted", multi_ring_profile),
|
||||
run_case("open", "rejected", open_profile),
|
||||
run_case("self-intersecting", "accepted", self_intersecting_profile),
|
||||
run_case("invalid-nesting", "accepted", disjoint_profile),
|
||||
]
|
||||
report = {
|
||||
"schemaVersion": 1,
|
||||
"baselineId": "freecad-1.1.1-partdesign-profile-oracle",
|
||||
"freecadVersion": ".".join(App.Version()[0:3]),
|
||||
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||
"length": LENGTH,
|
||||
"tolerance": TOLERANCE,
|
||||
"status": "pass" if all(case["passed"] for case in cases) else "failed",
|
||||
"summary": {
|
||||
"cases": len(cases),
|
||||
"passed": sum(1 for case in cases if case["passed"]),
|
||||
"accepted": sum(1 for case in cases if case["observed"] == "accepted"),
|
||||
"rejected": sum(1 for case in cases if case["observed"] == "rejected"),
|
||||
},
|
||||
"cases": cases,
|
||||
}
|
||||
print("FREECAD_PARTDESIGN_PROFILE_ORACLE_RESULT=" + json.dumps(report, sort_keys=True))
|
||||
Reference in New Issue
Block a user