Lab5 Forge API Intro – Get Properties & Search

(This is a continuation from the previous post: Lab4 “Forge API Web Intro JS”)

This post was prompted by an inquiry about accessing properties of Revit model using Forge API. He left a comment saying that he followed my tutorial and was able to view the uploaded model successfully. So let’s take Forge API Intro Lab4 as a starting point and build on top of it. In this post, we are going to add two functionalities that allow you to:

  • Select an object and obtain its properties
  • Search the model for a given string and isolate them in the viewer

Below is a sample image showing how a final web page may look like. Notice right above the viewer area; there are “Get Properties” and “Search” buttons along with a text field. We are going to add those.

ForgeIntroLab5

Modification to viewerBasic.js 

In the previous lab’s exercise, we have included JavaScript file named viewerBasic.js. This is like an utility specific for our minimum project. (If you recall, I restructured it from the original Basic Viewer tutorial to make is easier to use by modularizing it. It assumes for a display of a single 3D model with basic UI turned on.) The basic functionality of this file remains the same. We can use the same code except that we want to return the viewer so that we can call viewer functions later on. To do so, we add one line at the end of our viewByTokenAndUrn() to return the viewer object, and move two lines that create the viewer to the outside of onDocumentLoadSuccess() callback function: e.g.,

viewerBasic.js, viewByTokenAndUrn()
  1. function viewByTokenAndUrn(token, urn, viewerDivId) {
  2.     var viewer;
  3.     // …
  4.     function onDocumentLoadSuccess(doc) {
  5.         // …
  6.         // Lab5 moved 
  7.         //var viewerDiv = document.getElementById(viewerDivId);
  8.         //viewer = new Autodesk.Viewing.Private.GuiViewer3D(viewerDiv);
  9.         ////
  10.         viewer.start(svfUrl, modelOptions, onLoadModelSuccess, onLoadModelError);
  11.     }
  12.     // …
  13.     // Lab5 moved
  14.     var viewerDiv = document.getElementById(viewerDivId);
  15.     viewer = new Autodesk.Viewing.Private.GuiViewer3D(viewerDiv);
  16.     ////
  17.     // This is from basic viewer.
  18.     Autodesk.Viewing.Initializer(options, function onInitialized() {
  19.         Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
  20.     });
  21.     return viewer; // Lab5 added
  22. }

This allows the calling function to get hold of the viewer object and access various methods of the viewer. Save viewerBasic.js.

Next, open ForgeUI.aspx code. At the top of JavaScript code section for the viewer, declare variable, say _viewer. Set _viewer to assign the return value from viewerByTokenAndUrn().

ForgeUI.aspx
  1.     var _viewer; // Lab5
  2.     function buttonViewClicked() {
  3.         var token = $(‘#TextBoxToken’).val();
  4.         var urn = $(‘#TextBoxUrn64’).val();
  5.         // Lab5
  6.         _viewer = viewByTokenAndUrn(token, urn, “MyViewerDiv”);
  7.         ////
  8.     }

With this small modification, we can access viewer object through _viewer variable in the client side html file. Additional functionalities will be in JavaScript code.

Get Properties

Now, let’s add a new functionality to get properties of a selected object in the viewer. To do this, we use two methods of _viewer or an instance of Viewer3D class:

  • Viewer3D.getSelection()
  • Viewer3D.getProperties()

getSelection() takes no argument, and returns the array of the currently selected object id’s. getProperties() takes three arguments: objectId, onSuccessCallback and onErrorCallback; and upon success, it calls onSuccessCallback.

The code below shows the function that takes a viewer object as an input and display the properties of a currently selected element in the area specified by the second argument outputTextArea. To make is easier to read the code within the project, I put this function in a separate javascript file and named it viewerPropertiesSearch.js.

viewerPropertiesSearcg.js, viewerGetProperties()
  1. //===================================================================
  2. // Lab5. Get Properties
  3. //===================================
  4. // For simplicity, we only show properties of one selected object here.
  5. function viewerGetProperties(viewer, outputTextArea) {
  6.     // Callback for view.getProperties() on success.
  7.     function propCallback(data) {
  8.         // Check if we got properties.
  9.         if ((data.properties == null) || (data.properties.length == 0)) {
  10.             outputTextArea.value = “no properties”;
  11.             return;
  12.         }
  13.         // Iterate over properties and put together
  14.         // a list of property’s name/value pairs to diplay.
  15.         var str = “”;
  16.         var length = data.properties.length;
  17.         for (var i = 0; i < length; i++) {
  18.             var obj = data.properties[i];
  19.             str += obj.displayName + “: “ + obj.displayValue + “\n”;
  20.         }
  21.         outputTextArea.value = str;
  22.     }
  23.     function propErrorCallback(data) {
  24.         outputTextArea.value = “error in getProperties().”;
  25.     }
  26.     //—————————————-
  27.     // Main – Properties
  28.     //———————
  29.     if (viewer.getSelection().length > 0) {
  30.         var objSelected = viewer.getSelection()[0];
  31.         viewer.getProperties(objSelected, propCallback, propErrorCallback);
  32.     }
  33.     else {
  34.         outputTextArea.value = “Please select one element to show properties.”;
  35.     }
  36. }

You can call this function from a callback function for “Get Properties” button click, e.g.,

ForgeUI.aspx
  1.         <!– Lab 5. Properties and Search –> 
  2.         <input id=”ButtonProperty” type=”button” value=”Get Properties” onclick=”getProperties() /> 
  3.         <textarea id=”TextAreaResult” rows=”3″ cols=”80″> </textarea>
  4.     </div>
  5.     </form>
  6.     <!– Viewer Lab 5 –> 
  7.     <script src=”Scripts/viewerPropertiesSearch.js”></script>
  8.     <script>
  9.         // …
  10.         //===================================================================
  11.         // Lab5. Properties   
  12.         //===================================
  13.         // Callback for “Get Properties” button.  
  14.         // For simplicity, we only show properties of one selected object here.
  15.         function getProperties() {
  16.             var txtArea = document.getElementById(“TextAreaResult”);
  17.             viewerGetProperties(_viewer, txtArea);
  18.         }

This is it in terms of getting properties of an selected object. You might be finding it easier than you thought.

You should be able to test your code now. Try uploading a model, select one element, and press “Get Properties” button. If everything is working as intended, you will see a list of properties displayed in the text box above the viewing area.

Search

Let’s add one more functionality. This time we are going to add “search”. Search is probably one of attractive features of Forge API. You can search through a model for any attributes or properties attached to individual components of the model. For this, we use two methods of _viewer or Viewer3D class:

  • Viewer3D.search()
  • Viewer3D.isolate()

search() takes four arguments: textToSearch, onSuccessCallback, onErrorCallback, and arrayOfAttributeNames. The fourth one is optional; if omitted, search will be performed for any attributes. And upon success, it calls onSuccessCallback function.

isolate() takes an array of object ids and isolate them or dim objects which is not a part of an array. We call this to show what objects are returned as a result of search.

In addition, we used clearSelection() to clears current selection.

  • Viewer3D.clearSelection()

This is to clear the result we added earlier to get properties of a selected object.

The below shows the minimum code to realize our search functionality. viewerSearch() takes a viewer object and a search string as input arguments, and isolate elements identified as result of search.  The output text area is to display the message in case something did not go as expected in this case:

viewerPropertiesSearch.js, viewerSearch()
  1. //===================================================================
  2. // Lab5. Search  
  3. //===================================
  4. function viewerSearch(viewer, searchStr, outputTextArea) {
  5.     // Callback for _viewer.search() on success.
  6.     function searchCallback(ids) {
  7.         if (ids.length > 0) {
  8.             viewer.isolate(ids);
  9.             outputTextArea.value = ids;
  10.         }
  11.         else {
  12.             outputTextArea.value = “nothing found.”;
  13.         }
  14.     }
  15.     // Callback for _viewer.search() on error.
  16.     function searchErrorCallback() {
  17.         outputTextArea.value = “error in search().”;
  18.     }
  19.     //—————————————
  20.     // Main – Search
  21.     //—————–
  22.     viewer.clearSelection();
  23.     viewer.search(searchStr, searchCallback, searchErrorCallback);
  24. }

You can set this function in the callback for a Search button click, e.g.,

ForgeUI.aspx
  1.         <!– Lab 5. Properties and Search –>
  2.         <input id=”ButtonProperty” type=”button” value=”Get Properties” onclick=”getProperties()” />&nbsp;
  3.         <input id=”ButtonSearch” type=”button” value=”Search >>” onclick=”search() />&nbsp;
  4.         <input id=”SearchString” type=”text” value=””/>
  5.         <br />
  6.         <textarea id=”TextAreaResult” rows=”3″ cols=”80″> </textarea>
  7.         <!– The Viewer will be instantiated here –>

  8.     </div>
  9.     </form>
  10.     <script>
  11.         // …
  12.         //===================================================================
  13.         // Lab5. Search  
  14.         //===================================
  15.         //  Callback for “Search” button.
  16.         function search() {
  17.             var txtArea = document.getElementById(“TextAreaResult”);
  18.             var searchStr = document.getElementById(“SearchString”).value;
  19.             if (searchStr.length == 0) {
  20.                 txtArea.value = “no search string.”;
  21.                 return;
  22.             }
  23.             viewerSearch(_viewer, searchStr, txtArea);
  24.         }

Now, time for another test. This time, type in a word, for example, “door” in the small text box next to “Search >>” button, then click “Search >>”. If everything is working as intended, you will see a collection of object isolated in the viewing area. To finish isolation, right click anywhere within the viewer area and click “Show all objects”.

You can get the source code for Lab 5 from here: Lab5

For those who haven’t seen my original post about “Hello World” style introduction to Forge API, I also put the link here: Forge API Intro Labs Overview

I hope this gives you a good entry point to further take advantage of the client side Viewer JavaScript API. There are other ways to access properties and search, such as using Model Derivatives server side API and viewer’s search extension. But they are beyond the scope of this “getting started” intro lab.  For more information, please refer to the documentation on Forge developer portal.

Mikako

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s