mirror of
https://github.com/yeicor-3d/yet-another-cad-viewer.git
synced 2025-12-19 22:24:17 +01:00
lots of fixes and finding new problems
This commit is contained in:
@@ -53,11 +53,30 @@ function centerCamera() {
|
||||
let selectionEnabled = ref(false);
|
||||
let selectedMaterials: Array<Material> = []
|
||||
let hasListener = false;
|
||||
let ignoreClickFrom: [number, number] | null = null;
|
||||
let selectionMoveListener = (event: MouseEvent) => {
|
||||
if (!selectionEnabled.value) return;
|
||||
ignoreClickFrom = [event.clientX, event.clientY];
|
||||
};
|
||||
|
||||
let selectionListener = (event: MouseEvent) => {
|
||||
if (!selectionEnabled.value) return;
|
||||
if (!selectionEnabled.value) {
|
||||
ignoreClickFrom = undefined;
|
||||
return;
|
||||
}
|
||||
if (ignoreClickFrom) {
|
||||
let [x, y] = ignoreClickFrom;
|
||||
if (Math.abs(event.clientX - x) > 5 || Math.abs(event.clientY - y) > 5) {
|
||||
ignoreClickFrom = undefined;
|
||||
return;
|
||||
}
|
||||
ignoreClickFrom = undefined;
|
||||
}
|
||||
let viewer: ModelViewerElement = props.refSData.viewer;
|
||||
// FIXME: Clicking near edges does not work...
|
||||
// FIXME: Clicking with ORTHO camera does not work...
|
||||
const material = viewer.materialFromPoint(event.clientX, event.clientY);
|
||||
console.log(material)
|
||||
if (material === null) return;
|
||||
const wasSelected = selectedMaterials.find((m) => m === material) !== undefined;
|
||||
if (wasSelected) {
|
||||
@@ -85,7 +104,8 @@ function toggleSelection() {
|
||||
selectionEnabled.value = !selectionEnabled.value;
|
||||
if (selectionEnabled.value) {
|
||||
if (!hasListener) {
|
||||
viewer.addEventListener('click', selectionListener);
|
||||
viewer.addEventListener('mouseup', selectionListener);
|
||||
viewer.addEventListener('mousedown', selectionMoveListener); // Avoid clicking when dragging
|
||||
hasListener = true;
|
||||
}
|
||||
for (let material of selectedMaterials) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import {settings} from "../misc/settings";
|
||||
import {ModelViewerElement, RGBA} from '@google/model-viewer';
|
||||
import {ModelViewerElement} from '@google/model-viewer';
|
||||
import {onMounted, ref} from "vue";
|
||||
import {$scene} from "@google/model-viewer/lib/model-viewer-base";
|
||||
import type {ModelScene} from "@google/model-viewer/lib/three-components/ModelScene";
|
||||
@@ -33,12 +33,13 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<model-viewer ref="viewer"
|
||||
style="width: 100%; height: 100%" :src="props.src" alt="The 3D model(s)" camera-controls
|
||||
camera-orbit="30deg 75deg auto"
|
||||
max-camera-orbit="Infinity 180deg auto" min-camera-orbit="-Infinity 0deg auto" disable-tap
|
||||
style="width: 100%; height: 100%" :src="props.src" alt="The 3D model(s)" camera-controls camera-orbit="30deg 75deg auto"
|
||||
max-camera-orbit="Infinity 180deg auto" min-camera-orbit="-Infinity 0deg 1%" disable-tap
|
||||
:exposure="settings.exposure" :shadow-intensity="settings.shadowIntensity" interaction-prompt="none"
|
||||
:autoplay="settings.autoplay" :ar="settings.arModes.length > 0" :ar-modes="settings.arModes"
|
||||
:skybox-image="settings.background" :environment-image="settings.background"></model-viewer>
|
||||
:skybox-image="settings.background" :environment-image="settings.background">
|
||||
<slot></slot> <!-- Controls, annotations, etc. -->
|
||||
</model-viewer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import importlib.metadata
|
||||
|
||||
import numpy as np
|
||||
from pygltflib import *
|
||||
|
||||
@@ -10,6 +12,8 @@ class GLTFMgr:
|
||||
"""A utility class to build our GLTF2 objects easily and incrementally"""
|
||||
|
||||
gltf: GLTF2 = GLTF2(
|
||||
asset=Asset(generator=f"yacv_server@{importlib.metadata.version('yacv_server')}"),
|
||||
scene=0,
|
||||
scenes=[Scene(nodes=[0])],
|
||||
nodes=[Node(mesh=0)],
|
||||
meshes=[Mesh(primitives=[])],
|
||||
@@ -19,16 +23,6 @@ class GLTFMgr:
|
||||
samplers=[Sampler(magFilter=NEAREST)],
|
||||
textures=[Texture(source=0, sampler=0)],
|
||||
images=[Image(bufferView=0, mimeType='image/png')],
|
||||
materials=[
|
||||
Material(name="face", alphaCutoff=None, pbrMetallicRoughness=PbrMetallicRoughness(
|
||||
baseColorTexture=TextureInfo(index=0), baseColorFactor=[1, 1, 0.5, 1])),
|
||||
Material(name="edge", alphaCutoff=None, pbrMetallicRoughness=PbrMetallicRoughness(
|
||||
baseColorFactor=[0, 0, 0.5, 1])),
|
||||
Material(name="vertex", alphaCutoff=None, pbrMetallicRoughness=PbrMetallicRoughness(
|
||||
baseColorFactor=[0.5, 0.5, 0.5, 1])),
|
||||
# Material(name="selected", alphaCutoff=None, pbrMetallicRoughness=PbrMetallicRoughness(
|
||||
# baseColorTexture=TextureInfo(index=0), baseColorFactor=[1, 0, 0, 1])),
|
||||
],
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
@@ -40,24 +34,41 @@ class GLTFMgr:
|
||||
vertices = np.array([[v[0], v[1], v[2]] for v in vertices_raw], dtype=np.float32)
|
||||
indices = np.array([[i[0], i[1], i[2]] for i in indices_raw], dtype=np.uint32)
|
||||
tex_coord = np.array([[t[0], t[1]] for t in tex_coord_raw], dtype=np.float32)
|
||||
self._add_any(vertices, indices, tex_coord, mode=TRIANGLES, material=0)
|
||||
self._add_any(vertices, indices, tex_coord, mode=TRIANGLES, material="face")
|
||||
|
||||
def add_edge(self, vertices_raw: List[Tuple[float, float, float]]):
|
||||
"""Add an edge to the GLTF as a new primitive of the unique mesh"""
|
||||
vertices = np.array([[v[0], v[1], v[2]] for v in vertices_raw], dtype=np.float32)
|
||||
indices = np.array(list(map(lambda i: [i, i + 1], range(len(vertices) - 1))), dtype=np.uint32)
|
||||
tex_coord = np.array([])
|
||||
self._add_any(vertices, indices, tex_coord, mode=LINE_STRIP, material=1)
|
||||
self._add_any(vertices, indices, tex_coord, mode=LINE_STRIP, material="edge")
|
||||
|
||||
def add_vertex(self, vertex: Tuple[float, float, float]):
|
||||
"""Add a vertex to the GLTF as a new primitive of the unique mesh"""
|
||||
vertices = np.array([[vertex[0], vertex[1], vertex[2]]])
|
||||
indices = np.array([[0]], dtype=np.uint32)
|
||||
tex_coord = np.array([], dtype=np.float32)
|
||||
self._add_any(vertices, indices, tex_coord, mode=POINTS, material=2)
|
||||
self._add_any(vertices, indices, tex_coord, mode=POINTS, material="vertex")
|
||||
|
||||
def add_material(self, kind: str) -> int:
|
||||
"""It is important to use a different material for each primitive to be able to change them at runtime"""
|
||||
new_material: Material
|
||||
if kind == "face":
|
||||
new_material = Material(name="face", alphaCutoff=None, pbrMetallicRoughness=PbrMetallicRoughness(
|
||||
baseColorTexture=TextureInfo(index=0), baseColorFactor=[1, 1, 0.5, 1]))
|
||||
elif kind == "edge":
|
||||
new_material = Material(name="edge", alphaCutoff=None, pbrMetallicRoughness=PbrMetallicRoughness(
|
||||
baseColorFactor=[0, 0, 0.5, 1]))
|
||||
elif kind == "vertex":
|
||||
new_material = Material(name="vertex", alphaCutoff=None, pbrMetallicRoughness=PbrMetallicRoughness(
|
||||
baseColorFactor=[0.5, 0.5, 0.5, 1]))
|
||||
else:
|
||||
raise ValueError(f"Unknown material kind {kind}")
|
||||
self.gltf.materials.append(new_material)
|
||||
return len(self.gltf.materials) - 1
|
||||
|
||||
def _add_any(self, vertices: np.ndarray, indices: np.ndarray, tex_coord: np.ndarray, mode: int = TRIANGLES,
|
||||
material: int = 0):
|
||||
material: str = "face"):
|
||||
assert vertices.ndim == 2
|
||||
assert vertices.shape[1] == 3
|
||||
vertices = vertices.astype(np.float32)
|
||||
@@ -86,7 +97,7 @@ class GLTFMgr:
|
||||
if len(tex_coord) > 0 else Attributes(POSITION=accessor_base + 1),
|
||||
indices=accessor_base,
|
||||
mode=mode,
|
||||
material=material,
|
||||
material=self.add_material(material),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ if __name__ == "__main__":
|
||||
|
||||
# Add the CAD part of the logo to the server
|
||||
obj = build_logo()
|
||||
Shape(obj).export_stl(os.path.join(ASSETS_DIR, 'logo.stl'))
|
||||
# DEBUG: Shape(obj).export_stl(os.path.join(ASSETS_DIR, 'logo.stl'))
|
||||
show_object(obj, 'logo')
|
||||
|
||||
# Save the complete logo to a single GLB file
|
||||
|
||||
@@ -21,11 +21,11 @@ from gltf import GLTFMgr
|
||||
|
||||
def tessellate(
|
||||
ocp_shape: TopoDS_Shape,
|
||||
tolerance: float = 1e-3,
|
||||
tolerance: float = 0.1,
|
||||
angular_tolerance: float = 0.1,
|
||||
faces: bool = True,
|
||||
edges: bool = True,
|
||||
vertices: bool = True,
|
||||
vertices: bool = False,
|
||||
) -> GLTF2:
|
||||
"""Tessellate a whole shape into a list of triangle vertices and a list of triangle indices."""
|
||||
mgr = GLTFMgr()
|
||||
|
||||
Reference in New Issue
Block a user