- added renderer

- Added undo
This commit is contained in:
bklronin
2026-07-12 23:25:59 +02:00
parent 9f1387fe68
commit dda9db822b
2 changed files with 36 additions and 25 deletions
+22 -16
View File
@@ -4,19 +4,9 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="8f0bafd6-58a0-4b20-aa2b-ddc3ba278873" name="Changes" comment="- Working assembly multi :)">
<list default="true" id="8f0bafd6-58a0-4b20-aa2b-ddc3ba278873" name="Changes" comment="- added renderer&#10;- Added undo">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui.ui" beforeDir="false" afterPath="$PROJECT_DIR$/gui.ui" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui_ui.py" beforeDir="false" afterPath="$PROJECT_DIR$/gui_ui.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/geometry/base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/geometry/base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/geometry_occ/sketch.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/geometry_occ/sketch.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/io/project_io.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/io/project_io.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/models/data_model.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/models/data_model.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/rendering/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/rendering/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/rendering/occ_renderer.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/rendering/occ_renderer.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/ui/main_window.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/ui/main_window.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/ui/sketch_widget.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/ui/sketch_widget.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/ui/viewer_widget.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/ui/viewer_widget.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/fluency/rendering/occ_to_mesh.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/fluency/rendering/occ_to_mesh.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -405,7 +395,23 @@
<option name="project" value="LOCAL" />
<updated>1783798929531</updated>
</task>
<option name="localTasksCounter" value="36" />
<task id="LOCAL-00036" summary="- added renderer">
<option name="closed" value="true" />
<created>1783887682052</created>
<option name="number" value="00036" />
<option name="presentableId" value="LOCAL-00036" />
<option name="project" value="LOCAL" />
<updated>1783887682052</updated>
</task>
<task id="LOCAL-00037" summary="- added renderer&#10;- Added undo">
<option name="closed" value="true" />
<created>1783887704766</created>
<option name="number" value="00037" />
<option name="presentableId" value="LOCAL-00037" />
<option name="project" value="LOCAL" />
<updated>1783887704766</updated>
</task>
<option name="localTasksCounter" value="38" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@@ -426,8 +432,6 @@
<ignored-roots>
<path value="$PROJECT_DIR$/pythonProject" />
</ignored-roots>
<MESSAGE value="init" />
<MESSAGE value="- Basic oop sketch widget implement" />
<MESSAGE value="- Renabled extrusion with new object system" />
<MESSAGE value="- Sketch projection partly works again :)" />
<MESSAGE value="- Added new componnt controls" />
@@ -451,6 +455,8 @@
<MESSAGE value="- assembly draft" />
<MESSAGE value="- Added save file foramt&#10;- Split main.py refactor" />
<MESSAGE value="- Working assembly multi :)" />
<option name="LAST_COMMIT_MESSAGE" value="- Working assembly multi :)" />
<MESSAGE value="- added renderer" />
<MESSAGE value="- added renderer&#10;- Added undo" />
<option name="LAST_COMMIT_MESSAGE" value="- added renderer&#10;- Added undo" />
</component>
</project>
+14 -9
View File
@@ -87,17 +87,18 @@ def occ_shape_to_ply(
f"Tessellation: {len(vertices)} vertices, {len(faces)} triangles"
)
# Compute outward-facing vertex normals from triangle geometry.
# This ensures consistent lighting even when OCC triangulation winding
# is inconsistent across faces (e.g. after location transforms).
normals = _compute_outward_normals(vertices, faces, shape)
# Compute outward-facing vertex normals AND correct face winding.
# OCC triangulation produces inconsistent winding across faces (especially
# after location transforms). Mitsuba uses face winding for front/back
# determination, so both normals AND winding must be consistent.
normals, corrected_faces = _compute_outward_normals(vertices, faces, shape)
# Write PLY with normals
# Write PLY with corrected faces and normals
if output_path is None:
fd, output_path = tempfile.mkstemp(suffix=".ply", prefix="fluency_render_")
os.close(fd)
_write_ply(output_path, vertices, faces, normals)
_write_ply(output_path, vertices, corrected_faces, normals)
logger.info(f"Wrote PLY: {output_path}")
return output_path
@@ -106,14 +107,18 @@ def _compute_outward_normals(
vertices: np.ndarray,
faces: np.ndarray,
shape,
) -> np.ndarray:
"""Compute outward-facing vertex normals.
) -> Tuple[np.ndarray, np.ndarray]:
"""Compute outward-facing vertex normals and correct face winding.
1. Compute per-face normals from cross product of triangle edges.
2. Determine correct orientation by checking face normals against the
shape centroid (outward = away from center).
3. Flip triangles with inward normals before accumulating to vertices.
4. Average and normalize per-vertex normals.
Returns (normals, corrected_faces) so the PLY writer can use consistent
winding order — critical for Mitsuba which uses winding for front/back
face determination.
"""
n_verts = len(vertices)
v_normals = np.zeros((n_verts, 3), dtype=np.float64)
@@ -189,7 +194,7 @@ def _compute_outward_normals(
v_lengths[v_lengths < 1e-10] = 1.0
v_normals /= v_lengths
return v_normals.astype(np.float32)
return v_normals.astype(np.float32), corrected_faces.astype(np.uint32)
def occ_shape_to_stl(