🚀 Auto-deploy: melhoria no snap e medição AR em 22/05/2026 21:20:32

This commit is contained in:
2026-05-22 21:20:32 +00:00
parent 63ad53edfb
commit c85dc85936
6 changed files with 181 additions and 78 deletions
+20 -6
View File
@@ -23,6 +23,7 @@ import { useDevKit } from '@/devkit/useDevKit';
import { DevPanel } from '@/devkit/DevPanel';
import { FakeControllers } from '@/devkit/FakeControllers';
import { VisibilityApplier } from '@/components/three/ModelViewer';
import { registerModelLocalGroup, unregisterModelLocalGroup } from '@/lib/modelTransforms';
import { parseIFCtoThree } from '@/lib/convertIFC';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
@@ -99,6 +100,13 @@ function XRModel({ sceneModel }: { sceneModel: import('@/stores/useModelStore').
}, [sceneModel.url, sceneModel.fileName]);
const ref = useRef<THREE.Group>(null);
useEffect(() => {
const g = ref.current;
if (!g) return;
registerModelLocalGroup(sceneModel.id, g);
return () => unregisterModelLocalGroup(sceneModel.id, g);
}, [sceneModel.id]);
const fineTuning = sceneModel.fineTuning;
const opacity = useModelStore((s) => s.opacity);
const renderMode = useModelStore((s) => s.renderMode);
@@ -106,6 +114,7 @@ function XRModel({ sceneModel }: { sceneModel: import('@/stores/useModelStore').
const wireframeThickness = useModelStore((s) => s.wireframeThickness);
const edgeThresholdAngle = useModelStore((s) => s.edgeThresholdAngle);
const checklist = useModelStore((s) => s.checklist);
const measureMode = useModelStore((s) => s.measureMode);
const modelInfo = useMemo(() => {
if (!scene) return { size: new THREE.Vector3(), center: new THREE.Vector3() };
@@ -145,12 +154,13 @@ function XRModel({ sceneModel }: { sceneModel: import('@/stores/useModelStore').
const materials = Array.isArray(child.material) ? child.material : [child.material];
materials.forEach((mat: THREE.Material) => {
if (mat instanceof THREE.MeshStandardMaterial) {
if (renderMode === 'edges') {
if (renderMode === 'edges' && !measureMode) {
mat.visible = false;
} else {
mat.visible = true;
mat.transparent = opacity < 1;
mat.opacity = opacity;
const targetOpacity = measureMode ? 0.25 : opacity;
mat.transparent = targetOpacity < 1;
mat.opacity = targetOpacity;
mat.wireframe = renderMode === 'wireframe';
if (renderMode === 'wireframe') {
mat.wireframeLinewidth = wireframeThickness;
@@ -167,16 +177,19 @@ function XRModel({ sceneModel }: { sceneModel: import('@/stores/useModelStore').
}
});
if (renderMode === 'edges' && child.geometry) {
if ((renderMode === 'edges' || measureMode) && child.geometry) {
const edgesGeo = new THREE.EdgesGeometry(child.geometry, edgeThresholdAngle);
const lineMat = new THREE.LineBasicMaterial({ color: wireframeColor, linewidth: wireframeThickness });
const lineMat = new THREE.LineBasicMaterial({
color: measureMode ? '#00f3ff' : wireframeColor,
linewidth: measureMode ? 2 : wireframeThickness,
});
const lineSegments = new THREE.LineSegments(edgesGeo, lineMat);
lineSegments.userData.__edgeLine = true;
child.add(lineSegments);
}
}
});
}, [scene, opacity, renderMode, checklist, wireframeColor, wireframeThickness, edgeThresholdAngle, sceneModel.color]);
}, [scene, opacity, renderMode, checklist, wireframeColor, wireframeThickness, edgeThresholdAngle, sceneModel.color, measureMode]);
const rotXRad = (fineTuning.rotX * Math.PI) / 180;
const rotYRad = (fineTuning.rotY * Math.PI) / 180;
@@ -457,6 +470,7 @@ function XRSnapHandler() {
// Click to measure
useEffect(() => {
if (!measureMode) return;
if (gl.xr.isPresenting) return; // Ignora cliques simulados do DOM quando o WebXR está ativo
const onClick = (e: MouseEvent) => {
if (snapPoint) {
addMeasurePoint({ x: snapPoint.x, y: snapPoint.y, z: snapPoint.z });