Compare commits

..

4 Commits

Author SHA1 Message Date
Yeicor
551832258f Merge branch 'master' into renovate/build123d-0.x 2025-02-16 13:02:33 +01:00
Yeicor
3116f909d5 Small fix and updates 2025-02-16 12:59:52 +01:00
Yeicor
6ee98b6e19 Update pyproject.toml 2025-02-16 09:06:10 +01:00
renovate[bot]
25628c96d8 Update dependency build123d to >=0.9,<0.10 2025-02-16 05:20:50 +00:00
13 changed files with 1327 additions and 1400 deletions

View File

@@ -6,9 +6,13 @@
],
"automerge": true,
"automergeType": "branch",
"schedule": [ "* * * * 0,6" ],
"schedule": [
"before 3am on Saturday"
],
"lockFileMaintenance": {
"enabled": true,
"schedule": [ "* * * * 0,6" ]
"schedule": [
"before 3am on Saturday"
]
}
}

View File

@@ -981,7 +981,7 @@ third-party archives.
The following npm package may be included in this product:
- typescript@5.8.3
- typescript@5.7.2
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.3.0
- @lit-labs/ssr-dom-shim@1.2.1
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.27.0
- @babel/parser@7.26.3
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.27.0
- @babel/types@7.26.3
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.9.0
- three-mesh-bvh@0.8.3
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.7.1
- semver@7.6.3
This package contains the following license:
@@ -1685,13 +1685,13 @@ THE SOFTWARE.
The following npm package may be included in this product:
- three@0.175.0
- three@0.171.0
This package contains the following license:
The MIT License
Copyright © 2010-2025 three.js authors
Copyright © 2010-2024 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.8.0
- vuetify@3.7.6
This package contains the following license:
@@ -1844,7 +1844,7 @@ THE SOFTWARE.
The following npm package may be included in this product:
- ktx-parse@1.0.0
- ktx-parse@0.7.1
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.3
- @gltf-transform/extensions@4.1.3
- @gltf-transform/functions@4.1.3
- @gltf-transform/core@4.1.1
- @gltf-transform/extensions@4.1.1
- @gltf-transform/functions@4.1.1
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.5.3
- postcss@8.4.49
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.11
- nanoid@3.3.8
This package contains the following license:

View File

@@ -11,7 +11,7 @@ const emit = defineEmits<{ remove: [string] }>()
let {sceneDocument} = inject<{ sceneDocument: Ref<Document> }>('sceneDocument')!!;
const expandedNames = ref<Array<string>>([]);
let expandedNames = ref<Array<string>>([]);
function meshesList(sceneDocument: Document): Array<Array<Mesh>> {
// Grouped by shared name
@@ -44,7 +44,7 @@ defineExpose({findModel})
<template>
<v-expansion-panels v-for="meshes in meshesList(sceneDocument)" :key="meshName(meshes[0])"
v-model="expandedNames as any" multiple>
v-model="expandedNames" multiple>
<model :meshes="meshes" :viewer="props.viewer" @remove="onRemove(meshes[0])"/>
</v-expansion-panels>
</template>
@@ -61,4 +61,4 @@ defineExpose({findModel})
.v-overlay--active > .v-overlay__content {
display: block !important; /* HACK: Fix buggy tooltips not showing? */
}
</style>
</style>

View File

@@ -1,6 +1,6 @@
{
"name": "yet-another-cad-viewer",
"version": "0.9.6",
"version": "0.9.3",
"description": "",
"license": "MIT",
"private": true,
@@ -22,7 +22,7 @@
"@jamescoyle/vue-icon": "^0.1.2",
"@mdi/js": "^7.4.47",
"@mdi/svg": "^7.4.47",
"three": "^0.177.0",
"three": "^0.173.0",
"three-mesh-bvh": "^0.9.0",
"three-orientation-gizmo": "https://github.com/jrj2211/three-orientation-gizmo",
"vue": "^3.5.13",
@@ -31,17 +31,17 @@
"devDependencies": {
"@tsconfig/node20": "^20.1.4",
"@types/node": "^22.9.3",
"@types/three": "^0.177.0",
"@vitejs/plugin-vue": "^6.0.0",
"@vitejs/plugin-vue-jsx": "^5.0.0",
"@types/three": "^0.173.0",
"@vitejs/plugin-vue": "^5.2.0",
"@vitejs/plugin-vue-jsx": "^4.1.0",
"@vue/tsconfig": "^0.7.0",
"buffer": "^5.5.0||^6.0.0",
"commander": "^14.0.0",
"generate-license-file": "^4.0.0",
"npm-run-all2": "^8.0.0",
"commander": "^13.0.0",
"generate-license-file": "^3.6.0",
"npm-run-all2": "^7.0.1",
"terser": "^5.36.0",
"typescript": "~5.8.0",
"vite": "^7.0.0",
"typescript": "~5.7.0",
"vite": "^6.0.0",
"vue-tsc": "^2.1.10"
}
}

832
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "yacv-server"
version = "0.9.6"
version = "0.9.3"
description = "Yet Another CAD Viewer (server)"
authors = ["Yeicor <4929005+Yeicor@users.noreply.github.com>"]
license = "MIT"

View File

@@ -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, Color
from build123d import Compound, Shape, 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 = [Compound(shape) for shape in shapes_raw_filtered_sorted if shape is not None]
shapes_bd = [Shape(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)

View File

@@ -169,7 +169,6 @@ 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]))

