lots of fixes and finding new problems

This commit is contained in:
Yeicor
2024-02-19 21:19:26 +01:00
parent c9e8bde9ca
commit ba74b97bd9
5 changed files with 57 additions and 25 deletions

View File

@@ -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) {

View File

@@ -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>

View File

@@ -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),
)
)

View File

@@ -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

View 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()