diff --git a/assets/icons/measure.svg b/assets/icons/measure.svg
new file mode 100644
index 0000000..df29db6
--- /dev/null
+++ b/assets/icons/measure.svg
@@ -0,0 +1,66 @@
+
+
\ No newline at end of file
diff --git a/sandbox/embed_edges.html b/sandbox/embed_edges.html
index 1d4df26..c2040cc 100644
--- a/sandbox/embed_edges.html
+++ b/sandbox/embed_edges.html
@@ -71,6 +71,7 @@
+
diff --git a/sandbox/embed_selfhost_errors.html b/sandbox/embed_selfhost_errors.html
index dfee977..a74f59d 100644
--- a/sandbox/embed_selfhost_errors.html
+++ b/sandbox/embed_selfhost_errors.html
@@ -71,6 +71,7 @@
+
diff --git a/sandbox/embed_selfhost_externallibs.html b/sandbox/embed_selfhost_externallibs.html
index 3306850..f12633b 100644
--- a/sandbox/embed_selfhost_externallibs.html
+++ b/sandbox/embed_selfhost_externallibs.html
@@ -71,6 +71,7 @@
+
diff --git a/sandbox/embed_selfhost_fullscreen.html b/sandbox/embed_selfhost_fullscreen.html
index c5df813..061b8ac 100644
--- a/sandbox/embed_selfhost_fullscreen.html
+++ b/sandbox/embed_selfhost_fullscreen.html
@@ -70,6 +70,7 @@
+
diff --git a/sandbox/embed_selfhost_manual.html b/sandbox/embed_selfhost_manual.html
index 77260e5..110afed 100644
--- a/sandbox/embed_selfhost_manual.html
+++ b/sandbox/embed_selfhost_manual.html
@@ -71,6 +71,7 @@
+
diff --git a/sandbox/embed_selfhost_multiple.html b/sandbox/embed_selfhost_multiple.html
index cacbee9..dab88ab 100644
--- a/sandbox/embed_selfhost_multiple.html
+++ b/sandbox/embed_selfhost_multiple.html
@@ -71,6 +71,7 @@
+
diff --git a/sandbox/embed_selfhost_single.html b/sandbox/embed_selfhost_single.html
index 29ff348..be2c242 100644
--- a/sandbox/embed_selfhost_single.html
+++ b/sandbox/embed_selfhost_single.html
@@ -70,6 +70,7 @@
+
+
+
@@ -115,6 +116,7 @@
+
diff --git a/website/index.html b/website/index.html
index 6570473..0ba7512 100644
--- a/website/index.html
+++ b/website/index.html
@@ -79,6 +79,7 @@
+
@@ -117,6 +118,7 @@
+
diff --git a/website/o3dv/css/O3DVIcons/O3DVIcons.woff b/website/o3dv/css/O3DVIcons/O3DVIcons.woff
index 2046bcb..491c5b4 100644
Binary files a/website/o3dv/css/O3DVIcons/O3DVIcons.woff and b/website/o3dv/css/O3DVIcons/O3DVIcons.woff differ
diff --git a/website/o3dv/css/icons.css b/website/o3dv/css/icons.css
index 1b32aa5..c2c804a 100644
--- a/website/o3dv/css/icons.css
+++ b/website/o3dv/css/icons.css
@@ -1,6 +1,6 @@
@font-face {
font-family: "O3DVIcons";
- src: url("O3DVIcons/O3DVIcons.woff?9f1e775b55726eccac0336790d9d9b2f") format("woff");
+ src: url("O3DVIcons/O3DVIcons.woff?a94a3e222e39f4785c00ccb77bce301e") format("woff");
}
i[class^="icon-"]:before, i[class*=" icon-"]:before {
@@ -86,48 +86,51 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
.icon-materials:before {
content: "\f118";
}
-.icon-meshes:before {
+.icon-measure:before {
content: "\f119";
}
-.icon-missing_files:before {
+.icon-meshes:before {
content: "\f11a";
}
-.icon-model:before {
+.icon-missing_files:before {
content: "\f11b";
}
-.icon-open_url:before {
+.icon-model:before {
content: "\f11c";
}
-.icon-open:before {
+.icon-open_url:before {
content: "\f11d";
}
-.icon-settings:before {
+.icon-open:before {
content: "\f11e";
}
-.icon-share:before {
+.icon-settings:before {
content: "\f11f";
}
-.icon-theme:before {
+.icon-share:before {
content: "\f120";
}
-.icon-tree_mesh:before {
+.icon-theme:before {
content: "\f121";
}
-.icon-tree_view:before {
+.icon-tree_mesh:before {
content: "\f122";
}
-.icon-twitter:before {
+.icon-tree_view:before {
content: "\f123";
}
-.icon-up_y:before {
+.icon-twitter:before {
content: "\f124";
}
-.icon-up_z:before {
+.icon-up_y:before {
content: "\f125";
}
-.icon-visible:before {
+.icon-up_z:before {
content: "\f126";
}
-.icon-warning:before {
+.icon-visible:before {
content: "\f127";
}
+.icon-warning:before {
+ content: "\f128";
+}
diff --git a/website/o3dv/css/sidebar.css b/website/o3dv/css/sidebar.css
index 57bc6ee..7ab7083 100644
--- a/website/o3dv/css/sidebar.css
+++ b/website/o3dv/css/sidebar.css
@@ -46,6 +46,12 @@ div.ov_sidebar_content
overflow: auto;
}
+div.ov_sidebar_section
+{
+ margin: 10px 0px;
+ overflow: auto;
+}
+
div.ov_sidebar_content div.ov_sidebar_settings_content
{
margin-bottom: 20px;
@@ -83,6 +89,17 @@ div.ov_sidebar_content div.ov_sidebar_settings_padded
overflow: hidden;
}
+div.ov_sidebar_content div.ov_sidebar_measure_name
+{
+ font-weight: bold;
+ margin-bottom: 5px;
+}
+
+div.ov_sidebar_content div.ov_sidebar_measure_value
+{
+ margin-bottom: 10px;
+}
+
div.ov_sidebar_content button.pcr-button
{
width: 30px;
diff --git a/website/o3dv/js/featureset.js b/website/o3dv/js/featureset.js
index 118c951..64ac4bf 100644
--- a/website/o3dv/js/featureset.js
+++ b/website/o3dv/js/featureset.js
@@ -1,3 +1,4 @@
OV.FeatureSet =
{
+ MeasureTool : false
};
diff --git a/website/o3dv/js/navigator.js b/website/o3dv/js/navigator.js
index 801c0f0..cb3601e 100644
--- a/website/o3dv/js/navigator.js
+++ b/website/o3dv/js/navigator.js
@@ -64,11 +64,7 @@ OV.Navigator = class
this.panelSet.Init ({
onResize : () => {
- if (this.panelSet.IsPanelsVisible ()) {
- OV.ShowDomElement (this.splitterDiv);
- } else {
- OV.HideDomElement (this.splitterDiv);
- }
+ OV.ShowDomElement (this.splitterDiv, this.panelSet.IsPanelsVisible ());
this.callbacks.onResize ();
},
onShowHidePanels : (show) => {
diff --git a/website/o3dv/js/navigatormeshespanel.js b/website/o3dv/js/navigatormeshespanel.js
index 6d1be07..b1126b1 100644
--- a/website/o3dv/js/navigatormeshespanel.js
+++ b/website/o3dv/js/navigatormeshespanel.js
@@ -157,15 +157,10 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel
buttons.flatList.iconDiv.classList.add ('selected');
buttons.treeView.iconDiv.classList.remove ('selected');
}
- if (showTree && isHierarchical) {
- OV.ShowDomElement (buttons.separator);
- OV.ShowDomElement (buttons.expandAll.div);
- OV.ShowDomElement (buttons.collapseAll.div);
- } else {
- OV.HideDomElement (buttons.separator);
- OV.HideDomElement (buttons.expandAll.div);
- OV.HideDomElement (buttons.collapseAll.div);
- }
+ let showExpandButtons = showTree && isHierarchical;
+ OV.ShowDomElement (buttons.separator, showExpandButtons);
+ OV.ShowDomElement (buttons.expandAll.div, showExpandButtons);
+ OV.ShowDomElement (buttons.collapseAll.div, showExpandButtons);
}
function UpdateView (panel, importResult, isHierarchical)
diff --git a/website/o3dv/js/panelset.js b/website/o3dv/js/panelset.js
index 7b5ab84..8668eee 100644
--- a/website/o3dv/js/panelset.js
+++ b/website/o3dv/js/panelset.js
@@ -4,7 +4,7 @@ OV.Panel = class
{
this.parentDiv = parentDiv;
this.panelDiv = OV.AddDiv (parentDiv);
- OV.HideDomElement (this.panelDiv);
+ OV.ShowDomElement (this.panelDiv, false);
this.visible = false;
}
@@ -25,11 +25,7 @@ OV.Panel = class
}
this.visible = show;
- if (this.visible) {
- OV.ShowDomElement (this.panelDiv);
- } else {
- OV.HideDomElement (this.panelDiv);
- }
+ OV.ShowDomElement (this.panelDiv, this.visible);
}
Resize ()
@@ -101,7 +97,7 @@ OV.PanelSet = class
this.panelsVisible = show;
if (this.panelsVisible) {
- OV.ShowDomElement (this.contentDiv);
+ OV.ShowDomElement (this.contentDiv, true);
OV.SetDomElementWidth (this.parentDiv, this.menuDiv.offsetWidth + this.panelsPrevWidth);
} else {
for (let panelButton of this.panelButtons) {
@@ -112,7 +108,7 @@ OV.PanelSet = class
}
this.panelsPrevWidth = this.contentDiv.offsetWidth;
OV.SetDomElementWidth (this.parentDiv, this.menuDiv.offsetWidth);
- OV.HideDomElement (this.contentDiv);
+ OV.ShowDomElement (this.contentDiv, false);
}
this.callbacks.onShowHidePanels (this.panelsVisible);
diff --git a/website/o3dv/js/sidebar.js b/website/o3dv/js/sidebar.js
index 64ef49d..5a995cb 100644
--- a/website/o3dv/js/sidebar.js
+++ b/website/o3dv/js/sidebar.js
@@ -8,9 +8,13 @@ OV.Sidebar = class
this.detailsPanel = new OV.SidebarDetailsPanel (this.panelSet.GetContentDiv ());
this.settingsPanel = new OV.SidebarSettingsPanel (this.panelSet.GetContentDiv (), settings);
+ this.measurePanel = new OV.SidebarMeasurePanel (this.panelSet.GetContentDiv ());
this.panelSet.AddPanel (this.detailsPanel);
this.panelSet.AddPanel (this.settingsPanel);
+ if (OV.FeatureSet.MeasureTool) {
+ this.panelSet.AddPanel (this.measurePanel);
+ }
this.panelSet.ShowPanel (this.detailsPanel);
}
@@ -30,11 +34,7 @@ OV.Sidebar = class
this.panelSet.Init ({
onResize : () => {
- if (this.panelSet.IsPanelsVisible ()) {
- OV.ShowDomElement (this.splitterDiv);
- } else {
- OV.HideDomElement (this.splitterDiv);
- }
+ OV.ShowDomElement (this.splitterDiv, this.panelSet.IsPanelsVisible ());
this.callbacks.onResize ();
},
onShowHidePanels : (show) => {
@@ -57,6 +57,12 @@ OV.Sidebar = class
}
});
+ this.measurePanel.Init ({
+ onActivatedChange : (isActivated) => {
+ this.callbacks.onMeasureToolActivedChange (isActivated);
+ }
+ });
+
OV.InstallVerticalSplitter (this.splitterDiv, this.mainDiv, true, () => {
this.callbacks.onResize ();
});
@@ -67,6 +73,11 @@ OV.Sidebar = class
this.settingsPanel.UpdateSettings (hasDefaultMaterial);
}
+ UpdateMeasureTool (measureTool)
+ {
+ this.measurePanel.UpdateMeasureTool (measureTool);
+ }
+
Resize (height)
{
OV.SetDomElementOuterHeight (this.mainDiv, height);
diff --git a/website/o3dv/js/sidebarmeasurepanel.js b/website/o3dv/js/sidebarmeasurepanel.js
new file mode 100644
index 0000000..64a6f0c
--- /dev/null
+++ b/website/o3dv/js/sidebarmeasurepanel.js
@@ -0,0 +1,97 @@
+OV.SidebarMeasurePanel = class extends OV.SidebarPanel
+{
+ constructor (parentDiv)
+ {
+ super (parentDiv);
+
+ this.helpSection = null;
+ this.resultSection = null;
+ }
+
+ GetName ()
+ {
+ return 'Measure';
+ }
+
+ GetIcon ()
+ {
+ return 'measure';
+ }
+
+ Init (callbacks)
+ {
+ super.Init (callbacks);
+
+ let isActive = false;
+ let activateButton = OV.AddDiv (this.contentDiv, 'ov_button ov_sidebar_button', 'Activate');
+ activateButton.addEventListener ('click', () => {
+ isActive = !isActive;
+ if (isActive) {
+ activateButton.classList.add ('outline');
+ activateButton.innerHTML = 'Deactivate';
+ } else {
+ activateButton.classList.remove ('outline');
+ activateButton.innerHTML = 'Activate';
+ }
+ this.callbacks.onActivatedChange (isActive);
+ });
+
+ this.helpSection = OV.AddDiv (this.contentDiv, 'ov_sidebar_section');
+ this.resultSection = OV.AddDiv (this.contentDiv, 'ov_sidebar_section');
+ }
+
+ UpdateMeasureTool (measureTool)
+ {
+ OV.ClearDomElement (this.helpSection);
+ OV.ClearDomElement (this.resultSection);
+
+ OV.ShowDomElement (this.helpSection, true);
+ OV.ShowDomElement (this.resultSection, false);
+
+ if (measureTool.IsActive ()) {
+ let markerCount = measureTool.GetMarkerCount ();
+ if (markerCount === 0) {
+ this.helpSection.innerHTML = 'Select a model point to start measure.';
+ } else if (markerCount === 1) {
+ this.helpSection.innerHTML = 'Select another model point to start measure.';
+ } else if (markerCount === 2) {
+ OV.ShowDomElement (this.helpSection, false);
+ OV.ShowDomElement (this.resultSection, true);
+
+ let calculatedValues = measureTool.Calculate ();
+
+ OV.AddDiv (this.resultSection, 'ov_sidebar_measure_name', 'Distance of points');
+ let pointsDistanceStr = calculatedValues.pointsDistance.toLocaleString (undefined, {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 6
+ });
+ OV.AddDiv (this.resultSection, 'ov_sidebar_measure_value', pointsDistanceStr);
+
+ OV.AddDiv (this.resultSection, 'ov_sidebar_measure_name', 'Distance of parallel faces');
+ if (calculatedValues.parallelFacesDistance !== null) {
+ let facesDistanceStr = calculatedValues.parallelFacesDistance.toLocaleString (undefined, {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 6
+ });
+ OV.AddDiv (this.resultSection, 'ov_sidebar_measure_value', facesDistanceStr);
+ } else {
+ OV.AddDiv (this.resultSection, 'ov_sidebar_measure_value', 'Faces are not parallel');
+ }
+
+ OV.AddDiv (this.resultSection, 'ov_sidebar_measure_name', 'Angle of faces');
+ let facesAngleDegree = calculatedValues.facesAngle * OV.RadDeg;
+ let facesAngleStr = facesAngleDegree.toLocaleString (undefined, {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 6
+ });
+ OV.AddDiv (this.resultSection, 'ov_sidebar_measure_value', facesAngleStr + '°');
+
+ }
+ }
+ }
+
+ Clear ()
+ {
+
+ }
+};
diff --git a/website/o3dv/js/sidebarsettingspanel.js b/website/o3dv/js/sidebarsettingspanel.js
index 27ff8e2..6a10f85 100644
--- a/website/o3dv/js/sidebarsettingspanel.js
+++ b/website/o3dv/js/sidebarsettingspanel.js
@@ -58,11 +58,7 @@ OV.SettingsColorSection = class
Show (show)
{
- if (show) {
- OV.ShowDomElement (this.contentDiv);
- } else {
- OV.HideDomElement (this.contentDiv);
- }
+ OV.ShowDomElement (this.contentDiv, show);
}
Update (color)
@@ -139,11 +135,11 @@ OV.SettingsEdgeDisplaySection = class
this.buttons = [];
let offButton = AddRadioButton (buttonsDiv, 'off', 'Don\'t Show Edges', () => {
- OV.HideDomElement (this.edgeSettingsDiv);
+ OV.ShowDomElement (this.edgeSettingsDiv, false);
callbacks.onShowEdgesChange (false);
});
let onButton = AddRadioButton (buttonsDiv, 'on', 'Show Edges', () => {
- OV.ShowDomElement (this.edgeSettingsDiv);
+ OV.ShowDomElement (this.edgeSettingsDiv, true);
callbacks.onShowEdgesChange (true);
});
this.buttons.push (offButton);
@@ -166,11 +162,7 @@ OV.SettingsEdgeDisplaySection = class
ShowEdgeSettings (show)
{
- if (show) {
- OV.ShowDomElement (this.edgeSettingsDiv);
- } else {
- OV.HideDomElement (this.edgeSettingsDiv);
- }
+ OV.ShowDomElement (this.edgeSettingsDiv, show);
}
Clear ()
@@ -338,7 +330,7 @@ OV.SidebarSettingsPanel = class extends OV.SidebarPanel
AddResetToDefaultsButton ()
{
let defaultSettings = new OV.Settings ();
- let resetToDefaultsButton = OV.AddDiv (this.contentDiv, 'ov_button outline ov_sidebar_button', 'Reset to Default');
+ let resetToDefaultsButton = OV.AddDiv (this.contentDiv, 'ov_button ov_sidebar_button outline', 'Reset to Default');
resetToDefaultsButton.addEventListener ('click', () => {
this.settings.backgroundColor = defaultSettings.backgroundColor;
this.settings.defaultColor = defaultSettings.defaultColor;
diff --git a/website/o3dv/js/toolbar.js b/website/o3dv/js/toolbar.js
index 968caf1..4319446 100644
--- a/website/o3dv/js/toolbar.js
+++ b/website/o3dv/js/toolbar.js
@@ -41,6 +41,11 @@ OV.ToolbarButton = class
this.buttonImg.classList.remove (className);
}
+ IsSelected ()
+ {
+ return this.selected;
+ }
+
SetSelected (selected)
{
this.selected = selected;
@@ -66,6 +71,17 @@ OV.Toolbar = class
return button;
}
+ AddImagePushButton (image, imageTitle, isSelected, onClick)
+ {
+ let button = new OV.ToolbarButton (image, imageTitle, () => {
+ button.SetSelected (!button.IsSelected ());
+ onClick ();
+ });
+ button.AddDomElements (this.mainDiv);
+ button.SetSelected (isSelected);
+ return button;
+ }
+
AddImageRadioButton (buttonData, selectedIndex, onClick)
{
let buttons = [];
diff --git a/website/o3dv/js/treeview.js b/website/o3dv/js/treeview.js
index e30a22b..ff3a46c 100644
--- a/website/o3dv/js/treeview.js
+++ b/website/o3dv/js/treeview.js
@@ -154,10 +154,10 @@ OV.TreeViewGroupItem = class extends OV.TreeViewItem
return;
}
if (this.isVisible) {
- OV.ShowDomElement (this.mainElement);
+ OV.ShowDomElement (this.mainElement, true);
this.childrenDiv.classList.add ('ov_tree_view_children');
} else {
- OV.HideDomElement (this.mainElement);
+ OV.ShowDomElement (this.mainElement, false);
this.childrenDiv.classList.remove ('ov_tree_view_children');
}
}
@@ -170,10 +170,10 @@ OV.TreeViewGroupItem = class extends OV.TreeViewItem
}
if (show) {
OV.SetSvgIconImageElement (this.openCloseButton, this.openButtonIcon);
- OV.ShowDomElement (this.childrenDiv);
+ OV.ShowDomElement (this.childrenDiv, true);
} else {
OV.SetSvgIconImageElement (this.openCloseButton, this.closeButtonIcon);
- OV.HideDomElement (this.childrenDiv);
+ OV.ShowDomElement (this.childrenDiv, false);
}
}
diff --git a/website/o3dv/js/website.js b/website/o3dv/js/website.js
index c131bd7..d215fe4 100644
--- a/website/o3dv/js/website.js
+++ b/website/o3dv/js/website.js
@@ -13,6 +13,7 @@ OV.Website = class
this.parameters = parameters;
this.settings = new OV.Settings ();
this.viewer = new OV.Viewer ();
+ this.measureTool = new OV.MeasureTool ();
this.hashHandler = new OV.HashHandler ();
this.cookieHandler = new OV.CookieHandler ();
this.toolbar = new OV.Toolbar (this.parameters.toolbarDiv);
@@ -33,6 +34,7 @@ OV.Website = class
this.SwitchTheme (this.settings.themeId, false);
this.InitViewer ();
+ this.InitMeasureTool ();
this.InitToolbar ();
this.InitDragAndDrop ();
this.InitSidebar ();
@@ -111,17 +113,17 @@ OV.Website = class
this.uiState = uiState;
if (this.uiState === OV.WebsiteUIState.Intro) {
- OV.ShowDomElement (this.parameters.introDiv);
- OV.HideDomElement (this.parameters.mainDiv);
+ OV.ShowDomElement (this.parameters.introDiv, true);
+ OV.ShowDomElement (this.parameters.mainDiv, false);
ShowOnlyOnModelElements (false);
} else if (this.uiState === OV.WebsiteUIState.Model) {
- OV.HideDomElement (this.parameters.introDiv);
- OV.ShowDomElement (this.parameters.mainDiv);
+ OV.ShowDomElement (this.parameters.introDiv, false);
+ OV.ShowDomElement (this.parameters.mainDiv, true);
ShowOnlyOnModelElements (true);
this.UpdatePanelsVisibility ();
} else if (this.uiState === OV.WebsiteUIState.Loading) {
- OV.HideDomElement (this.parameters.introDiv);
- OV.HideDomElement (this.parameters.mainDiv);
+ OV.ShowDomElement (this.parameters.introDiv, false);
+ OV.ShowDomElement (this.parameters.mainDiv, false);
ShowOnlyOnModelElements (false);
}
@@ -133,6 +135,7 @@ OV.Website = class
this.HidePopups ();
this.model = null;
this.parameters.fileNameDiv.innerHTML = '';
+ this.measureTool.Clear ();
this.viewer.Clear ();
this.navigator.Clear ();
this.sidebar.Clear ();
@@ -151,13 +154,21 @@ OV.Website = class
OnModelClicked (button, mouseCoordinates)
{
- if (button === 1) {
- let meshUserData = this.viewer.GetMeshUserDataUnderMouse (mouseCoordinates);
- if (meshUserData === null) {
- this.navigator.SetSelection (null);
- } else {
- this.navigator.SetSelection (new OV.Selection (OV.SelectionType.Mesh, meshUserData.originalMeshId));
- }
+ if (button !== 1) {
+ return;
+ }
+
+ if (this.measureTool.IsActive ()) {
+ this.measureTool.Click (mouseCoordinates);
+ this.sidebar.UpdateMeasureTool (this.measureTool);
+ return;
+ }
+
+ let meshUserData = this.viewer.GetMeshUserDataUnderMouse (mouseCoordinates);
+ if (meshUserData === null) {
+ this.navigator.SetSelection (null);
+ } else {
+ this.navigator.SetSelection (new OV.Selection (OV.SelectionType.Mesh, meshUserData.originalMeshId));
}
}
@@ -422,6 +433,11 @@ OV.Website = class
]);
}
+ InitMeasureTool ()
+ {
+ this.measureTool.Init (this.viewer, this.highlightColor);
+ }
+
InitToolbar ()
{
function AddButton (toolbar, eventHandler, imageName, imageTitle, classNames, onClick)
@@ -568,6 +584,15 @@ OV.Website = class
onThemeChange : () => {
this.SwitchTheme (this.settings.themeId, true);
},
+ onMeasureToolActivedChange : (isActivated) => {
+ if (isActivated) {
+ this.navigator.SetSelection (null);
+ this.measureTool.SetActive (true);
+ } else {
+ this.measureTool.SetActive (false);
+ }
+ this.sidebar.UpdateMeasureTool (this.measureTool);
+ },
onResize : () => {
this.Resize ();
},