View File

@@ -138,4 +138,3 @@ class HTTPHandler(SimpleHTTPRequestHandler):
self.send_header('E-Tag', f'"{_hash}"')
self.end_headers()
self.wfile.write(exported_glb)
return None

View File

@@ -1,6 +1,8 @@
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
@@ -56,7 +58,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 a generator that yields events and automatically unsubscribes"""
"""Subscribes to events as an generator that yields events and automatically unsubscribes"""
q = self._subscribe(include_buffered, include_future)
try:
while True:

View File

@@ -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 Vertex, Face, Location, Compound
from build123d import Shape, Vertex, Face, Location
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 = Compound(cad_like)
shape = Shape(cad_like)
# Perform tessellation tasks
edge_to_faces: Dict[str, List[TopoDS_Face]] = {}
@@ -59,9 +59,6 @@ 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()
@@ -72,10 +69,9 @@ def _tessellate_face(
angular_tolerance: float = 0.1,
color: Optional[ColorTuple] = None,
):
face = Compound(ocp_face)
face = Shape(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")
@@ -90,7 +86,6 @@ 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]:

View File

@@ -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
from PIL import Image
# noinspection PyProtectedMember
from build123d import Shape, Axis, Location, Vector
from build123d import Shape, Axis, Location, Vector, Color
from dataclasses_json import dataclass_json
from PIL import Image
from io import BytesIO
from yacv_server.cad import _hashcode, get_color
from yacv_server.cad import _hashcode, ColorTuple, 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 overridden by `show(..., texture="<uri>")`.
It can be set with the YACV_BASE_TEXTURE=<uri> and overriden 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,7 +331,6 @@ class YACV:
try:
return next(subscription), event.hash
finally:
# noinspection PyInconsistentReturns
subscription.close()
def export_all(self, folder: str,
@@ -382,30 +381,19 @@ def _preprocess_cad(obj: CADLike, **kwargs) -> CADCoreLike:
return obj
_obj_name_counts = {}
_find_var_name_count = 0
def _find_var_name(obj: any, avoid_levels: int = 2) -> str:
"""A hacky way to get a stable name for an object that may change over time"""
# Build123d objects have a "label" property, CadQuery Assembly's have "name"
for f in ('label', 'name'):
if hasattr(obj, f):
v = getattr(obj, f)
if v != '':
return v;
# Otherwise walk up our stack to see if there's a local variable that points to it
global _find_var_name_count
obj_shape = get_shape(obj, error=False) or obj
for frame in inspect.stack()[avoid_levels:]:
for key, value in frame.frame.f_locals.items():
if get_shape(value, error=False) is obj_shape:
return key
# Last resort, name it for its type with a disambiguating number
global _obj_name_counts
t = obj.__class__.__name__
_obj_name_counts[t] = 1 if t not in _obj_name_counts else _obj_name_counts[t] + 1
return t + str(_obj_name_counts[t])
_find_var_name_count += 1
return 'unknown_var_' + str(_find_var_name_count)
def sizeof_fmt(num, suffix="B"):

1766
yarn.lock

File diff suppressed because it is too large Load Diff