Initial import of NODEDC BIM Viewer
This commit is contained in:
+271
@@ -0,0 +1,271 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>xeokit BIM Viewer</title>
|
||||
<link rel="stylesheet" href="./lib/fontawesome-free-5.11.2-web/css/all.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../dist/xeokit-bim-viewer.css" type="text/css" />
|
||||
<link rel="stylesheet" href="./css/style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<input type="checkbox" id="explorer_toggle" />
|
||||
<label for="explorer_toggle" class="xeokit-i18n explorer_toggle_label xeokit-btn fas fa-2x fa-sitemap"
|
||||
data-xeokit-i18ntip="toolbar.toggleExplorer" data-tippy-content="Toggle explorer"></label>
|
||||
<input type="checkbox" id="inspector_toggle" />
|
||||
<label id="inspector_toggle_label" for="inspector_toggle"
|
||||
class="xeokit-i18n inspector_toggle_label xeokit-btn fas fa-info-circle fa-2x"
|
||||
data-xeokit-i18ntip="toolbar.toggleProperties" data-tippy-content="Toggle properties"></label>
|
||||
<div id="myExplorer"></div>
|
||||
<div id="myToolbar"></div>
|
||||
<div id="myInspector"></div>
|
||||
<div id="myViewer">
|
||||
<canvas id="myCanvas"></canvas>
|
||||
<canvas id="myNavCubeCanvas"></canvas>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
<!-- Tooltips libraries -->
|
||||
<script src="./lib/popper.js"></script>
|
||||
<script src="./lib/tippy.js"></script>
|
||||
|
||||
<script type="module">
|
||||
|
||||
import { Server, BIMViewer, LocaleService } from "../dist/xeokit-bim-viewer.es.js";
|
||||
|
||||
import { messages as localeMessages } from "../dist/messages.js";
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
const requestParams = getRequestParams();
|
||||
const locale = requestParams.locale || "en";
|
||||
const projectId = requestParams.projectId;
|
||||
|
||||
if (!projectId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const openExplorer = requestParams.openExplorer;
|
||||
setExplorerOpen(openExplorer === "true");
|
||||
|
||||
const enableEditModels = (requestParams.enableEditModels === "true");
|
||||
|
||||
const server = new Server({
|
||||
dataDir: requestParams.dataDir || "./data"
|
||||
});
|
||||
|
||||
const bimViewer = new BIMViewer(server, {
|
||||
localeService: new LocaleService({
|
||||
messages: localeMessages,
|
||||
locale: locale
|
||||
}),
|
||||
enableMeasurements: true,
|
||||
canvasElement: document.getElementById("myCanvas"), // WebGL canvas
|
||||
keyboardEventsElement: document, // Optional, defaults to document
|
||||
explorerElement: document.getElementById("myExplorer"), // Left panel
|
||||
toolbarElement: document.getElementById("myToolbar"), // Toolbar
|
||||
inspectorElement: document.getElementById("myInspector"), // Right panel
|
||||
navCubeCanvasElement: document.getElementById("myNavCubeCanvas"),
|
||||
busyModelBackdropElement: document.getElementById("myViewer"),
|
||||
enableEditModels: enableEditModels
|
||||
});
|
||||
|
||||
bimViewer.localeService.on("updated", () => {
|
||||
const localizedElements = document.querySelectorAll('.xeokit-i18n');
|
||||
localizedElements.forEach((localizedElement) => {
|
||||
if (localizedElement.dataset.xeokitI18n) {
|
||||
localizedElement.innerText = bimViewer.localeService.translate(localizedElement.dataset.xeokitI18n);
|
||||
}
|
||||
if (localizedElement.dataset.xeokitI18ntip) {
|
||||
const translation = bimViewer.localeService.translate(localizedElement.dataset.xeokitI18ntip);
|
||||
if (translation) {
|
||||
localizedElement.dataset.tippyContent = bimViewer.localeService.translate(localizedElement.dataset.xeokitI18ntip);
|
||||
}
|
||||
}
|
||||
if (localizedElement.dataset.tippyContent) {
|
||||
if (localizedElement._tippy) {
|
||||
localizedElement._tippy.setContent(localizedElement.dataset.tippyContent);
|
||||
} else {
|
||||
tippy(localizedElement, {
|
||||
appendTo: "parent",
|
||||
zIndex: 1000000,
|
||||
allowHTML: true
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
bimViewer.setConfigs({
|
||||
"showSpaces": false, // Default
|
||||
"selectedGlowThrough": true,
|
||||
"highlightGlowThrough": true,
|
||||
"dtxEnabled": true // Enable data texture scene representation for models - may be slow on low-spec GPUs
|
||||
});
|
||||
|
||||
bimViewer.on("openExplorer", () => {
|
||||
setExplorerOpen(true);
|
||||
});
|
||||
|
||||
bimViewer.on("openInspector", () => {
|
||||
setInspectorOpen(true);
|
||||
});
|
||||
|
||||
bimViewer.on("addModel", (event) => { // "Add" selected in Models tab's context menu
|
||||
console.log("addModel: " + JSON.stringify(event, null, "\t"));
|
||||
});
|
||||
|
||||
bimViewer.on("editModel", (event) => { // "Edit" selected in Models tab's context menu
|
||||
console.log("editModel: " + JSON.stringify(event, null, "\t"));
|
||||
});
|
||||
|
||||
bimViewer.on("deleteModel", (event) => { // "Delete" selected in Models tab's context menu
|
||||
console.log("deleteModel: " + JSON.stringify(event, null, "\t"));
|
||||
});
|
||||
|
||||
const viewerConfigs = requestParams.configs;
|
||||
if (viewerConfigs) {
|
||||
const configNameVals = viewerConfigs.split(",");
|
||||
for (let i = 0, len = configNameVals.length; i < len; i++) {
|
||||
const configNameValStr = configNameVals[i];
|
||||
const configNameVal = configNameValStr.split(":");
|
||||
const configName = configNameVal[0];
|
||||
const configVal = configNameVal[1];
|
||||
bimViewer.setConfig(configName, configVal);
|
||||
}
|
||||
}
|
||||
|
||||
bimViewer.loadProject(projectId, () => {
|
||||
const modelId = requestParams.modelId;
|
||||
if (modelId) {
|
||||
bimViewer.loadModel(modelId);
|
||||
}
|
||||
const tab = requestParams.tab;
|
||||
if (tab) {
|
||||
bimViewer.openTab(tab);
|
||||
}
|
||||
watchHashParams();
|
||||
},
|
||||
(errorMsg) => {
|
||||
console.error(errorMsg);
|
||||
});
|
||||
|
||||
function watchHashParams() {
|
||||
let lastHash = "";
|
||||
window.setInterval(() => {
|
||||
const currentHash = window.location.hash;
|
||||
if (currentHash !== lastHash) {
|
||||
parseHashParams();
|
||||
lastHash = currentHash;
|
||||
}
|
||||
}, 400);
|
||||
}
|
||||
|
||||
function parseHashParams() {
|
||||
const params = getHashParams();
|
||||
const actionsStr = params.actions;
|
||||
if (!actionsStr) {
|
||||
return;
|
||||
}
|
||||
const actions = actionsStr.split(",");
|
||||
if (actions.length === 0) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0, len = actions.length; i < len; i++) {
|
||||
const action = actions[i];
|
||||
switch (action) {
|
||||
case "focusObject":
|
||||
const objectId = params.objectId;
|
||||
if (!objectId) {
|
||||
console.error("Param expected for `focusObject` action: 'objectId'");
|
||||
break;
|
||||
}
|
||||
bimViewer.setAllObjectsSelected(false);
|
||||
bimViewer.setObjectsSelected([objectId], true);
|
||||
bimViewer.flyToObject(objectId, () => {
|
||||
// FIXME: Showing objects in tabs involves scrolling the HTML within the tabs - disable until we know how to scroll the correct DOM element. Otherwise, that function works OK
|
||||
|
||||
// bimViewer.showObjectInObjectsTab(objectId);
|
||||
// bimViewer.showObjectInClassesTab(objectId);
|
||||
// bimViewer.showObjectInStoreysTab(objectId);
|
||||
});
|
||||
break;
|
||||
case "focusObjects":
|
||||
const objectIds = params.objectIds;
|
||||
if (!objectIds) {
|
||||
console.error("Param expected for `focusObjects` action: 'objectIds'");
|
||||
break;
|
||||
}
|
||||
const objectIdArray = objectIds.split(",");
|
||||
bimViewer.setAllObjectsSelected(false);
|
||||
bimViewer.setObjectsSelected(objectIdArray, true);
|
||||
bimViewer.viewFitObjects(objectIdArray, () => {
|
||||
});
|
||||
break;
|
||||
case "clearFocusObjects":
|
||||
bimViewer.setAllObjectsSelected(false);
|
||||
bimViewer.viewFitAll();
|
||||
// TODO: view fit nothing?
|
||||
break;
|
||||
case "openTab":
|
||||
const tabId = params.tabId;
|
||||
if (!tabId) {
|
||||
console.error("Param expected for `openTab` action: 'tabId'");
|
||||
break;
|
||||
}
|
||||
bimViewer.openTab(tabId);
|
||||
break;
|
||||
default:
|
||||
console.error("Action not supported: '" + action + "'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setExplorerOpen(explorerOpen) {
|
||||
const toggle = document.getElementById("explorer_toggle");
|
||||
if (toggle) {
|
||||
toggle.checked = explorerOpen;
|
||||
}
|
||||
}
|
||||
|
||||
function setInspectorOpen(inspectorOpen) {
|
||||
const toggle = document.getElementById("inspector_toggle");
|
||||
if (toggle) {
|
||||
toggle.checked = inspectorOpen;
|
||||
}
|
||||
}
|
||||
|
||||
function getRequestParams() {
|
||||
const vars = {};
|
||||
window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, (m, key, value) => {
|
||||
vars[key] = value;
|
||||
});
|
||||
return vars;
|
||||
}
|
||||
|
||||
function getHashParams() {
|
||||
const hashParams = {};
|
||||
let e;
|
||||
const a = /\+/g; // Regex for replacing addition symbol with a space
|
||||
const r = /([^&;=]+)=?([^&;]*)/g;
|
||||
const d = function (s) {
|
||||
return decodeURIComponent(s.replace(a, " "));
|
||||
};
|
||||
const q = window.location.hash.substring(1);
|
||||
while (e = r.exec(q)) {
|
||||
hashParams[d(e[1])] = d(e[2]);
|
||||
}
|
||||
return hashParams;
|
||||
}
|
||||
|
||||
window.bimViewer = bimViewer;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user