From b629f07f5ef34464b347ce7cc14c6a53b2c8a6bf Mon Sep 17 00:00:00 2001 From: Yeicor <4929005+Yeicor@users.noreply.github.com> Date: Sun, 20 Apr 2025 12:47:23 +0200 Subject: [PATCH] Fix broken gltf exports and minor cleanup --- assets/licenses.txt | 30 +++++++++++++++--------------- yacv_server/cad.py | 12 ++++++------ yacv_server/gltf.py | 1 + yacv_server/myhttp.py | 1 + yacv_server/pubsub.py | 6 ++---- yacv_server/tessellate.py | 11 ++++++++--- yacv_server/yacv.py | 13 +++++++------ 7 files changed, 40 insertions(+), 34 deletions(-) diff --git a/assets/licenses.txt b/assets/licenses.txt index 1ee7f72..76315f4 100644 --- a/assets/licenses.txt +++ b/assets/licenses.txt @@ -981,7 +981,7 @@ third-party archives. The following npm package may be included in this product: - - typescript@5.7.2 + - typescript@5.8.3 This package contains the following license: @@ -1121,7 +1121,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The following npm package may be included in this product: - - @lit-labs/ssr-dom-shim@1.2.1 + - @lit-labs/ssr-dom-shim@1.3.0 This package contains the following license: @@ -1247,7 +1247,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. The following npm package may be included in this product: - - @babel/parser@7.26.3 + - @babel/parser@7.27.0 This package contains the following license: @@ -1420,7 +1420,7 @@ The following npm packages may be included in this product: - @babel/helper-string-parser@7.25.9 - @babel/helper-validator-identifier@7.25.9 - - @babel/types@7.26.3 + - @babel/types@7.27.0 These packages each contain the following license: @@ -1451,7 +1451,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. The following npm package may be included in this product: - - three-mesh-bvh@0.8.3 + - three-mesh-bvh@0.9.0 This package contains the following license: @@ -1601,7 +1601,7 @@ The MIT license applies to all non-font and non-icon files. The following npm package may be included in this product: - - semver@7.6.3 + - semver@7.7.1 This package contains the following license: @@ -1685,13 +1685,13 @@ THE SOFTWARE. The following npm package may be included in this product: - - three@0.171.0 + - three@0.175.0 This package contains the following license: The MIT License -Copyright © 2010-2024 three.js authors +Copyright © 2010-2025 three.js authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -1775,7 +1775,7 @@ THE SOFTWARE. The following npm package may be included in this product: - - vuetify@3.7.6 + - vuetify@3.8.0 This package contains the following license: @@ -1844,7 +1844,7 @@ THE SOFTWARE. The following npm package may be included in this product: - - ktx-parse@0.7.1 + - ktx-parse@1.0.0 This package contains the following license: @@ -1906,9 +1906,9 @@ SOFTWARE. The following npm packages may be included in this product: - - @gltf-transform/core@4.1.1 - - @gltf-transform/extensions@4.1.1 - - @gltf-transform/functions@4.1.1 + - @gltf-transform/core@4.1.3 + - @gltf-transform/extensions@4.1.3 + - @gltf-transform/functions@4.1.3 These packages each contain the following license: @@ -1968,7 +1968,7 @@ THE SOFTWARE. The following npm package may be included in this product: - - postcss@8.4.49 + - postcss@8.5.3 This package contains the following license: @@ -1997,7 +1997,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. The following npm package may be included in this product: - - nanoid@3.3.8 + - nanoid@3.3.11 This package contains the following license: diff --git a/yacv_server/cad.py b/yacv_server/cad.py index 12128ff..1d576c4 100644 --- a/yacv_server/cad.py +++ b/yacv_server/cad.py @@ -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) diff --git a/yacv_server/gltf.py b/yacv_server/gltf.py index de0ad86..6c4a2df 100644 --- a/yacv_server/gltf.py +++ b/yacv_server/gltf.py @@ -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])) diff --git a/yacv_server/myhttp.py b/yacv_server/myhttp.py index 4eede72..503320b 100644 --- a/yacv_server/myhttp.py +++ b/yacv_server/myhttp.py @@ -138,3 +138,4 @@ class HTTPHandler(SimpleHTTPRequestHandler): self.send_header('E-Tag', f'"{_hash}"') self.end_headers() self.wfile.write(exported_glb) + return None diff --git a/yacv_server/pubsub.py b/yacv_server/pubsub.py index 5a0e627..19f16e2 100644 --- a/yacv_server/pubsub.py +++ b/yacv_server/pubsub.py @@ -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: diff --git a/yacv_server/tessellate.py b/yacv_server/tessellate.py index f40bf56..e8a3eb0 100644 --- a/yacv_server/tessellate.py +++ b/yacv_server/tessellate.py @@ -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]: diff --git a/yacv_server/yacv.py b/yacv_server/yacv.py index 87c7d0f..ef91f25 100644 --- a/yacv_server/yacv.py +++ b/yacv_server/yacv.py @@ -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= and overriden by `show(..., texture="")`. + It can be set with the YACV_BASE_TEXTURE= and overridden by `show(..., texture="")`. The can be file: or data:;base64, where is the mime type and 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,