mirror of
https://github.com/yeicor-3d/yet-another-cad-viewer.git
synced 2025-12-19 22:24:17 +01:00
make "inner" edges more visible
This commit is contained in:
1
yacv_server/plugin.py
Normal file
1
yacv_server/plugin.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# TODO: Plugins that can freely modify the GLTF file as it is being built
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
import io
|
import io
|
||||||
import re
|
import re
|
||||||
|
from typing import List, Dict, Tuple
|
||||||
|
|
||||||
from OCP.BRep import BRep_Tool
|
from OCP.BRep import BRep_Tool
|
||||||
from OCP.BRepAdaptor import BRepAdaptor_Curve
|
from OCP.BRepAdaptor import BRepAdaptor_Curve
|
||||||
@@ -9,7 +10,7 @@ from OCP.TopExp import TopExp
|
|||||||
from OCP.TopLoc import TopLoc_Location
|
from OCP.TopLoc import TopLoc_Location
|
||||||
from OCP.TopTools import TopTools_IndexedMapOfShape
|
from OCP.TopTools import TopTools_IndexedMapOfShape
|
||||||
from OCP.TopoDS import TopoDS_Face, TopoDS_Edge, TopoDS_Shape, TopoDS_Vertex
|
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
|
from pygltflib import GLTF2
|
||||||
|
|
||||||
import mylogger
|
import mylogger
|
||||||
@@ -32,15 +33,23 @@ def tessellate(
|
|||||||
shape = Shape(ocp_shape)
|
shape = Shape(ocp_shape)
|
||||||
|
|
||||||
# Perform tessellation tasks
|
# Perform tessellation tasks
|
||||||
|
edge_to_faces: Dict[TopoDS_Edge, List[TopoDS_Face]] = {}
|
||||||
|
vertex_to_faces: Dict[TopoDS_Vertex, List[TopoDS_Face]] = {}
|
||||||
if faces:
|
if faces:
|
||||||
for face in shape.faces():
|
for face in shape.faces():
|
||||||
_tessellate_face(mgr, face.wrapped, tolerance, angular_tolerance)
|
_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:
|
if edges:
|
||||||
for edge in shape.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:
|
if vertices:
|
||||||
for vertex in shape.vertices():
|
for vertex in shape.vertices():
|
||||||
_tessellate_vertex(mgr, vertex.wrapped)
|
_tessellate_vertex(mgr, vertex_to_faces[vertex], vertex.wrapped)
|
||||||
|
|
||||||
return mgr.gltf
|
return mgr.gltf
|
||||||
|
|
||||||
@@ -70,19 +79,37 @@ def _tessellate_face(
|
|||||||
mgr.add_face(vertices, indices, uv)
|
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(
|
def _tessellate_edge(
|
||||||
mgr: GLTFMgr,
|
mgr: GLTFMgr,
|
||||||
ocp_edge: TopoDS_Edge,
|
ocp_edge: TopoDS_Edge,
|
||||||
|
faces: List[TopoDS_Face],
|
||||||
angular_deflection: float = 0.1,
|
angular_deflection: float = 0.1,
|
||||||
curvature_deflection: float = 0.1,
|
curvature_deflection: float = 0.1,
|
||||||
):
|
):
|
||||||
|
# Use a curve discretizer to get the vertices
|
||||||
curve = BRepAdaptor_Curve(ocp_edge)
|
curve = BRepAdaptor_Curve(ocp_edge)
|
||||||
discretizer = GCPnts_TangentialDeflection(curve, angular_deflection, curvature_deflection)
|
discretizer = GCPnts_TangentialDeflection(curve, angular_deflection, curvature_deflection)
|
||||||
assert discretizer.NbPoints() > 1, "Edge is too small??"
|
assert discretizer.NbPoints() > 1, "Edge is too small??"
|
||||||
|
|
||||||
# add vertices
|
# add vertices
|
||||||
vertices = [
|
vertices = [
|
||||||
(v.X(), v.Y(), v.Z())
|
_push_point((v.X(), v.Y(), v.Z()), faces)
|
||||||
for v in (
|
for v in (
|
||||||
discretizer.Value(i) # .Transformed(transformation)
|
discretizer.Value(i) # .Transformed(transformation)
|
||||||
for i in range(1, discretizer.NbPoints() + 1)
|
for i in range(1, discretizer.NbPoints() + 1)
|
||||||
@@ -91,9 +118,9 @@ def _tessellate_edge(
|
|||||||
mgr.add_edge(vertices)
|
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()
|
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:
|
def _hashcode(obj: TopoDS_Shape) -> str:
|
||||||
|
|||||||
Reference in New Issue
Block a user