133 lines
4.2 KiB
TypeScript
133 lines
4.2 KiB
TypeScript
import { describe, expect, it } from "@jest/globals";
|
||
import * as THREE from "three";
|
||
import {
|
||
filterHighlightHelperNames,
|
||
isHighlightHelperObjectName,
|
||
setMeshHighlight,
|
||
} from "@/lib/3d/engine-highlight-resources";
|
||
|
||
describe("engine-highlight-resources", () => {
|
||
it("应识别高亮辅助节点名", () => {
|
||
expect(isHighlightHelperObjectName("__highlight_fill__")).toBe(true);
|
||
expect(isHighlightHelperObjectName("__highlight_edges__")).toBe(true);
|
||
expect(isHighlightHelperObjectName("cad_panel_001")).toBe(false);
|
||
});
|
||
|
||
it("应在层级名中剔除高亮辅助节点", () => {
|
||
const hierarchyNames = [
|
||
"__highlight_fill__",
|
||
"cad_panel_left",
|
||
"__highlight_edges__",
|
||
"root_group",
|
||
];
|
||
|
||
expect(filterHighlightHelperNames(hierarchyNames)).toEqual([
|
||
"cad_panel_left",
|
||
"root_group",
|
||
]);
|
||
});
|
||
|
||
it("应仅创建结构线高亮,不创建面填充", () => {
|
||
const mesh = new THREE.Mesh(
|
||
new THREE.BoxGeometry(100, 50, 18),
|
||
new THREE.MeshStandardMaterial({ color: 0x808080 }),
|
||
);
|
||
mesh.name = "cad_panel_left";
|
||
|
||
setMeshHighlight(mesh, true);
|
||
|
||
const fillMesh = mesh.children.find(
|
||
(child) => child.name === "__highlight_fill__",
|
||
) as THREE.Mesh | undefined;
|
||
const edgeLines = mesh.children.find(
|
||
(child) => child.name === "__highlight_edges__",
|
||
) as THREE.LineSegments | undefined;
|
||
|
||
expect(fillMesh).toBeUndefined();
|
||
expect(edgeLines).toBeDefined();
|
||
|
||
const edgeMaterial = edgeLines?.material as THREE.LineBasicMaterial;
|
||
|
||
expect(edgeMaterial.color.getHex()).toBe(0x008d74);
|
||
expect(edgeMaterial.opacity).toBeCloseTo(1, 2);
|
||
expect(edgeMaterial.depthTest).toBe(true);
|
||
expect(edgeMaterial.depthWrite).toBe(false);
|
||
expect(edgeLines?.renderOrder).toBe(3001);
|
||
|
||
setMeshHighlight(mesh, false);
|
||
|
||
expect(
|
||
mesh.children.find((child) => child.name === "__highlight_fill__"),
|
||
).toBeUndefined();
|
||
expect(
|
||
mesh.children.find((child) => child.name === "__highlight_edges__"),
|
||
).toBeUndefined();
|
||
});
|
||
|
||
it("若存在旧版 fill helper,应在高亮时被清理", () => {
|
||
const mesh = new THREE.Mesh(
|
||
new THREE.BoxGeometry(40, 40, 4),
|
||
new THREE.MeshStandardMaterial({ color: 0x666666 }),
|
||
);
|
||
mesh.name = "cad_panel_cleanup";
|
||
|
||
const legacyFill = new THREE.Mesh(
|
||
mesh.geometry,
|
||
new THREE.MeshBasicMaterial({ color: 0x0a84ff, transparent: true }),
|
||
);
|
||
legacyFill.name = "__highlight_fill__";
|
||
mesh.add(legacyFill);
|
||
|
||
setMeshHighlight(mesh, true);
|
||
|
||
expect(
|
||
mesh.children.find((child) => child.name === "__highlight_fill__"),
|
||
).toBeUndefined();
|
||
expect(
|
||
mesh.children.find((child) => child.name === "__highlight_edges__"),
|
||
).toBeDefined();
|
||
});
|
||
|
||
it("高亮结构线应贴合原始几何,不应因缩放产生偏移", () => {
|
||
const geometry = new THREE.BoxGeometry(100, 50, 18);
|
||
geometry.translate(1000, 0, 0);
|
||
const mesh = new THREE.Mesh(
|
||
geometry,
|
||
new THREE.MeshStandardMaterial({ color: 0x808080 }),
|
||
);
|
||
mesh.name = "cad_panel_offset_check";
|
||
|
||
setMeshHighlight(mesh, true);
|
||
|
||
const edgeLines = mesh.children.find(
|
||
(child) => child.name === "__highlight_edges__",
|
||
) as THREE.LineSegments | undefined;
|
||
expect(edgeLines).toBeDefined();
|
||
expect(edgeLines?.scale.x).toBeCloseTo(1, 6);
|
||
expect(edgeLines?.scale.y).toBeCloseTo(1, 6);
|
||
expect(edgeLines?.scale.z).toBeCloseTo(1, 6);
|
||
|
||
geometry.computeBoundingBox();
|
||
const sourceCenter = geometry.boundingBox?.getCenter(new THREE.Vector3());
|
||
const edgeCenter = new THREE.Box3()
|
||
.setFromObject(edgeLines as THREE.Object3D)
|
||
.getCenter(new THREE.Vector3());
|
||
expect(sourceCenter).toBeDefined();
|
||
expect(edgeCenter.x).toBeCloseTo(sourceCenter!.x, 6);
|
||
expect(edgeCenter.y).toBeCloseTo(sourceCenter!.y, 6);
|
||
expect(edgeCenter.z).toBeCloseTo(sourceCenter!.z, 6);
|
||
});
|
||
|
||
it("不应给高亮辅助节点重复叠加高亮", () => {
|
||
const helperMesh = new THREE.Mesh(
|
||
new THREE.BoxGeometry(20, 20, 2),
|
||
new THREE.MeshBasicMaterial(),
|
||
);
|
||
helperMesh.name = "__highlight_fill__";
|
||
|
||
setMeshHighlight(helperMesh, true);
|
||
|
||
expect(helperMesh.children).toHaveLength(0);
|
||
});
|
||
});
|