How To

Description

This page introduces the XYZ Point-Picking tool provided by 3DHOP, showing how to set up this simple but useful tool in the viewer.


Point-Picking Tool

Click to run live demo
Retrieving points coordinates in a 3DHOP scene

Set Up

3DHOP integrates a ready-to-use tool for picking a point on the surface of a 3D model, and get back the XYZ position of the point picked. In the above example, the toolbar button depicting a crosshair start the "point-picking mode": clicking on the surface of the 3D model, the XYZ coordinates of the picked point are shown in the interface.
Each point on the surface of a 3D model (or each vertex in a pointcloud) is a point in space, defined by its XYZ coordinates. If the 3D model is metric (i.e. its coordinates are in a known measure unit, and corresponds to measurements taken in the real world) and correctly oriented, the XYX coordinates of a point have a specific meaning.
This tool is especially useful when displaying 3D models of terrains or archeological excavations (which have been georeferenced), and for scientific visualization in general.
This tool is very similar, in structure, to the point-to-point measurement tool presented in the last how-to.

To use the point-picking tool, two steps are needed: the first one is to set-up the HTML components to activate the point-picking mode and to display the returned coordinates (toolbar buttons, and a panel wit some text), while the second one is to register the handle for the point-picking event. Let us begin with the first one: how to add a new tool button(s) and output panel to the viewer.

Just like for the measurement, we have to add to the toolbar the buttons for the point-picking: this is done by adding two lines in the toolbar definition, defining a pair of icons, one to activate and one to deactivate the point-picking tool. These two buttons works similarly to the couple used to turn on/off the light control or the fullscreen. Two suitable icons are already present in the "skin" folder.
So, in the BODY of the HTML page, where the toolbar is defined, we add two new clickable images, with ID pick_on and pick, as shown in the following code box:

<div id="3dhop" class="tdhop" onmousedown="if (event.preventDefault) event.preventDefault()">
 <div id="toolbar">
  <img id="home"       title="Home"                  src="skins/dark/home.png"         /><br/> 
  <img id="zoomin"     title="Zoom In"               src="skins/dark/zoomin.png"       /><br/>
  <img id="zoomout"    title="Zoom Out"              src="skins/dark/zoomout.png"      /><br/>
  <img id="light_on"   title="Disable Light Control" src="skins/dark/lightcontrol_on.png" 
                                                          style="position:absolute; visibility:hidden;"/>
  <img id="light"      title="Enable Light Control"  src="skins/dark/lightcontrol.png" /><br/>
  <img id="pick_on"    title="Disable PickPoint Mode"src="skins/dark/pick_on.png" 
                                                          style="position:absolute; visibility:hidden;"/>
  <img id="pick"       title="Enable PickPoint Mode" src="skins/dark/pick.png"         /><br/>  
  <img id="full_on"    title="Exit Full Screen"      src="skins/dark/full_on.png" 
                                                          style="position:absolute; visibility:hidden;"/>
  <img id="full"       title="Full Screen"           src="skins/dark/full.png"         />
 </div>
 ...

Now, we need to create a space on the webpage where to print out the picked XYZ coordinates. Again, in the BODY section, just after the TOOLBAR and before the CANVAS element used by the 3DHOP rendering, we add a small HTML panel made of a simple HTML DIV containing a SPAN text container, as shown below. Both the div and the span uses specific ID and CLASS (pickpoint-box and output-box for the div, pickpoint-output and output-text for the span), that have been defined in the 3DHOP CSS to have this panel automatically arrange itself in the page, always staying close to the measurement button.

 ...
 <div id="pickpoint-box" class="output-box">
  XYZ picked point<hr/>
  <span id="pickpoint-output" class="output-text" onmousedown="event.stopPropagation()">[ 0 , 0 , 0 ]</span>
 </div>
 ...

As said, the basic behaviour of the XYZ picking output panel is to stay close to the toolbar pick-point button. It is, however, possible to manually set the position of this pre-made component using the movePickpointbox helper function. This function takes as input the horizontal and vertical shift (in pixels) from the left-top corner of the CANVAS (notice that the XYZ picking box movement is not confined in the viewer space, but can go over its edges). This function may be called, like in the following example, in the document READY function, after the creation of the scene, to set the position when the page is loaded, but also later on, in any other javascript function.

$(document).ready(function(){
  ...
  movePickpointbox(10,10);  
}); 

Now that we have the HTML components, we can connect them to the 3DHOP viewer. In the script block, we can now add the new button-related actions in the actionsToolbar JavaScript function (that we presented in one of the first HOW-TOs):

function actionsToolbar(action) {
  if(action=='home')
    presenter.resetTrackball();
  else if(action=='zoomin') 
    presenter.zoomIn();
  else if(action=='zoomout') 
    presenter.zoomOut(); 
  else if(action=='light' || action=='light_on') { 
    presenter.enableLightTrackball(!presenter.isLightTrackballEnabled()); lightSwitch(); } 
  else if(action=='pick' || action=='pick_on') { 
    presenter.enablePickpointMode(!presenter.isPickpointModeEnabled()); pickpointSwitch(); } 
  else if(action=='full'  || action=='full_on') 
    fullscreenSwitch(); 
}

The new code is in the second-last "else if" statement, handling the pick and pick_on action IDs. When the user press the pick-point buttons, the actionsToolbar function is called with the appropriate parameter ('pick' or 'pick_on'). The actionsToolbar function enters in this statement and then executes the code here contained.
More specifically, when the pick-point buttons are pressed, the code presenter.enablePickpointMode(!presenter.isPickpointModeEnabled()), toggle the point-picking mode (activate it if it was inactive, and vice-versa). The pickpointSwitch() function then switch the appearance of the point-picking button icon, toggles the output panel visibility, and changes the mouse cursor.

Now we have to tell to 3DHOP what should happen when the user has picked a point on the 3D scene; similarly to what happens when a hot-spot is clicked, when the user picks a point, an event is fired by 3DHOP (containing the picked XYZ coordinates). We have to define a function that prints the coordinates in our output panel, and register this function to handle the point-picking event.
The following code box show the "onEndPick" function that we want to use to handle the point-picking event; the function gets in input the XYZ coodinates, and prints the X,Y and Z coodinates as an html text in the webpage component of ID pickpoint-output (our output panel). The JavaScript instruction .toFixed(2) and the next two lines are used to set the number of decimals when displaying the X, Y and Z components of the picked point coordinates.

function onEndPick(point) {
    var x = point[0].toFixed(2);
    var y = point[1].toFixed(2);
    var z = point[2].toFixed(2);
    $('#pickpoint-output').html("[ "+x+" , "+y+" , "+z+" ]");
}

After defining the "onEndPick" function, we have to tell 3DHOP to use this function when the measurement event is fired, using the following code, visible at the end of the "setup3dhop" main function:

    ...
    presenter._onEndPickingPoint = onEndPick;
}

Now the webpage does have a working pick-point tool: just load it and press the pick-point button to start picking. The pick-point button changes color, the output panel shows up and the mouse cursor changes to a crosshair. Now, if you click on the surface of the 3d mode, a point appear and its XYZ coordinates are printed in the output panel. If you click again on the model, another point will be picked. To exit the pick-point mode, just click on the toolbar measurement button again.

  • It is still possible to rotate ans scale the model in pick-point mode, just by dragging the mouse and using the wheel.
  • It is possible to pick the points on any of the visible instances, picking also works on point-clouds.
  • There is only one point picked at a time, each new picking will overwrite the previous one.
  • The picked point is lost if the pick-point mode is turned off.


Your Own Pick-Point Tool

The pick-point tool has been implemented as a ready-to-use functionality of the 3DHOP system, with the pre-made interface described in this how-to, as the simple XYZ picking is a very widely used tool. So, for basic users, this feature is ready out of the box.
It is clear, however, that other more advanced user will want to customize this functionality to cope with their needs. Now, all you need to implement a different interface is to add your HTML components to call, somewhere, the "presenter.enablePickpointMode( ... )" to make 3DHOP enter in the "pick-point mode", while providing and register a different, custom-made handler for the "_onEndPickingPoint" event, able to do whatever you want to do with the resulting measure (printing it in a log, sending to a remote database, saving it in a cookie).


A Word On Units and Reference Spaces

It is important to say something about the numbers returned by the pick-point tool: if your 3D models are not in a known scale, or are not oriented correctly, the returned XYZ coordinates may be meaningless.
3DHOP uses the [XYZ] coordinates exactly as they are stored in the 3D models: for this reason, any picked point on the 3D models displayed by 3DHOP will use the measure unit and reference space of the 3D model.
Most 3D models created by triangulation 3D scanning are in millimeters (and so the distance will be in mm), most 3D models created by terrestrial laser scanners are in meters (and so the distance will be measured in meters). If you do not know which unit of measure is used by your 3D model, or if your 3D model is not scaled to any measure unit, the XYZ coordinates you get by picking may be funny and not very useful.
Similarly, in order for the XYZ coordinates to be useful, the 3D models (or the whole 3D scene) have to be in a reference space with some kind of meaning: e.g. with the X axis is aligned with the east-west direction and the Y axis aligned with the north-south direction, or with the axis origin in a specific position of the model/scene, or with the shape of the 3D object "straight" with respect to the axis. If your 3D model is in a random position and orientation in space, the returned XYZ coordinates will not be meaningful.
Finally, be careful with the transformations that are applied to meshes and instances. If you have used your 3D model inside 3DHOP without any transformation (rotation, translation, scaling), the returned XYZ coordinates are exactly the ones defined IN THE SPACE OF THE MODEL for the point picked. However, if you have specified some transformation for the mesh and/or for the instance, those transformation will be taken in account when picking; it is then better to say that the picking happens IN THE SPACE OF THE SCENE.
In any case, it would be better to scale AND orient correctly your 3D models before putting them online inside 3DHOP.


Well, summarizing, to use the 3DHOP pick-point tool you just have to add to the viewer the output XYZ coordinates box panel and the new toolbar buttons (setting up the toolbar actions JavaScript function in the proper way). Done this, it only remains to register the right event handler, design the actions to perform when the event is fired and… you are done!

The complete sources of this example are provided together the 3DHOP code in the download section.

If you want instead to learn more about how to activate the feature for real-time sectioning the 3D models rendered with 3DHOP click here and go to the next HOWTO.