added support for non-dto meshes to meshCache

This commit is contained in:
azykov@mail.ru 2026-05-26 19:53:54 +03:00
parent 4d09a47118
commit f16f45fad8
No known key found for this signature in database
6 changed files with 40 additions and 32 deletions

View File

@ -1,5 +1,4 @@
import { useSceneHelper } from "../helpers/hooks/useSceneHelper"; import { useSceneHelper } from "../helpers/hooks/useSceneHelper";
import { model } from "../model/model";
import { state } from "../state/root"; import { state } from "../state/root";
import { ThreeView, type ThreeViewEventArgs, type ThreeViewMouseEventArgs } from "./ThreeView"; import { ThreeView, type ThreeViewEventArgs, type ThreeViewMouseEventArgs } from "./ThreeView";

View File

@ -25,7 +25,7 @@ export type FaceHitResult = BaseHitResult & {
export type EdgeHitResult = BaseHitResult & { export type EdgeHitResult = BaseHitResult & {
kind: 'edge', kind: 'edge',
id?: Id, id: Id,
faceId: Id, faceId: Id,
} }

View File

@ -1,4 +1,4 @@
import type { Object3D, OrthographicCamera, PerspectiveCamera, Scene, Vector2Like, WebGLRenderer } from "three"; import { Mesh, MeshStandardMaterial, PlaneGeometry, type Object3D, type OrthographicCamera, type PerspectiveCamera, type Scene, type Vector2Like, type WebGLRenderer } from "three";
import { MeshCache } from "../layers/meshCache"; import { MeshCache } from "../layers/meshCache";
import { GeometryCache } from "../layers/geometryCache"; import { GeometryCache } from "../layers/geometryCache";
import type { Id } from "../types"; import type { Id } from "../types";
@ -37,6 +37,15 @@ export class SceneHelper {
for (const mesh of meshes) for (const mesh of meshes)
this.meshes.addMesh(mesh.faceId, mesh); this.meshes.addMesh(mesh.faceId, mesh);
} }
const plane = new Mesh(
new PlaneGeometry(14, 14),
new MeshStandardMaterial({ color: 0x080810 }),
);
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
this.meshes.addRawMesh('xyplane', plane);
} }
public get hints(): ThreeHintDisplay { public get hints(): ThreeHintDisplay {
@ -84,7 +93,9 @@ export class SceneHelper {
if (!this.meshes) if (!this.meshes)
throw new Error('SceneHelper is not initiallized'); throw new Error('SceneHelper is not initiallized');
return this.meshes.meshes; return [
...this.meshes.meshes,
];
} }
public updateMouseFrustumHint() { public updateMouseFrustumHint() {

View File

@ -4,24 +4,20 @@ import type { MeshDto } from '../backend/dto';
export class GeometryCache { export class GeometryCache {
private readonly items = new Map<string, THREE.BufferGeometry>(); private readonly items = new Map<string, THREE.BufferGeometry>();
private key(id: string, lod: number) { public has(id: string): boolean {
return `${id}:${lod}`; return this.items.has(id);
} }
public has(id: string, lod: number): boolean { public get(id: string): THREE.BufferGeometry | undefined {
return this.items.has(this.key(id, lod)); return this.items.get(id);
} }
public get(id: string, lod: number): THREE.BufferGeometry | undefined { public set(id: string, payload: THREE.BufferGeometry) {
return this.items.get(this.key(id, lod)); this.items.set(id, payload);
} }
public set(id: string, lod: number, payload: THREE.BufferGeometry) { public createMesh(id: string, dto: MeshDto): THREE.BufferGeometry {
this.items.set(this.key(id, lod), payload); let geometry = this.get(id);
}
public getOrCreate(id: string, lod: number, dto: MeshDto): THREE.BufferGeometry {
let geometry = this.get(id, lod);
if (geometry) if (geometry)
return geometry; return geometry;
@ -32,16 +28,16 @@ export class GeometryCache {
geometry.setAttribute('normal', new THREE.BufferAttribute(dto.normals, 3)); geometry.setAttribute('normal', new THREE.BufferAttribute(dto.normals, 3));
geometry.setIndex(new THREE.BufferAttribute(dto.indices, 1)); geometry.setIndex(new THREE.BufferAttribute(dto.indices, 1));
this.set(id, lod, geometry); this.set(id, geometry);
return geometry; return geometry;
} }
unset(id: string, lod: number) { unset(id: string) {
const geometry = this.get(id, lod); const geometry = this.get(id);
if (geometry) { if (geometry) {
geometry.dispose(); geometry.dispose();
this.items.delete(this.key(id, lod)); this.items.delete(id);
} }
} }
} }

View File

@ -67,19 +67,25 @@ export class MeshCache {
return Object.values(this.items); return Object.values(this.items);
} }
// Called when FE scene graph syncs from BE public addMesh(id: string, dto: MeshDto) {
addMesh(id: string, dto: MeshDto) {
if (this.items[id]) if (this.items[id])
return; return;
const geo = this.cache.getOrCreate(id, 0, dto); const geometry = this.cache.createMesh(id, dto);
const mesh = new THREE.Mesh(geometry, this.baseMaterial);
const geoVCount = geo.attributes.position.count; this.addRawMesh(id, mesh);
geo.setAttribute('selected', new THREE.BufferAttribute(new Float32Array(geoVCount), 1));
const mesh = new THREE.Mesh(geo, this.baseMaterial);
mesh.userData = dto mesh.userData = dto
mesh.userData.vertexIds = dto.loop.map((v) => v.vertex); mesh.userData.vertexIds = dto.loop.map((v) => v.vertex);
}
public addRawMesh(id: string, mesh: THREE.Mesh) {
if (this.items[id])
return;
const geoVCount = mesh.geometry.attributes.position.count;
mesh.geometry.setAttribute('selected', new THREE.BufferAttribute(new Float32Array(geoVCount), 1));
this.scene.add(mesh); this.scene.add(mesh);
this.items[id] = mesh; this.items[id] = mesh;
@ -111,7 +117,7 @@ export class MeshCache {
else else
mesh.material.dispose(); mesh.material.dispose();
this.cache.unset((mesh.userData as MeshDto).faceId, 0); this.cache.unset((mesh.userData as MeshDto).faceId);
delete (this.items[id]); delete (this.items[id]);
} }

View File

@ -1,11 +1,7 @@
import verb from "verb-nurbs";
import type { Solid, Surface } from "../types/brep"; import type { Solid, Surface } from "../types/brep";
import { db } from "../backend/db"; import { db } from "../backend/db";
import { NURBSBuilder } from "./NURBSBuilder"; import { NURBSBuilder } from "./NURBSBuilder";
const verbAny = verb as any;
export type Point = [number, number, number]; export type Point = [number, number, number];
export type Tri = [number, number, number]; export type Tri = [number, number, number];
export type UV = [number, number]; export type UV = [number, number];