feat: expand oracle and topology evidence gates
This commit is contained in:
@@ -8,6 +8,20 @@ import FreeCAD as App
|
||||
|
||||
|
||||
def property_metadata(obj):
|
||||
def json_value(value):
|
||||
if value is None or isinstance(value, (bool, int, float, str)):
|
||||
return value
|
||||
if isinstance(value, (list, tuple)):
|
||||
return [json_value(item) for item in value]
|
||||
if isinstance(value, dict):
|
||||
return {str(key): json_value(item) for key, item in value.items()}
|
||||
# FreeCAD quantities and placements keep a stable textual form while
|
||||
# the report remains valid JSON for every registered property type.
|
||||
try:
|
||||
return str(value)
|
||||
except Exception:
|
||||
return "<unserializable>"
|
||||
|
||||
properties = []
|
||||
for name in obj.PropertiesList:
|
||||
try:
|
||||
@@ -22,23 +36,61 @@ def property_metadata(obj):
|
||||
status = list(obj.getPropertyStatus(name))
|
||||
except Exception:
|
||||
status = []
|
||||
properties.append({"name": name, "typeId": type_id, "group": group, "status": status})
|
||||
try:
|
||||
default = json_value(getattr(obj, name))
|
||||
except Exception:
|
||||
default = "<unreadable>"
|
||||
properties.append({"name": name, "typeId": type_id, "group": group, "status": status, "default": default})
|
||||
return properties
|
||||
|
||||
|
||||
def probe_object(document, type_id):
|
||||
object_name = "Reference" + type_id.replace(":", "_")
|
||||
try:
|
||||
obj = document.addObject(type_id, "Reference" + type_id.replace(":", "_"))
|
||||
obj = document.addObject(type_id, object_name)
|
||||
except Exception as error:
|
||||
return {"typeId": type_id, "available": False, "error": str(error)}
|
||||
return {"typeId": type_id, "available": False, "probeStatus": "unavailable", "error": str(error)}
|
||||
return {
|
||||
"typeId": type_id,
|
||||
"available": True,
|
||||
"probeStatus": "available",
|
||||
"name": obj.Name,
|
||||
"runtimeTypeId": obj.TypeId,
|
||||
"properties": property_metadata(obj),
|
||||
}
|
||||
|
||||
|
||||
def probe_registered_objects(document):
|
||||
try:
|
||||
registered = sorted(set(str(type_id) for type_id in document.supportedTypes()))
|
||||
except Exception as error:
|
||||
return {"available": False, "types": [], "error": str(error)}
|
||||
|
||||
records = []
|
||||
for index, type_id in enumerate(registered):
|
||||
record = probe_object(document, type_id)
|
||||
record["candidateIndex"] = index
|
||||
record["candidateSource"] = "Document.supportedTypes"
|
||||
records.append(record)
|
||||
# A few GUI-only TechDraw providers dereference their view during
|
||||
# removeObject(). Keep those instances alive until FreeCAD exits so a
|
||||
# probe cannot turn a valid metadata observation into a process crash.
|
||||
if not bool(getattr(App, "GuiUp", False)) and record.get("available") and record.get("name"):
|
||||
try:
|
||||
document.removeObject(record["name"])
|
||||
except Exception as error:
|
||||
record["cleanupError"] = str(error)
|
||||
|
||||
return {
|
||||
"available": True,
|
||||
"candidateSource": "Document.supportedTypes",
|
||||
"candidateCount": len(records),
|
||||
"availableCount": sum(1 for record in records if record.get("available")),
|
||||
"unavailableCount": sum(1 for record in records if not record.get("available")),
|
||||
"types": records,
|
||||
}
|
||||
|
||||
|
||||
ALL_REFERENCE_MODULES = [
|
||||
"AddonManager", "Assembly", "BIM", "CAM", "Cloud", "Draft", "Fem", "Help",
|
||||
"Idf", "Import", "Inspection", "JtReader", "Material", "Measure", "Mesh",
|
||||
@@ -180,6 +232,9 @@ def probe_gui_commands(document, selected_object):
|
||||
|
||||
document = App.newDocument("ReferenceProbe")
|
||||
box_object = document.addObject("Part::Box", "CommandProbeBox")
|
||||
modules = [probe_module(name) for name in ALL_REFERENCE_MODULES]
|
||||
gui_commands = probe_gui_commands(document, box_object)
|
||||
runtime_objects = probe_registered_objects(document)
|
||||
version = App.Version()
|
||||
result = {
|
||||
"schemaVersion": 1,
|
||||
@@ -191,12 +246,13 @@ result = {
|
||||
"guiUp": bool(getattr(App, "GuiUp", False)),
|
||||
"buildPurpose": "desktop-reference-oracle" if bool(getattr(App, "GuiUp", False)) else "headless-reference-oracle",
|
||||
"moduleCount": len(ALL_REFERENCE_MODULES),
|
||||
"modules": [probe_module(name) for name in ALL_REFERENCE_MODULES],
|
||||
"modules": modules,
|
||||
"objects": [probe_object(document, type_id) for type_id in [
|
||||
"Part::Box", "Part::Cylinder", "Part::Sphere", "Part::Cone",
|
||||
"Part::Feature", "PartDesign::Feature", "Sketcher::SketchObject",
|
||||
]],
|
||||
"guiCommands": probe_gui_commands(document, box_object),
|
||||
"runtimeObjects": runtime_objects,
|
||||
"guiCommands": gui_commands,
|
||||
}
|
||||
result["moduleStatusSummary"] = {
|
||||
status: sum(1 for module in result["modules"] if module["runtimeStatus"] == status)
|
||||
|
||||
Reference in New Issue
Block a user