make "inner" edges more visible

This commit is contained in:
Yeicor
2024-02-24 10:56:18 +01:00
parent dc600c3f6c
commit 69b1da711e
2 changed files with 34 additions and 6 deletions

1
yacv_server/plugin.py Normal file
View File

@@ -0,0 +1 @@
# TODO: Plugins that can freely modify the GLTF file as it is being built

View File

@@ -1,6 +1,7 @@
import hashlib
import io
import re
from typing import List, Dict, Tuple
from OCP.BRep import BRep_Tool
from OCP.BRepAdaptor import BRepAdaptor_Curve
@@ -9,7 +10,7 @@ from OCP.TopExp import TopExp
from OCP.TopLoc import TopLoc_Location
from OCP.TopTools import TopTools_IndexedMapOfShape
from OCP.TopoDS import TopoDS_Face, TopoDS_Edge, TopoDS_Shape, TopoDS_Vertex
from build123d import Shape, Vertex
from build123d import Shape, Vertex, Face
from pygltflib import GLTF2
import mylogger
@@ -32,15 +33,23 @@ def tessellate(
shape = Shape(ocp_shape)
# Perform tessellation tasks
edge_to_faces: Dict[TopoDS_Edge, List[TopoDS_Face]] = {}
vertex_to_faces: Dict[TopoDS_Vertex, List[TopoDS_Face]] = {}
if faces:
for face in shape.faces():
_tessellate_face(mgr, face.wrapped, tolerance, angular_tolerance)
if edges:
for edge in face.edges():
edge_to_faces[edge] = edge_to_faces.get(edge, []) + [face.wrapped]
if vertices:
for vertex in face.vertices():
vertex_to_faces[vertex.wrapped] = vertex_to_faces.get(vertex.wrapped, []) + [face.wrapped]
if edges:
for edge in shape.edges():
_tessellate_edge(mgr, edge.wrapped, angular_tolerance, angular_tolerance)
_tessellate_edge(mgr, edge.wrapped, edge_to_faces[edge], angular_tolerance, angular_tolerance)
if vertices:
for vertex in shape.vertices():
_tessellate_vertex(mgr, vertex.wrapped)
_tessellate_vertex(mgr, vertex_to_faces[vertex], vertex.wrapped)
return mgr.gltf
@@ -70,19 +79,37 @@ def _tessellate_face(
mgr.add_face(vertices, indices, uv)
def _push_point(v: Tuple[float, float, float], faces: List[TopoDS_Face]) -> Tuple[float, float, float]:
# Use the connected faces to push edges/vertices and make them always visible
push_dir = (0, 0, 0)
for ocp_face in faces:
normal = Face(ocp_face).normal_at(v)
push_dir = (push_dir[0] + normal.X, push_dir[1] + normal.Y, push_dir[2] + normal.Z)
if push_dir != (0, 0, 0):
# Normalize the push direction by the number of faces and a constant factor
# NOTE: Don't overdo it, or metrics will be wrong
n = len(faces) / 1e-3
push_dir = (push_dir[0] / n, push_dir[1] / n, push_dir[2] / n)
# Push the vertex by the normal
v = (v[0] + push_dir[0], v[1] + push_dir[1], v[2] + push_dir[2])
return v
def _tessellate_edge(
mgr: GLTFMgr,
ocp_edge: TopoDS_Edge,
faces: List[TopoDS_Face],
angular_deflection: float = 0.1,
curvature_deflection: float = 0.1,
):
# Use a curve discretizer to get the vertices
curve = BRepAdaptor_Curve(ocp_edge)
discretizer = GCPnts_TangentialDeflection(curve, angular_deflection, curvature_deflection)
assert discretizer.NbPoints() > 1, "Edge is too small??"
# add vertices
vertices = [
(v.X(), v.Y(), v.Z())
_push_point((v.X(), v.Y(), v.Z()), faces)
for v in (
discretizer.Value(i) # .Transformed(transformation)
for i in range(1, discretizer.NbPoints() + 1)
@@ -91,9 +118,9 @@ def _tessellate_edge(
mgr.add_edge(vertices)
def _tessellate_vertex(mgr: GLTFMgr, ocp_vertex: TopoDS_Vertex):
def _tessellate_vertex(mgr: GLTFMgr, ocp_vertex: TopoDS_Vertex, faces: List[TopoDS_Face]):
c = Vertex(ocp_vertex).center()
mgr.add_vertex((c.X, c.Y, c.Z))
mgr.add_vertex(_push_point((c.X, c.Y, c.Z), faces))
def _hashcode(obj: TopoDS_Shape) -> str: