🚀 Auto-deploy: melhoria no snap e medição AR em 11/06/2026 14:55:19
This commit is contained in:
@@ -11,7 +11,7 @@ import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
||||
import { mainCameraRef, mainControlsRef, viewAnim, calibration, pushModelFaceNormal, computeCalibrationQuaternion, subscribeCalibration } from './viewCubeBus';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
function getColorForMaterialName(name: string): string {
|
||||
export function getColorForMaterialName(name: string): string {
|
||||
if (!name) return '#a1a1aa';
|
||||
let hash = 0;
|
||||
for (let i = 0; i < name.length; i++) {
|
||||
@@ -208,7 +208,7 @@ function GLBModel({ sceneModel, isActive }: { sceneModel: SceneModel; isActive:
|
||||
const setActive = useModelStore((s) => s.setActiveModel);
|
||||
const selectionMode = useModelStore((s) => s.selectionMode);
|
||||
const measureMode = useModelStore((s) => s.measureMode);
|
||||
const ifcMaterialColors = useModelStore((s) => s.ifcMaterialColors);
|
||||
const ifcColorMode = useModelStore((s) => s.ifcColorMode);
|
||||
const fineTuning = sceneModel.fineTuning;
|
||||
|
||||
// Re-render when calibration state changes (so calQuat resets to identity during the flow).
|
||||
@@ -277,8 +277,11 @@ function GLBModel({ sceneModel, isActive }: { sceneModel: SceneModel; isActive:
|
||||
} else {
|
||||
const root = findElementRoot(child);
|
||||
const matName = root?.userData?.materialName;
|
||||
if (ifcMaterialColors && matName) {
|
||||
const descName = root?.userData?.properties?.description || root?.userData?.description;
|
||||
if (ifcColorMode === 'material' && matName) {
|
||||
mat.color.set(getColorForMaterialName(matName));
|
||||
} else if (ifcColorMode === 'description' && descName) {
|
||||
mat.color.set(getColorForMaterialName(descName));
|
||||
} else {
|
||||
// Tint with the per-model color (subtle)
|
||||
mat.color.set(sceneModel.color);
|
||||
@@ -304,7 +307,7 @@ function GLBModel({ sceneModel, isActive }: { sceneModel: SceneModel; isActive:
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [scene, opacity, renderMode, checklist, wireframeColor, wireframeThickness, edgeThresholdAngle, sceneModel.color, measureMode, ifcMaterialColors]);
|
||||
}, [scene, opacity, renderMode, checklist, wireframeColor, wireframeThickness, edgeThresholdAngle, sceneModel.color, measureMode, ifcColorMode]);
|
||||
|
||||
const rotXRad = (fineTuning.rotX * Math.PI) / 180;
|
||||
const rotYRad = (fineTuning.rotY * Math.PI) / 180;
|
||||
|
||||
+38
-11
@@ -24,7 +24,7 @@ const Index = () => {
|
||||
const [showLanding, setShowLanding] = useState(false);
|
||||
|
||||
const [converting, setConverting] = useState(false);
|
||||
const { model, addModel, models, maxModels, xrSupported, setXrSupported, ifcMaterialColors, setIfcMaterialColors } = useModelStore();
|
||||
const { model, addModel, models, maxModels, xrSupported, setXrSupported, ifcColorMode, setIfcColorMode } = useModelStore();
|
||||
|
||||
// --- Painel de Logs Remotos em Tempo Real ---
|
||||
const [debugLogs, setDebugLogs] = useState<{ level: 'info' | 'warn' | 'error'; message: string; timestamp: string; data?: unknown }[]>([]);
|
||||
@@ -265,21 +265,48 @@ const Index = () => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Toggle IFC Material Colors */}
|
||||
<div className="flex items-center justify-between rounded-lg border border-border bg-card/50 p-3.5">
|
||||
{/* Escolha do Filtro de Cores (IFC) */}
|
||||
<div className="flex flex-col gap-2 rounded-lg border border-border bg-card/50 p-3.5">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<Label htmlFor="ifc-mat-colors-toggle" className="text-xs font-semibold cursor-pointer text-foreground">
|
||||
Cores por Material (IFC)
|
||||
<Label className="text-xs font-semibold text-foreground">
|
||||
Modo de Cores (IFC)
|
||||
</Label>
|
||||
<p className="text-[10px] text-muted-foreground">
|
||||
{ifcMaterialColors ? 'Cores baseadas no material do IFC' : 'Cores padrão da cena'}
|
||||
Escolha como aplicar cores aos elementos do modelo
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
id="ifc-mat-colors-toggle"
|
||||
checked={ifcMaterialColors}
|
||||
onCheckedChange={setIfcMaterialColors}
|
||||
/>
|
||||
<div className="grid grid-cols-3 gap-1 bg-slate-950/40 p-1 rounded-md border border-border/40 mt-1">
|
||||
<button
|
||||
onClick={() => setIfcColorMode('none')}
|
||||
className={`py-1.5 px-2 text-[10px] font-medium rounded transition-all ${
|
||||
ifcColorMode === 'none'
|
||||
? 'bg-primary text-primary-foreground shadow-sm'
|
||||
: 'text-muted-foreground hover:bg-slate-900/60 hover:text-foreground'
|
||||
}`}
|
||||
>
|
||||
Cor Única
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setIfcColorMode('material')}
|
||||
className={`py-1.5 px-2 text-[10px] font-medium rounded transition-all ${
|
||||
ifcColorMode === 'material'
|
||||
? 'bg-primary text-primary-foreground shadow-sm'
|
||||
: 'text-muted-foreground hover:bg-slate-900/60 hover:text-foreground'
|
||||
}`}
|
||||
>
|
||||
Material
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setIfcColorMode('description')}
|
||||
className={`py-1.5 px-2 text-[10px] font-medium rounded transition-all ${
|
||||
ifcColorMode === 'description'
|
||||
? 'bg-primary text-primary-foreground shadow-sm'
|
||||
: 'text-muted-foreground hover:bg-slate-900/60 hover:text-foreground'
|
||||
}`}
|
||||
>
|
||||
Descrição
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Demo buttons */}
|
||||
|
||||
+12
-2
@@ -23,7 +23,7 @@ import { ControllerLocomotion } from '@/components/three/ControllerLocomotion';
|
||||
import { useDevKit } from '@/devkit/useDevKit';
|
||||
import { DevPanel } from '@/devkit/DevPanel';
|
||||
import { FakeControllers } from '@/devkit/FakeControllers';
|
||||
import { VisibilityApplier } from '@/components/three/ModelViewer';
|
||||
import { VisibilityApplier, findElementRoot, getColorForMaterialName } from '@/components/three/ModelViewer';
|
||||
import { registerModelLocalGroup, unregisterModelLocalGroup } from '@/lib/modelTransforms';
|
||||
import { parseIFCtoThree } from '@/lib/convertIFC';
|
||||
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
||||
@@ -104,6 +104,7 @@ function XRModel({ sceneModel }: { sceneModel: import('@/stores/useModelStore').
|
||||
const edgeThresholdAngle = useModelStore((s) => s.edgeThresholdAngle);
|
||||
const checklist = useModelStore((s) => s.checklist);
|
||||
const measureMode = useModelStore((s) => s.measureMode);
|
||||
const ifcColorMode = useModelStore((s) => s.ifcColorMode);
|
||||
|
||||
const modelInfo = useMemo(() => {
|
||||
if (!scene) return { size: new THREE.Vector3(), center: new THREE.Vector3() };
|
||||
@@ -158,10 +159,19 @@ function XRModel({ sceneModel }: { sceneModel: import('@/stores/useModelStore').
|
||||
mat.color.setHSL(0, 0.7, 0.5);
|
||||
} else if (allApproved) {
|
||||
mat.color.setHSL(0.38, 0.7, 0.45);
|
||||
} else {
|
||||
const root = findElementRoot(child);
|
||||
const matName = root?.userData?.materialName;
|
||||
const descName = root?.userData?.properties?.description || root?.userData?.description;
|
||||
if (ifcColorMode === 'material' && matName) {
|
||||
mat.color.set(getColorForMaterialName(matName));
|
||||
} else if (ifcColorMode === 'description' && descName) {
|
||||
mat.color.set(getColorForMaterialName(descName));
|
||||
} else {
|
||||
mat.color.set(sceneModel.color);
|
||||
}
|
||||
}
|
||||
}
|
||||
mat.needsUpdate = true;
|
||||
}
|
||||
});
|
||||
@@ -181,7 +191,7 @@ function XRModel({ sceneModel }: { sceneModel: import('@/stores/useModelStore').
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [scene, opacity, renderMode, checklist, wireframeColor, wireframeThickness, edgeThresholdAngle, sceneModel.color, measureMode]);
|
||||
}, [scene, opacity, renderMode, checklist, wireframeColor, wireframeThickness, edgeThresholdAngle, sceneModel.color, measureMode, ifcColorMode]);
|
||||
|
||||
const rotXRad = (fineTuning.rotX * Math.PI) / 180;
|
||||
const rotYRad = (fineTuning.rotY * Math.PI) / 180;
|
||||
|
||||
@@ -95,6 +95,9 @@ function loadVisibility(fileName: string): { hidden: Set<string>; isolated: Set<
|
||||
}
|
||||
|
||||
const IFC_MAT_COLORS_KEY = 'tsxr_ifc_mat_colors_v1';
|
||||
const IFC_COLOR_MODE_KEY = 'tsxr_ifc_color_mode_v1';
|
||||
export type IFCColorMode = 'none' | 'material' | 'description';
|
||||
|
||||
function loadIfcMaterialColors(): boolean {
|
||||
try {
|
||||
const raw = localStorage.getItem(IFC_MAT_COLORS_KEY);
|
||||
@@ -106,6 +109,21 @@ function saveIfcMaterialColors(enabled: boolean) {
|
||||
try { localStorage.setItem(IFC_MAT_COLORS_KEY, String(enabled)); } catch (e) { /* ignore */ }
|
||||
}
|
||||
|
||||
function loadIfcColorMode(): IFCColorMode {
|
||||
try {
|
||||
const raw = localStorage.getItem(IFC_COLOR_MODE_KEY);
|
||||
if (raw === 'none' || raw === 'material' || raw === 'description') {
|
||||
return raw as IFCColorMode;
|
||||
}
|
||||
const legacy = localStorage.getItem(IFC_MAT_COLORS_KEY);
|
||||
if (legacy === 'false') return 'none';
|
||||
} catch (e) { /* ignore */ }
|
||||
return 'material';
|
||||
}
|
||||
function saveIfcColorMode(mode: IFCColorMode) {
|
||||
try { localStorage.setItem(IFC_COLOR_MODE_KEY, mode); } catch (e) { /* ignore */ }
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface ScaleRatio {
|
||||
@@ -372,6 +390,8 @@ interface ModelStore {
|
||||
|
||||
ifcMaterialColors: boolean;
|
||||
setIfcMaterialColors: (enabled: boolean) => void;
|
||||
ifcColorMode: IFCColorMode;
|
||||
setIfcColorMode: (mode: IFCColorMode) => void;
|
||||
|
||||
xrRig: THREE.Group | null;
|
||||
setXRRig: (rig: THREE.Group | null) => void;
|
||||
@@ -815,7 +835,18 @@ export const useModelStore = create<ModelStore>((set, get) => ({
|
||||
ifcMaterialColors: loadIfcMaterialColors(),
|
||||
setIfcMaterialColors: (enabled: boolean) => {
|
||||
saveIfcMaterialColors(enabled);
|
||||
set({ ifcMaterialColors: enabled });
|
||||
set((state) => {
|
||||
const mode = enabled ? 'material' : 'none';
|
||||
saveIfcColorMode(mode);
|
||||
return { ifcMaterialColors: enabled, ifcColorMode: mode };
|
||||
});
|
||||
},
|
||||
ifcColorMode: loadIfcColorMode(),
|
||||
setIfcColorMode: (mode: IFCColorMode) => {
|
||||
saveIfcColorMode(mode);
|
||||
const enabled = mode === 'material';
|
||||
saveIfcMaterialColors(enabled);
|
||||
set({ ifcColorMode: mode, ifcMaterialColors: enabled });
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user