feat(export_gltf): embed sharp angle in GLB extras + restore script
- Add export_extras=True to bpy.ops.export_scene.gltf() call
- Store schaeffler_sharp_angle_deg in scene custom props before export
→ value is embedded in scenes[0].extras in the GLB JSON chunk
→ survives import/export round-trip intact (verified: 30.0 restored)
- Add tools/restore_sharp_marks.py: companion Blender script that reads
the angle from scene.get("schaeffler_sharp_angle_deg") and re-applies
mark_sharp() + mark_seam() on all mesh objects after GLB import
GLB format cannot store per-edge sharp/seam flags natively; the visual
shading is correct via vertex splits. The extras + restore script give
users the ability to reconstruct Edit Mode markers without a second format.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -281,7 +281,14 @@ def main() -> None:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass # non-critical; export proceeds regardless
|
pass # non-critical; export proceeds regardless
|
||||||
|
|
||||||
# Export production GLB with full PBR material data
|
# Store the sharp angle in the scene so it is embedded in the GLB extras.
|
||||||
|
# After importing the production GLB in Blender, running restore_sharp_marks.py
|
||||||
|
# reads this value and re-applies mark_sharp()+mark_seam() on all mesh objects.
|
||||||
|
bpy.context.scene["schaeffler_sharp_angle_deg"] = args.smooth_angle
|
||||||
|
|
||||||
|
# Export production GLB with full PBR material data.
|
||||||
|
# export_extras=True embeds scene custom properties (incl. schaeffler_sharp_angle_deg)
|
||||||
|
# in the glTF scenes[0].extras JSON field, surviving the round-trip intact.
|
||||||
try:
|
try:
|
||||||
bpy.ops.export_scene.gltf(
|
bpy.ops.export_scene.gltf(
|
||||||
filepath=args.output_path,
|
filepath=args.output_path,
|
||||||
@@ -290,6 +297,7 @@ def main() -> None:
|
|||||||
use_selection=False,
|
use_selection=False,
|
||||||
export_materials="EXPORT",
|
export_materials="EXPORT",
|
||||||
export_image_format="AUTO",
|
export_image_format="AUTO",
|
||||||
|
export_extras=True,
|
||||||
)
|
)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print(f"GLB export failed: {exc}", file=sys.stderr)
|
print(f"GLB export failed: {exc}", file=sys.stderr)
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
"""Blender companion script: restore sharp + seam edge marks after importing a production GLB.
|
||||||
|
|
||||||
|
After importing a Schaeffler production GLB in Blender, run this script once via
|
||||||
|
the Scripting workspace (Text Editor → Run Script). It reads the sharp angle that
|
||||||
|
was baked into the GLB at export time and re-applies mark_sharp() + mark_seam() on
|
||||||
|
every mesh object.
|
||||||
|
|
||||||
|
The GLB visual shading already encodes the sharp edges via vertex splits (normals).
|
||||||
|
This script restores the blue sharp-crease and red seam markers in Edit Mode for
|
||||||
|
further editing in Blender.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
1. File → Import → glTF 2.0 (.glb) — open your production GLB
|
||||||
|
2. Open the Scripting workspace
|
||||||
|
3. Open this file (Text Editor → Open → restore_sharp_marks.py)
|
||||||
|
4. Click Run Script
|
||||||
|
"""
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
import math
|
||||||
|
|
||||||
|
angle_deg = bpy.context.scene.get("schaeffler_sharp_angle_deg", 30.0)
|
||||||
|
smooth_rad = math.radians(float(angle_deg))
|
||||||
|
|
||||||
|
mesh_objects = [o for o in bpy.data.objects if o.type == "MESH"]
|
||||||
|
if not mesh_objects:
|
||||||
|
print("No mesh objects found in scene.")
|
||||||
|
else:
|
||||||
|
total_sharp = 0
|
||||||
|
bpy.ops.object.select_all(action="DESELECT")
|
||||||
|
for obj in mesh_objects:
|
||||||
|
bpy.context.view_layer.objects.active = obj
|
||||||
|
obj.select_set(True)
|
||||||
|
bpy.ops.object.mode_set(mode="OBJECT")
|
||||||
|
for poly in obj.data.polygons:
|
||||||
|
poly.use_smooth = True
|
||||||
|
bpy.ops.object.mode_set(mode="EDIT")
|
||||||
|
bpy.ops.mesh.select_all(action="DESELECT")
|
||||||
|
bpy.ops.mesh.edges_select_sharp(sharpness=smooth_rad)
|
||||||
|
bpy.ops.mesh.mark_sharp()
|
||||||
|
bpy.ops.mesh.mark_seam()
|
||||||
|
bpy.ops.object.mode_set(mode="OBJECT")
|
||||||
|
total_sharp += sum(1 for e in obj.data.edges if e.use_edge_sharp)
|
||||||
|
obj.select_set(False)
|
||||||
|
print(f"Restored sharp/seam marks at {angle_deg}°: "
|
||||||
|
f"{total_sharp} edges across {len(mesh_objects)} objects.")
|
||||||
Reference in New Issue
Block a user