mirror of
https://github.com/yeicor-3d/yet-another-cad-viewer.git
synced 2025-12-19 22:24:17 +01:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ca53bca61 | ||
|
|
f1b04db24a | ||
|
|
a304536536 | ||
|
|
8b3d08826d | ||
|
|
40f424dd20 | ||
|
|
cb6c0acb63 | ||
|
|
4ddc38f5c5 | ||
|
|
f26d3a65a0 | ||
|
|
b027819815 | ||
|
|
768603b4d3 |
@@ -1290,7 +1290,7 @@ third-party archives.
|
||||
|
||||
The following npm package may be included in this product:
|
||||
|
||||
- typescript@5.3.3
|
||||
- typescript@5.4.2
|
||||
|
||||
This package contains the following license and notice below:
|
||||
|
||||
@@ -2408,7 +2408,7 @@ THE SOFTWARE.
|
||||
|
||||
The following npm package may be included in this product:
|
||||
|
||||
- vuetify@3.5.7
|
||||
- vuetify@3.5.8
|
||||
|
||||
This package contains the following license and notice below:
|
||||
|
||||
|
||||
3
build.py
3
build.py
@@ -2,7 +2,8 @@ import os
|
||||
import subprocess
|
||||
|
||||
if __name__ == "__main__":
|
||||
if os.getenv('SKIP_BUILD_FRONTEND') is None:
|
||||
# Building the frontend is optional
|
||||
if os.getenv('SKIP_BUILD_FRONTEND') is None and os.path.exists('package.json'):
|
||||
# When building the backend, make sure the frontend is built first
|
||||
subprocess.run(['yarn', 'install'], check=True)
|
||||
subprocess.run(['yarn', 'build', '--outDir', 'yacv_server/frontend'], check=True)
|
||||
|
||||
@@ -6,14 +6,11 @@ import {Vector3} from "three/src/math/Vector3.js"
|
||||
import {Box3} from "three/src/math/Box3.js"
|
||||
import {Matrix4} from "three/src/math/Matrix4.js"
|
||||
|
||||
let latestModel: string | null = null;
|
||||
|
||||
/** This class helps manage SceneManagerData. All methods are static to support reactivity... */
|
||||
export class SceneMgr {
|
||||
/** Loads a GLB model from a URL and adds it to the viewer or replaces it if the names match */
|
||||
static async loadModel(sceneUrl: Ref<string>, document: Document, name: string, url: string): Promise<Document> {
|
||||
let loadStart = performance.now();
|
||||
latestModel = name; // To help load helpers only once per model load batch
|
||||
|
||||
// Start merging into the current document, replacing or adding as needed
|
||||
document = await mergePartial(url, name, document);
|
||||
@@ -22,12 +19,8 @@ export class SceneMgr {
|
||||
|
||||
if (name !== extrasNameValueHelpers) {
|
||||
// Reload the helpers to fit the new model
|
||||
// Only reload the helpers after a few milliseconds of no more models being added/removed
|
||||
setTimeout(async () => {
|
||||
if (name === latestModel) {
|
||||
document = await this.reloadHelpers(sceneUrl, document);
|
||||
}
|
||||
}, 10)
|
||||
// TODO: Only reload the helpers after a few milliseconds of no more models being added/removed
|
||||
await this.reloadHelpers(sceneUrl, document);
|
||||
} else {
|
||||
// Display the final fully loaded model
|
||||
let displayStart = performance.now();
|
||||
|
||||
12
package.json
12
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "yet-another-cad-viewer",
|
||||
"version": "0.4.0",
|
||||
"version": "0.4.3",
|
||||
"description": "",
|
||||
"license": "MIT",
|
||||
"author": "Yeicor <4929005+Yeicor@users.noreply.github.com>",
|
||||
@@ -23,11 +23,11 @@
|
||||
"three": "^0.160.1",
|
||||
"three-orientation-gizmo": "https://github.com/jrj2211/three-orientation-gizmo",
|
||||
"vue": "^3.4.21",
|
||||
"vuetify": "^3.5.7"
|
||||
"vuetify": "^3.5.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node20": "^20.1.2",
|
||||
"@types/node": "^20.11.24",
|
||||
"@types/node": "^20.11.25",
|
||||
"@types/three": "^0.160.0",
|
||||
"@vitejs/plugin-vue": "^5.0.3",
|
||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||
@@ -36,9 +36,9 @@
|
||||
"commander": "^12.0.0",
|
||||
"generate-license-file": "^3.0.1",
|
||||
"npm-run-all2": "^6.1.1",
|
||||
"terser": "^5.28.1",
|
||||
"typescript": "~5.3.0",
|
||||
"terser": "^5.29.1",
|
||||
"typescript": "~5.4.2",
|
||||
"vite": "^5.1.5",
|
||||
"vue-tsc": "^2.0.5"
|
||||
"vue-tsc": "^2.0.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "yacv-server"
|
||||
version = "0.4.0" # TODO: Update automatically by CI on release (also for package.json!)
|
||||
version = "0.4.3" # TODO: Update automatically by CI on release (also for package.json!)
|
||||
description = "Yet Another CAD Viewer (server)"
|
||||
authors = ["Yeicor <4929005+Yeicor@users.noreply.github.com>"]
|
||||
license = "MIT"
|
||||
|
||||
@@ -6,7 +6,7 @@ import sys
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from threading import Thread
|
||||
from typing import Optional, Dict, Union
|
||||
from typing import Optional, Dict, Union, Callable
|
||||
|
||||
import aiohttp_cors
|
||||
from OCP.TopLoc import TopLoc_Location
|
||||
@@ -16,7 +16,7 @@ from aiohttp_sse import sse_response
|
||||
from build123d import Shape, Axis, Location, Vector
|
||||
from dataclasses_json import dataclass_json
|
||||
|
||||
from yacv_server.cad import get_shape, grab_all_cad, image_to_gltf
|
||||
from yacv_server.cad import get_shape, grab_all_cad, image_to_gltf, CADLike
|
||||
from yacv_server.mylogger import logger
|
||||
from yacv_server.pubsub import BufferedPubSub
|
||||
from yacv_server.tessellate import _hashcode, tessellate
|
||||
@@ -47,12 +47,12 @@ class UpdatesApiData:
|
||||
|
||||
|
||||
class UpdatesApiFullData(UpdatesApiData):
|
||||
obj: Optional[TopoDS_Shape]
|
||||
obj: Optional[CADLike]
|
||||
"""The OCCT object, if any (not serialized)"""
|
||||
kwargs: Optional[Dict[str, any]]
|
||||
"""The show_object options, if any (not serialized)"""
|
||||
|
||||
def __init__(self, name: str, hash: str, obj: Optional[TopoDS_Shape] = None,
|
||||
def __init__(self, name: str, hash: str, obj: Optional[CADLike] = None,
|
||||
kwargs: Optional[Dict[str, any]] = None):
|
||||
self.name = name
|
||||
self.hash = hash
|
||||
@@ -127,7 +127,7 @@ class Server:
|
||||
return
|
||||
|
||||
graceful_secs_connect = float(os.getenv('YACV_GRACEFUL_SECS_CONNECT', 12.0))
|
||||
graceful_secs_request = float(os.getenv('YACV_GRACEFUL_SECS_REQUEST', 1.0))
|
||||
graceful_secs_request = float(os.getenv('YACV_GRACEFUL_SECS_REQUEST', 5.0))
|
||||
# Make sure we can hold the lock for more than 100ms (to avoid exiting too early)
|
||||
logger.info('Stopping server (waiting for at least one frontend request first, cancel with CTRL+C)...')
|
||||
start = time.time()
|
||||
@@ -215,7 +215,7 @@ class Server:
|
||||
|
||||
obj_counter = 0
|
||||
|
||||
def _show_common(self, name: Optional[str], hash: str, start: float, obj: Optional[TopoDS_Shape] = None,
|
||||
def _show_common(self, name: Optional[str], hash: str, start: float, obj: Optional[CADLike] = None,
|
||||
kwargs=None):
|
||||
name = name or f'object_{self.obj_counter}'
|
||||
self.obj_counter += 1
|
||||
@@ -231,7 +231,7 @@ class Server:
|
||||
logger.info('show_object(%s, %s) took %.3f seconds', name, hash, time.time() - start)
|
||||
return precomputed_info
|
||||
|
||||
def show(self, any_object: Union[bytes, TopoDS_Shape, any], name: Optional[str] = None, **kwargs):
|
||||
def show(self, any_object: Union[bytes, CADLike, any], name: Optional[str] = None, **kwargs):
|
||||
"""Publishes "any" object to the server"""
|
||||
if isinstance(any_object, bytes):
|
||||
self.show_gltf(any_object, name, **kwargs)
|
||||
@@ -257,7 +257,7 @@ class Server:
|
||||
# Publish it like any other GLTF object
|
||||
self.show_gltf(gltf, name, **kwargs)
|
||||
|
||||
def show_cad(self, obj: Union[TopoDS_Shape, any], name: Optional[str] = None, **kwargs):
|
||||
def show_cad(self, obj: Union[CADLike, any], name: Optional[str] = None, **kwargs):
|
||||
"""Publishes a CAD object to the server"""
|
||||
start = time.time()
|
||||
|
||||
@@ -346,14 +346,15 @@ class Server:
|
||||
finally:
|
||||
await subscription.aclose()
|
||||
|
||||
def export_all(self, folder: str) -> None:
|
||||
def export_all(self, folder: str, export_filter: Callable[[str, Optional[CADLike]], bool] = lambda name, obj: True):
|
||||
"""Export all previously-shown objects to GLB files in the given folder"""
|
||||
import asyncio
|
||||
|
||||
async def _export_all():
|
||||
os.makedirs(folder, exist_ok=True)
|
||||
for name in self.shown_object_names():
|
||||
with open(os.path.join(folder, f'{name}.glb'), 'wb') as f:
|
||||
f.write(await self.export(name))
|
||||
if export_filter(name, self._shown_object(name).obj):
|
||||
with open(os.path.join(folder, f'{name}.glb'), 'wb') as f:
|
||||
f.write(await self.export(name))
|
||||
|
||||
asyncio.run(_export_all())
|
||||
|
||||
82
yarn.lock
82
yarn.lock
@@ -805,10 +805,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/ndarray/-/ndarray-1.0.14.tgz#96b28c09a3587a76de380243f87bb7a2d63b4b23"
|
||||
integrity sha512-oANmFZMnFQvb219SSBIhI1Ih/r4CvHDOzkWyJS/XRqkMrGH5/kaPSA1hQhdIBzouaE+5KpE/f5ylI9cujmckQg==
|
||||
|
||||
"@types/node@^20.11.24":
|
||||
version "20.11.24"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.24.tgz#cc207511104694e84e9fb17f9a0c4c42d4517792"
|
||||
integrity sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==
|
||||
"@types/node@^20.11.25":
|
||||
version "20.11.25"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.25.tgz#0f50d62f274e54dd7a49f7704cc16bfbcccaf49f"
|
||||
integrity sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==
|
||||
dependencies:
|
||||
undici-types "~5.26.4"
|
||||
|
||||
@@ -851,26 +851,26 @@
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz#508d6a0f2440f86945835d903fcc0d95d1bb8a37"
|
||||
integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==
|
||||
|
||||
"@volar/language-core@2.1.1", "@volar/language-core@~2.1.1":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.1.1.tgz#ea7c2448ac5bdb2dd2ed202e5ff57929cb8ef191"
|
||||
integrity sha512-oVbZcj97+5zlowkHMSJMt3aaAFuFyhXeXoOEHcqGECxFvw1TPCNnMM9vxhqNpoiNeWKHvggoq9WCk/HzJHtP8A==
|
||||
"@volar/language-core@2.1.2", "@volar/language-core@~2.1.2":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.1.2.tgz#2053c0ee48a822d5418be2c192e51e580764b49f"
|
||||
integrity sha512-5qsDp0Gf6fE09UWCeK7bkVn6NxMwC9OqFWQkMMkeej8h8XjyABPdRygC2RCrqDrfVdGijqlMQeXs6yRS+vfZYA==
|
||||
dependencies:
|
||||
"@volar/source-map" "2.1.1"
|
||||
"@volar/source-map" "2.1.2"
|
||||
|
||||
"@volar/source-map@2.1.1":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.1.1.tgz#9ca00177177417496a0364cea2f965445e19abb2"
|
||||
integrity sha512-OOtxrEWB2eZ+tnCy5JwDkcCPGlN3+ioNNzkywXE9k4XA7p4cN36frR7QPAOksvd7RXKUGHzSjq6XrYnTPa4z4Q==
|
||||
"@volar/source-map@2.1.2":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.1.2.tgz#d270ff8ef5c814582f0efe08272c0fd6b9effb3b"
|
||||
integrity sha512-yFJqsuLm1OaWrsz9E3yd3bJcYIlHqdZ8MbmIoZLrAzMYQDcoF26/INIhgziEXSdyHc8xd7rd/tJdSnUyh0gH4Q==
|
||||
dependencies:
|
||||
muggle-string "^0.4.0"
|
||||
|
||||
"@volar/typescript@~2.1.1":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.1.1.tgz#b3dddaf39140cc0e00d67bad943496e2470a3882"
|
||||
integrity sha512-5K41AWvFZCMMKZCx8bbFvbkyiKHr0s9k8P0M1FVXLX/9HYHzK5C9B8cX4uhATSehAytFIRnR4fTXVQtWp/Yzag==
|
||||
"@volar/typescript@~2.1.2":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.1.2.tgz#61f838cf4410e328a7ba638fadc41bb814772508"
|
||||
integrity sha512-lhTancZqamvaLvoz0u/uth8dpudENNt2LFZOWCw9JZiX14xRFhdhfzmphiCRb7am9E6qAJSbdS/gMt1utXAoHQ==
|
||||
dependencies:
|
||||
"@volar/language-core" "2.1.1"
|
||||
"@volar/language-core" "2.1.2"
|
||||
path-browserify "^1.0.1"
|
||||
|
||||
"@vue/babel-helper-vue-transform-on@1.2.1":
|
||||
@@ -948,12 +948,12 @@
|
||||
"@vue/compiler-dom" "3.4.21"
|
||||
"@vue/shared" "3.4.21"
|
||||
|
||||
"@vue/language-core@2.0.5":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.0.5.tgz#bd3502604ea785f4171815005997988563f18469"
|
||||
integrity sha512-knGXuQqhDSO7QJr8LFklsiWa23N2ikehkdVxtc9UKgnyqsnusughS2Tkg7VN8Hqed35X0B52Z+OGI5OrT/8uxQ==
|
||||
"@vue/language-core@2.0.6":
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.0.6.tgz#876f90622a3f801dce5cedcd6eae429d732152e2"
|
||||
integrity sha512-UzqU12tzf9XLqRO3TiWPwRNpP4fyUzE6MAfOQWQNZ4jy6a30ARRUpmODDKq6O8C4goMc2AlPqTmjOHPjHkilSg==
|
||||
dependencies:
|
||||
"@volar/language-core" "~2.1.1"
|
||||
"@volar/language-core" "~2.1.2"
|
||||
"@vue/compiler-dom" "^3.4.0"
|
||||
"@vue/shared" "^3.4.0"
|
||||
computeds "^0.0.1"
|
||||
@@ -2878,10 +2878,10 @@ tar@^6.1.11, tar@^6.1.2:
|
||||
mkdirp "^1.0.3"
|
||||
yallist "^4.0.0"
|
||||
|
||||
terser@^5.28.1:
|
||||
version "5.28.1"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.28.1.tgz#bf00f7537fd3a798c352c2d67d67d65c915d1b28"
|
||||
integrity sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==
|
||||
terser@^5.29.1:
|
||||
version "5.29.1"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.29.1.tgz#44e58045b70c09792ba14bfb7b4e14ca8755b9fa"
|
||||
integrity sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==
|
||||
dependencies:
|
||||
"@jridgewell/source-map" "^0.3.3"
|
||||
acorn "^8.8.2"
|
||||
@@ -2935,10 +2935,10 @@ tunnel-agent@^0.6.0:
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
typescript@~5.3.0:
|
||||
version "5.3.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37"
|
||||
integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==
|
||||
typescript@~5.4.2:
|
||||
version "5.4.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372"
|
||||
integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==
|
||||
|
||||
undici-types@~5.26.4:
|
||||
version "5.26.5"
|
||||
@@ -3011,13 +3011,13 @@ vue-template-compiler@^2.7.14:
|
||||
de-indent "^1.0.2"
|
||||
he "^1.2.0"
|
||||
|
||||
vue-tsc@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-2.0.5.tgz#f491e24d74fcbf50cc3a71fce5ac2c99ee6335d9"
|
||||
integrity sha512-e8WCgOVTrbmC04XPnI+IpaMTFYKaTm5s/MXFcvxO1l9kxzn+9FpGNVrBSlQE8VpTJaJg4kaBK1nj3NC20VJzjw==
|
||||
vue-tsc@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-2.0.6.tgz#29cb195ffea63d66ec70b64eb4aadc6cd162bb12"
|
||||
integrity sha512-kK50W4XqQL34vHRkxlRWLicrT6+F9xfgCgJ4KSmCHcytKzc1u3c94XXgI+CjmhOSxyw0krpExF7Obo7y4+0dVQ==
|
||||
dependencies:
|
||||
"@volar/typescript" "~2.1.1"
|
||||
"@vue/language-core" "2.0.5"
|
||||
"@volar/typescript" "~2.1.2"
|
||||
"@vue/language-core" "2.0.6"
|
||||
semver "^7.5.4"
|
||||
|
||||
vue@^3.4.21:
|
||||
@@ -3031,10 +3031,10 @@ vue@^3.4.21:
|
||||
"@vue/server-renderer" "3.4.21"
|
||||
"@vue/shared" "3.4.21"
|
||||
|
||||
vuetify@^3.5.7:
|
||||
version "3.5.7"
|
||||
resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-3.5.7.tgz#9dfa027a582aa7d2211c8019c33ef7cadd66c5c0"
|
||||
integrity sha512-BFj/puY8odRwY50pRfE1gpawnxreY8PtPb/tDw3oumxSLXhoXw8q6YLA6QUvqZrYEzcYpojxZIYhNWUky2KN1w==
|
||||
vuetify@^3.5.8:
|
||||
version "3.5.8"
|
||||
resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-3.5.8.tgz#bc8f08dfd3314640e7b5d43b50138a26d650cbbf"
|
||||
integrity sha512-8nGS+lKejZkev55HFwIfsRt+9fOqbeDQNmXxfmLKAlnUT8FtynVwbjAwHMtX/OQAQ3ZwRaR1ptqQQmx3OgxzbQ==
|
||||
|
||||
walk-up-path@^3.0.1:
|
||||
version "3.0.1"
|
||||
|
||||
Reference in New Issue
Block a user