-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathverify_visible_blender_ovrtx.py
More file actions
141 lines (118 loc) · 4.67 KB
/
Copy pathverify_visible_blender_ovrtx.py
File metadata and controls
141 lines (118 loc) · 4.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python3
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Verify the visible Blender process sees the installed OVRTX runtime."""
from __future__ import annotations
import argparse
import json
import socket
import sys
BLENDER_CODE = r'''
import importlib
import json
from pathlib import Path
import time
import traceback
import bpy
wait_seconds = __WAIT_SECONDS__
result = {}
try:
impl = importlib.import_module(
"bl_ext.user_default.ovrtx_blender_example.ovrtx_blender_example"
)
bundled_runtime = importlib.import_module(
"bl_ext.user_default.ovrtx_blender_example.ovrtx_blender_example.bundled_runtime"
)
runtime_services = importlib.import_module(
"bl_ext.user_default.ovrtx_blender_example.ovrtx_blender_example.runtime_services"
)
prefs = impl.get_addon_preferences()
runtime = impl.runtime_bundle_status()
root_value = (
str(runtime.get("current_root") or "")
if runtime.get("state") == "ready"
else ""
)
defaults = bundled_runtime.defaults(root=Path(root_value) if root_value else None)
if prefs is not None and root_value:
prefs.worker_command = defaults.worker_command
prefs.native_client_path = defaults.native_client_path
prefs.native_client_module = bundled_runtime.DEFAULT_OVRTX_NATIVE_CLIENT_MODULE
started = impl.start_runtime_services_async()
deadline = time.monotonic() + max(0, wait_seconds)
diagnostics = runtime_services.owner.diagnostics()
while diagnostics.get("status") not in {"ready", "failed"} and time.monotonic() < deadline:
time.sleep(0.5)
diagnostics = runtime_services.owner.diagnostics()
preflight = impl.preflight_preferences(prefs) if prefs is not None else None
result = {
"ok": bool(preflight and preflight.get("status") == "pass"),
"addon_preferences_id": getattr(impl, "ADDON_PREFERENCES_ID", ""),
"blend_file": bpy.data.filepath,
"is_dirty": bool(bpy.data.is_dirty),
"render_engine": bpy.context.scene.render.engine,
"runtime": runtime,
"started_async": started,
"worker_command": getattr(prefs, "worker_command", "") if prefs else "",
"native_client_path": getattr(prefs, "native_client_path", "") if prefs else "",
"ovphysx_worker_command": defaults.ovphysx_worker_command,
"runtime_services": diagnostics,
"preflight": preflight,
}
except Exception as exc:
result = {
"ok": False,
"error": repr(exc),
"traceback": traceback.format_exc(),
}
print(json.dumps(result, indent=2, default=str))
'''
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--host", default="127.0.0.1", help="Blender MCP TCP host")
parser.add_argument("--port", type=int, default=9876, help="Blender MCP TCP port")
parser.add_argument(
"--wait",
type=int,
default=120,
help="seconds to wait for OVRTX/OVPhysX runtime services",
)
args = parser.parse_args()
code = BLENDER_CODE.replace("__WAIT_SECONDS__", str(max(0, int(args.wait))))
response = _execute(args.host, args.port, code, timeout=max(10, args.wait + 10))
if response.get("status") != "success":
print(json.dumps(response, indent=2), file=sys.stderr)
return 1
payload = str(response.get("result", {}).get("result", "")).strip()
try:
result = json.loads(payload)
except json.JSONDecodeError:
print(payload)
print("Blender returned non-JSON verification output", file=sys.stderr)
return 1
print(json.dumps(result, indent=2, default=str))
return 0 if result.get("ok") else 1
def _execute(host: str, port: int, code: str, *, timeout: int) -> dict[str, object]:
command = {"type": "execute_code", "params": {"code": code}}
data = json.dumps(command).encode("utf-8")
with socket.create_connection((host, port), timeout=10) as client:
client.sendall(data)
client.settimeout(timeout)
chunks: list[bytes] = []
while True:
try:
chunk = client.recv(65536)
except socket.timeout:
break
if not chunk:
break
chunks.append(chunk)
try:
return json.loads(b"".join(chunks).decode("utf-8"))
except json.JSONDecodeError:
continue
if not chunks:
raise SystemExit(f"no response from Blender MCP at {host}:{port}")
return json.loads(b"".join(chunks).decode("utf-8"))
if __name__ == "__main__":
raise SystemExit(main())