_createViewer() {
console.log ('Iaf3DViewer _createViewer');
if (!this.props.view3d.enable) return;
const { fileSet, model, authToken, wsUri, settings } = this.props;
let viewerPromise;
let streamCutoffScale = 0.5;
this._viewerInitialized = true;
if (settings && settings.hasOwnProperty("streamCutoffScale"))
streamCutoffScale = parseFloat(settings.streamCutoffScale);
// this.props.openNotification ("The model is being loaded (" + this.props.graphicsResources.views[0].title + ")");
NotificationStore.notifyModelIsBeingLoaded(this, 0);
const perfLogger = new IafPerfLogger("viewer.defaultView3d");
// RRP:- Duplicate as it is called from modelStructure ready.
// this.initalizeModelComposer();
viewerPromise = this._hwvManager.createRemoteViewer(
this.evmElementIdManager.getEvmUuid(EvmUtils.EVMMode.View3d),
model,
fileSet,
authToken,
wsUri,
streamCutoffScale,
0
);
viewerPromise.then((viewer) => {
this._viewer = viewer;
this._boundingBoxMarkup = new IafBoundingBoxMarkup(this._viewer);
this.graphicsResources = this.props.graphicsResources;
this._viewer.graphicsResources = this.graphicsResources;
this.graphicsResources.setviewer(this, this._viewer);
this._isolateZoomHelper = new ViewerIsolateZoomHelper(viewer, this);
// Once the viewer is instantiated, we can set the state to true to have the React update the DOM
this.setState({
hwvInstantiated: true,
});
//use our own Select Operator
this.selectOperator = new SelectOperator(
this._viewer,
this._viewer.noteTextManager,
this
);
this.selectOperatorId = this._viewer.registerCustomOperator(
this.selectOperator
);
this.iafCuttingPlanesUtils = new IafCuttingPlanesUtils(this._viewer
, this.newToolbarElement ? this.newToolbarElement.current : undefined);
this._viewer.operatorManager.set(this.selectOperatorId, 1);
this.measurementManager = new IafMeasurementManager(this._viewer,"Measurement3d",this.projectId);
// Storing the callback in its own function to avoid registering a bound callback
// (more difficult to unregister that in HC)
//let parent = this;
this._viewer.setCallbacks({
// Add new callbacks at the top, so that they don't accidentally replace the earlier ones
// 10-12-23 ATK MK-149 Added viewer callbacks for error handling
modelStructureHeaderParsed: async (fileName, fileType) => {
console.log ('viewer.callbacks.modelStructureHeaderParsed'
, '/fileName', fileName
, '/fileType', fileType
);
},
missingModel: async (modelPath) => {
console.log ('viewer.callbacks.missingModel'
, '/modelPath', modelPath
);
},
modelLoadBegin: async () => {
console.log ('viewer.callbacks.modelLoadBegin'
);
},
modelLoadFailure: async (modelName, reason, error) => {
// TOBE: Reviewed for performace projects.
NotificationStore.notifyModelIsMissing(this, modelName, true);
console.error('viewer.callbacks.modelLoadFailure'
, '/modelName', modelName
, '/reason', reason
, '/error', error
);
},
modelLoaded: async (modelRootIds, source) => {
console.log ('viewer.callbacks.modelLoaded'
, '/modelRootIds', modelRootIds
, '/source', source
);
},
modelStructureLoadBegin: async () => {
console.log ('viewer.callbacks.modelStructureLoadBegin'
);
},
modelStructureLoadEnd: async () => {
console.log ('viewer.callbacks.modelStructureLoadEnd'
);
},
modelStructureParseBegin: async () => {
console.log ('viewer.callbacks.modelStructureParseBegin'
);
},
modelSwitchStart: async (clearOnly) => {
console.log ('viewer.callbacks.modelSwitchStart'
, '/clearOnly', clearOnly
);
},
modelSwitched: async (clearOnly, modelRootIds) => {
console.log ('viewer.callbacks.modelSwitched'
, '/clearOnly', clearOnly
, '/modelRootIds', modelRootIds
);
},
viewLoaded: async (view) => {
console.log ('viewer.callbacks.viewLoaded'
, '/view', view
);
},
websocketConnectionClosed: async () => {
console.log ('viewer.callbacks.websocketConnectionClosed'
);
},
webGlContextLost: async () => {
console.log ('viewer.callbacks.webGlContextLost'
);
},
streamingActivated: () => {
// if (!this.state.isModelStructureReady) this.setModelIsLoaded(this._viewer, false);
},
streamingDeactivated: async () => {
// if (!this.state.isModelStructureReady) this.setModelIsLoaded(this._viewer, true);
},
addCuttingSection: async (cuttingSection /* : Communicator.CuttingSection */) => {
console.log ('viewer.Callbacks.addCuttingSection', '/cuttingSection', cuttingSection);
},
removeCuttingSection: async () => {
console.log ('viewer.Callbacks.removeCuttingSection');
},
cuttingPlaneDragStart: async (cuttingSection /* : Communicator.CuttingSection */,
planeIndex /* : number */) => {
console.log ('viewer.Callbacks.cuttingPlaneDragStart',
'/cuttingSection', cuttingSection,
'/planeIndex', cuttingSection.planeIndex);
},
cuttingPlaneDragEnd: async (cuttingSection /* : Communicator.CuttingSection */,
planeIndex /* : number */) => {
// console.log ('viewer.Callbacks.cuttingPlaneDragEnd',
// '/cuttingSection', cuttingSection,
// '/cuttingSection.planeIndex.logical', cuttingSection.planeIndex.logical,
// '/planeIndex', cuttingSection.planeIndex,
// '/d', cuttingSection.getPlane(0).d);
this.iafCuttingPlanesUtils.onDragCuttingPlaneFromGraphics(cuttingSection);
},
cuttingPlaneDrag: async (cuttingSection /* : Communicator.CuttingSection */,
planeIndex /* : number */) => {
// console.log ('viewer.Callbacks.cuttingPlaneDrag',
// '/cuttingSection', cuttingSection,
// '/cuttingSection.planeIndex.logical', cuttingSection.planeIndex.logical,
// '/planeIndex', cuttingSection.planeIndex,
// '/d', cuttingSection.getPlane(0).d
// );
this.iafCuttingPlanesUtils.onDragCuttingPlaneFromGraphics(cuttingSection);
},
// ATK: To Do: Get rid of the following as it appears redundant
// sceneReady: () => {
// const camera = this._viewer.view.getCamera();
// // set saved intial camera position
// if (this.props.settings.initialCameraPosition) {
// let newCamera = window.Communicator.Camera.fromJson(
// this.props.settings.initialCameraPosition
// );
// this._viewer.view.setCamera(newCamera);
// }
// },
subtreeLoaded: (modelRootIds, source) => console.log('subtreeLoaded', source, modelRootIds),
subtreeDeleted: (modelRootIds) => console.log('subtreeDeleted', modelRootIds),
modelStructureReady: async () => {
perfLogger.end();
iafCallbackModelStructureReady(this);
},
measurementValueSet: async (m) => {
const { multiplier } = this.state;
let mValue = m.getMeasurementValue();
let uMultiplier = m.getUnitMultiplier();
let mmUnits = mValue * uMultiplier;
let newUnitMul = multiplier;
m.setUnitMultiplier(newUnitMul);
m._measurementValue = mmUnits / newUnitMul;
m.setMeasurementText(
Communicator.Util.formatWithUnit(m._measurementValue, newUnitMul)
);
},
selectionArray: async (selectionEvents) => {
if (selectionEvents.length === 0) return;
//selectionEvents only represents the latest select event
//use viewer.selectionManager.getResults to get current selected nodes
// or selectionEvents[0]._selection._nodeId
let id = this.getActiveSelectionNodeId(this._viewer, selectionEvents);
let elementId = id ? this.getClosestElementIds([id]) : undefined;
// let csdlOffset = this._viewer.model.getNodeIdOffset(id);
if (!id || !_.size(elementId)) {
console.log ('Viewer.selectionArray.3D'
, 'Invalid callback'
, '!id || !_.size(elementId)'
, '/id', JSON.stringify(id)
// , '/csdlOffset', csdlOffset
, '/elementId', JSON.stringify(elementId)
);
// HSK PLAT-4891: Bug - 3D Text Markup is editable only on creation
// this.markupManager && this.markupManager.drawTextOperator.selectTextboxItem(id);
NotificationStore.notifyNoBimAssociationFound(this);
return;
}
console.log ('Viewer.selectionArray.3D'
, '/id', id
, '/this.prevSelection', JSON.stringify(this.prevSelection)
, '/elementId', JSON.stringify(elementId)
);
return this.handleElementGraphicsSelection(elementId, false);
},
sceneReady: async () => {
console.log ('viewer.callbacks.sceneReady');
let camPos, target, upVec;
/*camPos = new window.Communicator.Point3(0, 200, 400);
target = new window.Communicator.Point3(0, 1, 0);
upVec = new window.Communicator.Point3(0.2, 1, 0.5);
const defaultCam = window.Communicator.Camera.create(
camPos, target, upVec, 1, 720, 720, 0.01);
this._viewer.view.setCamera(defaultCam);*/
// Background color for viewers
this._viewer.view.setBackgroundColor(
new window.Communicator.Color(252, 252, 252),
new window.Communicator.Color(230, 230, 230)
);
//check
// if opacity works
this.setNodeSelectionColor(this._viewer, bdSelectColor);
this.setNodeSelectionOutlineColor(this._viewer, bdSelectColor);
this.setNodeElementSelectionColor(this._viewer, faceSelectColor);
this.setNodeElementSelectionOutlineColor(this._viewer, lineSelectColor);
//PLAT-575: turn off parent selecting for now as it's not a helpful feature now
this._viewer.selectionManager.setSelectParentIfSelected(false);
//Default draw mode to Shaded rather than WireframeOnShaded
this._viewer.view.setDrawMode(Communicator.DrawMode.Shaded);
//if silhouetted edges are enabled, be sure to disable them in glass mode
this._viewer.view.setSilhouetteEnabled(true);
// set ambient occlusion mode and radius
this._viewer.view.setAmbientOcclusionEnabled(true);
this._viewer.view.setAmbientOcclusionRadius(0.01);
//this._viewer.view.setBloomEnabled(true)
//this._viewer.view.setBloomIntensityScale(0.1)
try {
// Calling initializeOperators to set up navigation operators
await this.initializeOperators();
console.log('Navigation operators successfully initialized.');
} catch (error) {
console.error('Error initializing navigation operators:', error.message);
}
// if(this._drawMode === IafDrawMode.Glass)
// this.setXrayModeSettings()
// object of IafSavedViews class
this.savedViewsManager = new IafSavedViews();
// Create Navigation cube
if(this.props.isShowNavCube || typeof this.props.isShowNavCube === "undefined"){
await this._viewer.view.getNavCube().enable();
await this._viewer.view
.getNavCube()
.setAnchor(window.Communicator.OverlayAnchor.LowerRightCorner);
}
if (
this.isElementThemingIdExists(this.props.colorGroups) ||
this.props?.sliceElementIds?.length > 0
)
this.forceUpdateViewerElements = true;
this.isSceneReady = true;
console.log("Web Viewer has been initialized.");
},
timeout: () => {
console.log ('viewer.callbacks.timeout');
if (
window.confirm(
"This page timed out due to inactivity. Press OK to refresh."
)
) {
location.reload();
}
},
camera: (camera) => {
iafCallbackCamera(this, camera);
},
// HSK PLAT-4861: UX - Move markup options to under Measurements (Annotations)
measurementCreated: (measurement) => {
!this.markupManager.repeatLastMode && this._viewer.operatorManager.set(this.selectOperatorId, IafOperatorUtils.IafOperatorPosition.Operation);
}
});
// window.addEventListener("resize", this.onResize);
// this.evmElementIdManager.getEvmElementById(EvmUtils.EVMMode.View3d).addEventListener("contextmenu", (e) => contextmenu(e, this));
// added click listner to close active submenu when clicked on viewer
// this.evmElementIdManager.getEvmElementById(EvmUtils.EVMMode.View3d).addEventListener("mousedown", (e) => mousedown(this));
// document.addEventListener("click", (e) => {this.contextMenu.style.display = "none";})
});
}
createRemoteViewer(containerId, model, fileSet , authToken, wsUri, streamCutoffScale, defaultViewIndex) {
let uri = wsUri + '/graphicssvc?fileSetId=' + fileSet._id +
'&nsfilter=' + model._namespaces[0] +
'&token=' + authToken + '&serverVersion=4'
// let fileName = fileSet && _.size(fileSet._files) > 0 ? fileSet._files[0]._fileName : model._name + '.scz'
let fileName = IafUtils.buildFileName(model, fileSet, defaultViewIndex ? defaultViewIndex : 0);
let viewerPromise = new Promise((resolve) => {
let params = {
containerId: containerId,
streamMode: window.Communicator.StreamingMode.All,
rendererType: window.Communicator.RendererType.Client,
streamCutoffScale: streamCutoffScale,
//memoryLimit: 512,
//empty: true
endpointUri: uri,
boundingPreviewMode: Communicator.BoundingPreviewMode.None,
// model: window.Communicator.EmptyModelName//model._name + '.scz'
model: fileName//model._name + '.scz'
};
console.log ('ViewerManager.createRemoteViewer', params);
// PLG-1263: EVM 1.0 - Multiple instances of viewer - Hack to wait for div to be created
IafUtils.waitForElement(containerId).then ((container) => {
let _viewer = new window.Communicator.WebViewer(params);
_viewer.start();
resolve(_viewer);
})
})
return viewerPromise;
}
2023_SP1 usign hoops communicator