add support for selecting vertices

This commit is contained in:
Yeicor
2024-02-24 23:38:58 +01:00
parent b3160fe3d3
commit dfff9720dc
3 changed files with 17 additions and 9 deletions

View File

@@ -19,7 +19,7 @@ let selectionEnabled = ref(false);
let selectedMaterials = defineModel<Array<Intersection<MObject3D>>>({default: []}); let selectedMaterials = defineModel<Array<Intersection<MObject3D>>>({default: []});
let hasListener = false; let hasListener = false;
let mouseDownAt: [number, number] | null = null; let mouseDownAt: [number, number] | null = null;
let selectFilter = ref('Faces'); let selectFilter = ref('Any');
const ray_caster = new Raycaster(); const ray_caster = new Raycaster();
let selectionMoveListener = (event: MouseEvent) => { let selectionMoveListener = (event: MouseEvent) => {
@@ -51,13 +51,17 @@ let selectionListener = (event: MouseEvent) => {
ray_caster.ray.direction.copy( ray_caster.ray.direction.copy(
scene.getTarget().clone().add(scene.target.position).sub((scene as any).camera.position).normalize()); scene.getTarget().clone().add(scene.target.position).sub((scene as any).camera.position).normalize());
} }
console.log('NDC', ndcCoords, 'Camera', (scene as any).camera, 'Ray', ray_caster.ray); // console.log('NDC', ndcCoords, 'Camera', (scene as any).camera, 'Ray', ray_caster.ray);
const hits = ray_caster.intersectObject(scene, true); const hits = ray_caster.intersectObject(scene, true);
console.log(hits)
let hit = hits.find((hit) => { let hit = hits.find((hit) => {
let isFace = hit.faceIndex !== null; const kind = hit.object.type
return hit.object.visible && !hit.object.userData.noHit && isFace == (selectFilter.value === 'Faces'); const kindOk = (selectFilter.value === 'Any') ||
((kind === 'Mesh' || kind === 'SkinnedMesh') && selectFilter.value === 'Faces') ||
(kind === 'Line' && selectFilter.value === 'Edges') ||
(kind === 'Points' && selectFilter.value === 'Vertices');
return hit.object.visible && !hit.object.userData.noHit && kindOk;
}) as Intersection<MObject3D> | undefined; }) as Intersection<MObject3D> | undefined;
console.log('Hit', hit)
if (!hit) { if (!hit) {
deselectAll(); deselectAll();
} else { } else {
@@ -137,7 +141,8 @@ function toggleSelection() {
</v-btn> </v-btn>
<v-tooltip :text="'Select Only ' + selectFilter" :open-on-click="false"> <v-tooltip :text="'Select Only ' + selectFilter" :open-on-click="false">
<template v-slot:activator="{ props }"> <template v-slot:activator="{ props }">
<v-select v-bind="props" class="select-only" variant="underlined" :items="['Faces', 'Edges', 'Vertices']" <!-- TODO: Keyboard shortcuts for fast selection (& other tools) -->
<v-select v-bind="props" class="select-only" variant="underlined" :items="['Any', 'Faces', 'Edges', 'Vertices']"
v-model="selectFilter"/> v-model="selectFilter"/>
</template> </template>
</v-tooltip> </v-tooltip>

View File

@@ -36,7 +36,11 @@ const LicensesDialogContent = defineAsyncComponent({
let props = defineProps<{ viewer: InstanceType<typeof ModelViewerWrapper> | null }>(); let props = defineProps<{ viewer: InstanceType<typeof ModelViewerWrapper> | null }>();
let selection: Ref<Array<Intersection<typeof MObject3D>>> = ref([]); let selection: Ref<Array<Intersection<typeof MObject3D>>> = ref([]);
let selectionFaceCount = () => selection.value.filter((s) => s.object.type == "Mesh" || s.object.type == "SkinnedMesh").length
let selectionEdgeCount = () => selection.value.filter((s) => s.object.type == "Line").length
let selectionVertexCount = () => selection.value.filter((s) => s.object.type == "Points").length
function syncOrthoCamera(force: boolean) { function syncOrthoCamera(force: boolean) {
let scene = props.viewer?.scene; let scene = props.viewer?.scene;
@@ -93,7 +97,6 @@ async function downloadSceneGlb() {
async function openGithub() { async function openGithub() {
window.open('https://github.com/yeicor-3d/yet-another-cad-viewer', '_blank') window.open('https://github.com/yeicor-3d/yet-another-cad-viewer', '_blank')
} }
</script> </script>
<template> <template>
@@ -111,7 +114,7 @@ async function openGithub() {
<svg-icon type="mdi" :path="mdiCrosshairsGps"/> <svg-icon type="mdi" :path="mdiCrosshairsGps"/>
</v-btn> </v-btn>
<v-divider/> <v-divider/>
<h5>Selection ({{ selection.filter((s) => s.face).length }}F {{ selection.filter((s) => !s.face).length }}E ?V)</h5> <h5>Selection ({{ selectionFaceCount() }}F {{ selectionEdgeCount() }}E {{ selectionVertexCount() }}V)</h5>
<selection-component :viewer="props.viewer" v-model="selection"/> <selection-component :viewer="props.viewer" v-model="selection"/>
<v-divider/> <v-divider/>
<v-spacer></v-spacer> <v-spacer></v-spacer>

View File

@@ -61,7 +61,7 @@ class GLTFMgr:
baseColorFactor=[0, 0, 0.5, 1])) baseColorFactor=[0, 0, 0.5, 1]))
elif kind == "vertex": elif kind == "vertex":
new_material = Material(name="vertex", alphaCutoff=None, pbrMetallicRoughness=PbrMetallicRoughness( new_material = Material(name="vertex", alphaCutoff=None, pbrMetallicRoughness=PbrMetallicRoughness(
baseColorFactor=[0, 0.2, 0, 1])) baseColorFactor=[0, 0.3, 0.3, 1]))
else: else:
raise ValueError(f"Unknown material kind {kind}") raise ValueError(f"Unknown material kind {kind}")
self.gltf.materials.append(new_material) self.gltf.materials.append(new_material)