mirror of
https://github.com/yeicor-3d/yet-another-cad-viewer.git
synced 2025-12-19 14:14:13 +01:00
Fix broken gltf exports and minor cleanup
This commit is contained in:
@@ -10,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_Shape
|
||||
from build123d import Compound, Shape, Color
|
||||
from build123d import Compound, Color
|
||||
|
||||
from yacv_server.gltf import GLTFMgr
|
||||
|
||||
@@ -78,7 +78,7 @@ def get_shape(obj: CADLike, error: bool = True) -> Optional[CADCoreLike]:
|
||||
# Sorting is required to improve hashcode consistency
|
||||
shapes_raw_filtered_sorted = sorted(shapes_raw_filtered, key=lambda x: _hashcode(x))
|
||||
# Build a single compound shape
|
||||
shapes_bd = [Shape(shape) for shape in shapes_raw_filtered_sorted if shape is not None]
|
||||
shapes_bd = [Compound(shape) for shape in shapes_raw_filtered_sorted if shape is not None]
|
||||
return get_shape(Compound(shapes_bd), error)
|
||||
except TypeError:
|
||||
pass
|
||||
@@ -121,11 +121,11 @@ def image_to_gltf(source: str | bytes, center: any, width: Optional[float] = Non
|
||||
hasher = hashlib.md5()
|
||||
hasher.update(source)
|
||||
name = 'image_' + hasher.hexdigest()
|
||||
format: str
|
||||
_format: str
|
||||
if save_mime == 'image/jpeg':
|
||||
format = 'JPEG'
|
||||
_format = 'JPEG'
|
||||
elif save_mime == 'image/png':
|
||||
format = 'PNG'
|
||||
_format = 'PNG'
|
||||
else:
|
||||
raise ValueError(f'Unsupported save MIME type (for GLTF files): {save_mime}')
|
||||
|
||||
@@ -154,7 +154,7 @@ def image_to_gltf(source: str | bytes, center: any, width: Optional[float] = Non
|
||||
img = img.resize((new_width, new_height))
|
||||
|
||||
# Save the image to a buffer
|
||||
img.save(img_buf, format=format)
|
||||
img.save(img_buf, format=_format)
|
||||
img_buf = img_buf.getvalue()
|
||||
|
||||
# Convert coordinates system as a last step (gltf is Y-up instead of Z-up)
|
||||
|
||||
@@ -169,6 +169,7 @@ class GLTFMgr:
|
||||
self.gltf.images = [Image(bufferView=len(buffers_list), mimeType=self.image[1])]
|
||||
self.gltf.textures = [Texture(source=0, sampler=0)]
|
||||
self.gltf.samplers = [Sampler(magFilter=NEAREST)]
|
||||
# noinspection PyPep8Naming
|
||||
self.gltf.materials[0].pbrMetallicRoughness.baseColorTexture = TextureInfo(index=0)
|
||||
buffers_list.append((Accessor(), BufferView(), self.image[0]))
|
||||
|
||||
|
||||
@@ -138,3 +138,4 @@ class HTTPHandler(SimpleHTTPRequestHandler):
|
||||
self.send_header('E-Tag', f'"{_hash}"')
|
||||
self.end_headers()
|
||||
self.wfile.write(exported_glb)
|
||||
return None
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import queue
|
||||
import queue
|
||||
import threading
|
||||
from typing import List, TypeVar, \
|
||||
Generic, Generator
|
||||
from typing import List, TypeVar, Generic, Generator
|
||||
|
||||
from yacv_server.mylogger import logger
|
||||
|
||||
@@ -58,7 +56,7 @@ class BufferedPubSub(Generic[T]):
|
||||
|
||||
def subscribe(self, include_buffered: bool = True, include_future: bool = True, yield_timeout: float = 0.0) -> \
|
||||
Generator[T, None, None]:
|
||||
"""Subscribes to events as an generator that yields events and automatically unsubscribes"""
|
||||
"""Subscribes to events as a generator that yields events and automatically unsubscribes"""
|
||||
q = self._subscribe(include_buffered, include_future)
|
||||
try:
|
||||
while True:
|
||||
|
||||
@@ -5,7 +5,7 @@ from OCP.BRepAdaptor import BRepAdaptor_Curve
|
||||
from OCP.GCPnts import GCPnts_TangentialDeflection
|
||||
from OCP.TopLoc import TopLoc_Location
|
||||
from OCP.TopoDS import TopoDS_Face, TopoDS_Edge, TopoDS_Shape, TopoDS_Vertex
|
||||
from build123d import Shape, Vertex, Face, Location
|
||||
from build123d import Vertex, Face, Location, Compound
|
||||
from pygltflib import GLTF2
|
||||
|
||||
from yacv_server.cad import CADCoreLike, ColorTuple
|
||||
@@ -33,7 +33,7 @@ def tessellate(
|
||||
mgr.add_location(Location(cad_like))
|
||||
|
||||
elif isinstance(cad_like, TopoDS_Shape):
|
||||
shape = Shape(cad_like)
|
||||
shape = Compound(cad_like)
|
||||
|
||||
# Perform tessellation tasks
|
||||
edge_to_faces: Dict[str, List[TopoDS_Face]] = {}
|
||||
@@ -59,6 +59,9 @@ def tessellate(
|
||||
for vertex in shape.vertices():
|
||||
_tessellate_vertex(mgr, vertex.wrapped, vertex_to_faces.get(vertex.wrapped, []), obj_color)
|
||||
|
||||
else:
|
||||
raise TypeError(f"Unsupported type: {type(cad_like)}: {cad_like}")
|
||||
|
||||
return mgr.build()
|
||||
|
||||
|
||||
@@ -69,9 +72,10 @@ def _tessellate_face(
|
||||
angular_tolerance: float = 0.1,
|
||||
color: Optional[ColorTuple] = None,
|
||||
):
|
||||
face = Shape(ocp_face)
|
||||
face = Compound(ocp_face)
|
||||
# face.mesh(tolerance, angular_tolerance)
|
||||
tri_mesh = face.tessellate(tolerance, angular_tolerance)
|
||||
# noinspection PyArgumentList
|
||||
poly = BRep_Tool.Triangulation_s(face.wrapped, TopLoc_Location())
|
||||
if poly is None:
|
||||
logger.warn("No triangulation found for face")
|
||||
@@ -86,6 +90,7 @@ def _tessellate_face(
|
||||
vertices = tri_mesh[0]
|
||||
indices = tri_mesh[1]
|
||||
mgr.add_face(vertices, indices, uv, color)
|
||||
return None
|
||||
|
||||
|
||||
def _push_point(v: Tuple[float, float, float], faces: List[TopoDS_Face]) -> Tuple[float, float, float]:
|
||||
|
||||
@@ -9,18 +9,18 @@ import threading
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from http.server import ThreadingHTTPServer
|
||||
from io import BytesIO
|
||||
from threading import Thread
|
||||
from typing import Optional, Dict, Union, Callable, List, Tuple
|
||||
|
||||
from OCP.TopLoc import TopLoc_Location
|
||||
from OCP.TopoDS import TopoDS_Shape
|
||||
# noinspection PyProtectedMember
|
||||
from build123d import Shape, Axis, Location, Vector, Color
|
||||
from dataclasses_json import dataclass_json
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
# noinspection PyProtectedMember
|
||||
from build123d import Shape, Axis, Location, Vector
|
||||
from dataclasses_json import dataclass_json
|
||||
|
||||
from yacv_server.cad import _hashcode, ColorTuple, get_color
|
||||
from yacv_server.cad import _hashcode, get_color
|
||||
from yacv_server.cad import get_shape, grab_all_cad, CADCoreLike, CADLike
|
||||
from yacv_server.gltf import get_version
|
||||
from yacv_server.myhttp import HTTPHandler
|
||||
@@ -95,7 +95,7 @@ class YACV:
|
||||
"""Default texture to use for model faces, in (data, mimetype) format.
|
||||
If left as None, a default checkerboard texture will be used.
|
||||
|
||||
It can be set with the YACV_BASE_TEXTURE=<uri> and overriden by `show(..., texture="<uri>")`.
|
||||
It can be set with the YACV_BASE_TEXTURE=<uri> and overridden by `show(..., texture="<uri>")`.
|
||||
The <uri> can be file:<path> or data:<mime>;base64,<data> where <mime> is the mime type and
|
||||
<data> is the base64 encoded image."""
|
||||
|
||||
@@ -331,6 +331,7 @@ class YACV:
|
||||
try:
|
||||
return next(subscription), event.hash
|
||||
finally:
|
||||
# noinspection PyInconsistentReturns
|
||||
subscription.close()
|
||||
|
||||
def export_all(self, folder: str,
|
||||
|
||||
Reference in New Issue
Block a user