Fix color persistence using metadata and source mesh ID fallback
Colors were being lost during resize operations because toDiagramEntity
extracted color from material.diffuseColor, which is no longer used after
the emissiveColor rendering optimization (commit c7887d7).
Root Causes:
1. Rendering system changed from diffuseColor to emissiveColor
2. Material properties unreliable when materials are shared
3. Material-based extraction broke when properties changed
Solution - Three-Tier Fallback Chain:
Priority 1: mesh.metadata.color
- Most reliable, explicitly set during mesh creation
- Already populated by buildMeshFromDiagramEntity (line 163)
Priority 2: Extract from mesh.sourceMesh.id (InstancedMesh)
- Tool mesh IDs encode color: "tool-BOX-#FF0000"
- Preserves original tool color regardless of material state
- Works for all instanced diagram meshes
Priority 3: Material properties (backwards compatibility)
- Checks emissiveColor first (current system)
- Falls back to diffuseColor (old system)
- Handles both StandardMaterial and PBRMaterial
- Maintains compatibility with non-instanced meshes
Changes:
- Import InstancedMesh from @babylonjs/core
- Replace direct material extraction with fallback chain
- Parse tool mesh ID to extract hex color code
- Normalize colors to lowercase
- Add null checks for safe color extraction
Benefits:
✅ Independent of material system changes
✅ Works with shared materials
✅ Preserves original tool colors
✅ Backwards compatible
✅ More reliable than material-only extraction
Files modified:
- toDiagramEntity.ts: Implement fallback chain for color extraction
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
af52d5992c
commit
43100ad650
@ -1,4 +1,4 @@
|
|||||||
import {AbstractMesh} from "@babylonjs/core";
|
import {AbstractMesh, InstancedMesh} from "@babylonjs/core";
|
||||||
import {DiagramEntity} from "../types/diagramEntity";
|
import {DiagramEntity} from "../types/diagramEntity";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {v4 as uuidv4} from 'uuid';
|
import {v4 as uuidv4} from 'uuid';
|
||||||
@ -25,20 +25,44 @@ export function toDiagramEntity(mesh: AbstractMesh): DiagramEntity {
|
|||||||
entity.from = mesh?.metadata?.from;
|
entity.from = mesh?.metadata?.from;
|
||||||
entity.to = mesh?.metadata?.to;
|
entity.to = mesh?.metadata?.to;
|
||||||
entity.scale = vectoxys(mesh.scaling);
|
entity.scale = vectoxys(mesh.scaling);
|
||||||
if (mesh.material) {
|
|
||||||
|
// Extract color using fallback chain for reliability
|
||||||
|
if (mesh.metadata?.color) {
|
||||||
|
// Priority 1: Explicit metadata color (most reliable)
|
||||||
|
entity.color = mesh.metadata.color;
|
||||||
|
} else if (mesh instanceof InstancedMesh && mesh.sourceMesh?.id) {
|
||||||
|
// Priority 2: Extract from tool mesh ID (e.g., "tool-BOX-#FF0000")
|
||||||
|
const toolId = mesh.sourceMesh.id;
|
||||||
|
const parts = toolId.split('-');
|
||||||
|
if (parts.length >= 3 && parts[0] === 'tool') {
|
||||||
|
const color = parts.slice(2).join('-'); // Handle colors with dashes
|
||||||
|
if (color.startsWith('#')) {
|
||||||
|
entity.color = color.toLowerCase(); // Normalize to lowercase
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (mesh.material) {
|
||||||
|
// Priority 3: Fallback to material extraction (backwards compatibility)
|
||||||
switch (mesh.material.getClassName()) {
|
switch (mesh.material.getClassName()) {
|
||||||
case "StandardMaterial":
|
case "StandardMaterial":
|
||||||
entity.color = (mesh.material as any).diffuseColor.toHexString();
|
const stdMat = mesh.material as any;
|
||||||
|
const stdColor = stdMat.emissiveColor || stdMat.diffuseColor;
|
||||||
|
if (stdColor) {
|
||||||
|
entity.color = stdColor.toHexString()?.toLowerCase();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "PBRMaterial":
|
case "PBRMaterial":
|
||||||
entity.color = (mesh.material as any).albedoColor.toHexString();
|
const pbrMat = mesh.material as any;
|
||||||
|
const pbrColor = pbrMat.emissiveColor || pbrMat.albedoColor;
|
||||||
|
if (pbrColor) {
|
||||||
|
entity.color = pbrColor.toHexString()?.toLowerCase();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (entity.template != "#object-template") {
|
if (entity.template != "#object-template") {
|
||||||
logger.error("toDiagramEntity: mesh.material is null");
|
logger.error("toDiagramEntity: mesh.material is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user