Summary
During a feature implementation for a “Transparent Topography” button in Autodesk Forge Viewer v7.x, the expected ghosting behavior failed. The goal was to make FBX topography elements transparent while keeping Revit (RVT) and Navisworks (NWD/NWC) elements opaque.
The implementation relied on setGhosting(true) combined with isolate() on non-FBX elements. The result was inconsistent: sometimes FBX elements remained opaque, and sometimes the entire scene turned transparent. This occurred because the logic misunderstood the interaction between loaded models, isolation state, and ghosting context. The fix requires using explicit opacity controls via setThemingColor or managing model visibility for the specific FBX model, rather than relying on ghosting.
Root Cause
The root cause is a misinterpretation of the setGhosting API behavior in a multi-model environment. setGhosting(true) is designed to make non-isolated elements transparent. However, it operates strictly within the context of the currently active model or the aggregate isolation state.
The specific failures in the code logic were:
- Context Mismatch: The code calls
isolate()with a list of DbIds, but these IDs span across different models (RVT and FBX). Theisolatemethod does not natively support cross-model ID lists without setting the model context first. - Model-Specific Ghosting:
setGhostingapplies transparency to elements that are not isolated in the current model. If the FBX model is a separateAutodesk.Viewing.Model, callingisolate()on RVT IDs might not isolate them in the FBX model’s context, causing ghosting to apply globally or not at all. - Phong Material Override: The
viewer.impl.invalidate(true)call forces a render, but it does not override the PhongMaterial defaults for ghosting if the viewer’s internal state thinks the isolated elements are the “foreground” and the FBX elements are “background” (or vice versa).
Why This Happens in Real Systems
- Aggregate Viewer State: Forge Viewer aggregates geometry from multiple models. Commands like
isolateandghostingoperate on a scene graph, not a database list. - Legacy vs. Modern APIs: The
setGhostingAPI was designed primarily for single-model workflows (e.g., NWD only) or standard isolation tasks. Using it to target specific sub-sets of data (like “FBX only”) in a mixed pipeline often yields race conditions. - Z-Fighting and Sorting: When mixing FBX topography with RVT BIM data, render sorting changes. If ghosting is applied via the generic pipeline, FBX geometry (often simpler meshes) might not respect the transparency depth buffer correctly compared to complex BIM elements.
Real-World Impact
- UX Confusion: Users see an “Opaque” button that creates a “Ghosted” mess, or a button that does nothing.
- Visual Artifacts: Inconsistent alpha blending leads to Z-fighting where transparent topography flickers over opaque walls, or becomes invisible.
- Performance: Triggering
invalidate(true)combined with rapid model isolation changes can spike CPU usage as the geometry tree is traversed repeatedly.
Example or Code
The original logic failed because it tried to manipulate the scene via aggregation. The correct logic uses explicit RGBA values for theming to force transparency, ignoring the isolate/ghosting state for specific IDs.
setTopographyTransparent(fbxDbIds, allDbIds) {
console.log('[ColorManager] Applying TRANSPARENT mode (Explicit Opacity)');
if (fbxDbIds.length === 0) {
console.warn('[ColorManager] No .FBX elements to make transparent');
return;
}
// 1. Ensure we are operating on the specific FBX model for the IDs
// Note: We assume the FBX model is already loaded and active or tracked.
// If fbxDbIds are from a separate model instance, we must pass that model to setThemingColor.
// 2. Define a transparent RGBA color (Alpha < 1.0)
// Example: Semi-transparent grey
const transparentColor = {
r: 200,
g: 200,
b: 200,
a: 0.3 // {
// setThemingColor applies to a specific model instance
this.viewer.setThemingColor(dbId, transparentColor, fbxModel);
});
// 4. Ensure the rest of the scene is opaque (or reset theming for non-FBX)
// If you need to "hide" or "dim" non-FBX elements, you can loop them or use isolate.
// But to keep them fully opaque and distinct, clearing theming for the OTHER model is safer.
const rvtModel = getRvtModelInstance();
this.viewer.clearThemingColors(rvtModel);
// 5. Reset isolation to ensure visibility
this.viewer.isolate([]); // Show all
// 6. Apply visibility override (Crucial for ghosting fallback)
// If you MUST use ghosting, apply it ONLY to the FBX model's nodes,
// but explicit theming is superior for "Topography Overlay" use cases.
console.log(`[ColorManager] Applied explicit transparency to ${fbxDbIds.length} FBX elements`);
}
How Senior Engineers Fix It
Senior engineers recognize that setGhosting is a scene-level global toggle, not a targeted ID modifier. To fix this, they:
- Abandon
setGhostingfor targeted requirements: They switch tosetThemingColorwith ana(alpha) value less than 1.0. This forces the WebGL renderer to handle the transparency specifically for those nodes. - Isolate by Model, not by ID: Instead of
viewer.isolate(listOfIds), they might useviewer.isolateModel(model)or simply ensure the FBX model is visually distinct using the alpha channel. - Use
setDisplayMode: If the goal is to see topography “ghosted” behind structure, they might switch the RVT model to “Wireframe” or “Hidden Line” while keeping the FBX model “Shaded with Edges” and applying a generic transparency to the FBX model’s material. - Validate Model Context: They ensure that
dbIdlookups are performed against the correctModelobject, because DbIds are only unique per model, not globally in a multi-model session.
Why Juniors Miss It
- Documentation Trap: The documentation says
setGhosting(true)makes non-isolated elements transparent. Juniors read this as “If I isolate non-FBX, FBX becomes transparent.” They miss the nuance that this applies to the active context and relies on the viewer’s internal isolate stack, which gets messy with multiple models. - Over-reliance High-Level APIs: They assume
isolate()handles all visibility logic. They don’t realize thatisolateis about showing/hiding, whilesetGhostingis a specific rendering effect that may not play nice with custom ID lists. - Alpha vs. Ghosting: Juniors often don’t realize that
setThemingColoraccepts an alpha channel. They stick to the “Ghosting” feature because the name sounds correct for the task (“Ghosting” = “see-through”), missing the more robust “Transparency” tool.