Enable and configure Web Central 3D Navigator
HTML Drawing Control
Enable and configure Web Central 3D Navigator
Web Central : Technologies / User Interface Add-ins / HTML Drawing Views / Web Central 3D Navigator
The Web Central 3D Navigator is a high-performance, interactive Web-based control for 3D BIM visualization, analysis and process integration. Web Central 3D Navigator control delivers:
- Intelligent demand loading of models and portions of models related to portfolio queries.
- Analysis, highlighting, and labeling based on portfolio-driven queries.
- Interaction with models, and the ability to embed BIM models into Archibus workflows and processes.
Note: The 3D Navigator and the 3D Publish features are licensed separately from the Archibus Web Central core and separately from the Extension for Revit.
Note : The BIM Viewer also shows 3D models and provides additional features not found with the 3D Navigator.
For examples of the 3D Navigator, see:
-
Space / Space Inventory / Space Manager / Space Console
-
Assets / Assets / Asset Manager / Equipment Systems Console
- Sample views in the Technologies / User Interface Add-Ins / HTML5 Drawing Views Web Central 3D Navigator
- When working with the sample HQ project for the above views, select floors and equipment that is located in the NB building. The sample data includes 3D enterprise graphics for building NB.
Toolbar
The Web Central 3D Navigator control provides a toolbar with these commands:
Icon | Action |
---|---|
Orbit |
Mouse drag over the drawing to change viewing angle. |
Pan | Mouse drag over the drawing to move it. Pressing down Shift key, mouse drag will move the drawing. |
Zoom | mouse drag over the drawing to zoom it in/out. Mouse wheeling will always do zooming in/out. Pressing down Ctrl key, mouse drag will zoom the drawing in/out (for Mac PC users). |
Home | Clicking it will restore the original position of the drawing. Pressing Esc key will also do this action. |
Enable the 3D Navigator in a view file
1. Add
ab-bim-3d-navigator.css
and
ab-bim-3d-navigator.js
:
<css file="ab-bim-3d-navigator.css"/>
<js file="ab-bim-3d-navigator.js"/>
2. Add an html panel:
<panel type="html" id="navigatorpanel">
<title>3D Navigator</title>
<html>
<div id="bim3d" class="bim3dContainer"> </div>
</html>
</panel>
3. In javaScript file, create a 3D Navigator object:
this.bim3d = new Ab.bim3d.Navigator('bim3d');
4. Use
this.bim3d
object and its APIs to add categories panel, to add custom context menus, to load drawing, and so on.
For details, see the examples on the Navigator in Technologies / User Interface Add-ins / HTML Drawing Views / Web Central 3D Navigator.
Context menus
Users can use context menus to manipulate selection of 3D assets by right-clicking the mouse.
There are five built-in context menus:
- Hide selected
- Hide similar objects (the objects have the same category as the selected)
- Show all objects
- Focus the selected (zoom in the selected)
- Clear selection
Turn off built-in context menus:
this.bim3d.contextMenus.setFilter(['hideSelected', 'hideSimilar', 'showAll']);
Add custom context menus
You can add a custom context menu based on user selected object's asset type:
var assetType = this.bim3d.getSelectedObjectAssetType(); var primaryKey = this.bim3d.getSelectedObjectPrimaryKey(); this.bim3d.contextMenus.setShowListener(function(menus){ if(primaryKey && assetType === 'rm'){ primaryKey = primaryKey.split(';'); menus.push(null); menus.push({label:'Show Room Contents', id:'showroomcontents_rm', actions:[function() { var url = 'ab-revit-overlay-rm.axvw?fieldName=rm.bl_id&fieldValue='+primaryKey[0]+'&fieldName2=rm.fl_id&fieldValue2='+primaryKey[1] +'&fieldName3=rm.rm_id&fieldValue3='+primaryKey[2]; View.openDialog(url, '', false, {width : 600, height : 650}); }]}); } });
Category panel
To configure information in 3D drawings, select desired categories in the category panel at the upper right. The panel below shows categories under four headings: Exterior / Core, Disciplines, Floor Elements, and Assets:
To add a category panel to a drawing:
/*
*@title: translatable to be displayed on UI.
*@name: used by the navigator.
*@codes: Array of category codes.
*@json: published 3D file name, either assembling from publish naming convention like {bl_id value in database}-shell or database afm_dwgs.dwg_name value.
when json='nb-shell', its corresponding link in Categories Panel will be inactive (white colored), clicking the link will invoke loading the file;
when json='null', its link in Categories Panel will be inactive (white colored), but apps should have already loaded but hidden its categories, clicking the link will display its categories;
when json='', its link in Categories panel will be active (yellow colored), user's clicking will hide its categories.
*@functions: List of published function codes to have a fine control over categories with same category code but in the different groups of Categories Panel.
For example, door's category is 'Doors', but its Function is 'Exterior' in published shell, and its Function is 'Interior' in published Floor.
*/
this.bim3d.setSuperCategories([
{title:'Exterior/Core', name:'Exterior', superCategories:[
{title:'Site', name: 'Site', codes:['Topography','Site','Roads','Parking', 'Property Lines','Pads'], json:'{building}-site'},
{title:'Shell', name: 'Shell', codes:['Roofs','Walls','Curtain Panels', 'Doors'], functions:['Exterior', 'Foundation', 'Retaining', 'Coreshaft'], json:'null'},
{title:'Core', name: 'Core', codes:['Floors','Stairs','Railings','Ceilings'], json:'null'}]},
{title:'Disciplines', name: 'Disciplines', superCategories:[
{title:'HVAC', name: 'HVAC', codes:['Ducts','Duct Fittings','Duct Systems','Flex Ducts','Air Terminals','Mechanical Equipment'],json:'{building}-hvac'},
{title:'Piping', name: 'Piping', codes:['Flex Pipes','Piping Systems','Plumbing','Plumbing Fixtures', 'Pipe Accessories', 'Pipe Fittings', 'Pipes'],
json:'{building}-plumbing'},
{title:'Lighting', name: 'Lighting', codes:['Lighting Devices', 'Lighting Fixtures', 'Electrical Fixtures'], dual:'false', functions:['Interior'],
json:'{building}-lighting'}]},
{title:'Floor Elements', name: 'Floor', superCategories:[
{title:'Interior Walls', name: 'Interior Walls', codes:['Walls'], functions:['Interior'], dual:'true', json:''},
{title:'Floors', name: 'Floors', dual:'true', codes:['Floors'], functions:['Interior'], json:''},
{title:'Ceilings', name: 'Ceilings', dual:'true', codes:['Ceilings'], functions:['Interior'], json:''} ,
{title:'Curtain Panels', name: 'Curtain Panels', codes:['Curtain Panels'], functions:['Interior'], dual:'true', json:''} ,
{title:'Doors', name: 'Doors', codes:['Doors'], functions:['Interior'], dual:'true', json:''}]},
{title:'Assets', name:'Assets', superCategories:[
{title:'Rooms', name: 'Rooms', codes:['Rooms'], functions:['Interior'],json:''},
{title:'Equipment', name: 'Equipment', codes: ['Fire Alarm Devices','Security Devices', 'Specialty Equipment' ,'Duct Fittings', 'Mechanical Equipment',
'Air Terminals'],
functions:['Interior'], json:''},{title:'Furniture', name: 'Furniture', codes: ['Furniture'], functions:['Interior'], json:''}]}
]);
After you add a category panel, use the API under Dynamically update category panel to control information that appears in the panel's title bar, and below the title bar.
If you open more than one 3D model, check the category panel's title bar to verify which drawing appears in the view. For example, select Building NB, Floor 01 in the space console to open that floor's 3D drawing, then select Building MC08, Floor 1 to open a second 3D drawing. Locations pane shows both models selected:
Title at the top of the category panel indicates which 3D drawing appears in the view:
Category data available for each 3D drawing varies from model to model. For example, one model might contain Site data or HVAC data, but another model might not. The category panel displays only categories available for the drawing open in the view. API under Dynamically update category panel updates the panel's categories when you open a new drawing.
Images below illustrate how the category panel displays categories available for a particular drawing. Building NB has Site and HVAC data available, whereas Building MC08 does not. Site and HVAC appear as selections in the NB category panel, but not in the panel for MC08.
Optional 3D operation selectors in panel's title bar
Use these selectors for isolating, highlighting, or labeling.
To add selectors:
/**
* Appends 3D operation selector (combo box) to specified div object.*
* @param: div, div object - a container for the selector.
* @param: selector object id.
* @param: prompt, a text title for the selector.
* @param: dsFilter, dataSource name filter.
* @param: options, Array of HTML Option objects.
* @param: callback, call back function when selecting an option.
* @param: defaultValue, default value for the selector. if it's not passed, the default will be 'None'.
*
*/
Ab.bim3d.Utility.appendSelector: function(div, comboId, prompt, dsFilter, options, callback, defaultValue)
//panel title bar object
var titleDiv = document.getElementById('navigatorpanel_title');
//use Ab.bim3d.Utility.appendSelector to set up 3D operation selectors
Ab.bim3d.Utility.appendSelector(titleDiv, 'isolate', "Isolates:", '', new Option('Highlight', 'Highlight'),
new Option('Rooms', 'Rooms'),new Option('Furniture', 'Furniture'), new Option('Selected', 'Selected'), this.isolate.bind(this));
Ab.bim3d.Utility.appendSelector(titleDiv, 'hilite', "Highlights:", 'DrawingControlHighlight', null, this.dataSourceUpadte.bind(this));
Ab.bim3d.Utility.appendSelector(titleDiv, 'labels', "Labels:", 'DrawingControlLabels', null, this.dataSourceUpadte.bind(this));
APIs
Create 3D Navigator Object
/**
* Constructor for 3D navigator.
* @param: divId, div object id to hold 3D drawing.
* @param: config, for future usage.
*/
constructor: function(divId, config)
//create an new object
var bim3d = new Ab.bim3d.Navigator('bim3d');
Load a drawing
/**
* Loads published 3D drawing.
* @param: fileName, its value comes from either database afm_dwgs.draw_name or assembling by publish naming convention like {bl_id}-shell.
It must be in lower-case and no file extension included.
* @param: isFirst, if it's the first-time loading call for a specified model or building. If true, the navigator will calculate the best layout and
orientation for the drawing and delete any cached 3D data.
* @param: callback, call back function with loaded scenes object as parameter.
*/
load: function(fileName, isFirst, callback){
/**
*following code example will load three published 3D files one by one.
*/
//load the shell of NB building
this.bim3d.load('nb-shell', true, function(scenes){
//load shell first to layout the drawing in best fitting and orientation, but hide its categories
scope.bim3d.showCategories(['Roofs','Walls','Curtain Panels', 'Doors'], null, false, false, false, scenes);
//load the core of NB building
scope.bim3d.load('nb-core', false, function(scenes){
//load core but hide its categories
scope.bim3d.showCategories(['Floors','Stairs','Railings','Ceilings'], null, false, false, false, scenes);
//load the level 1 of NB building and show its categories
scope.bim3d.load('nb-level 1', false, null);
});
});
Single mouse click
With mouse is over 3D object, a single-click will make the object selected and highlighted in red.
/**
* single click event listener callback function parameters.
*
*@param: id, 3d object id.
*@param: category, object's category code.
*@param: level, object's level.
*@param: assetType, object asset type like 'rm'.
*@param: primaryKeys, object primary key values like 'HQ;18;105'.
*@param: userData, object's published data.
*/
this.bim3d.setObjectClickEventListener(function(id, category, level, assetType, primaryKeys , userData){
primaryKeys = primaryKeys.split(';'); //Array like [HQ, 18, 105
//use primaryKeys as restriction to do drill-down
});
//turn off single click
this.bim3d.setObjectClickable(false);
Double mouse click
With mouse double click over 3D object, the object or its similar ones will be hidden.
//set up double click event listener
this.bim3d.setObjectHideEventListener(function(obj){...});
//turn off double click
this.bim3d.setObjectDoubleClickable(false);
Highlight
/**
* Gets highlight colors from database and highlights corresponding asset objects.
* @param: asset, asset type like rm, eq and so on.
* @param: viewName, axvw file name.
* @param: dataSourceId, highlight dataSource id.
* @param: restriction, Ab.view.Restriction.
* @param: parameters, dataSource parameters.
*/
thematicHighlight: function(asset, viewName, dataSourceId, restriction, parameters)
var restriction = new Ab.view.Restriction();
restriction.addClause('rm.bl_id', scope.selectedFloorRow['rm.bl_id'] );
//highlight objects
this.bim3d.thematicHighlight('rm', 'ab-ex-bim-3d-rm-example-navigator.axvw', scope.currentHighlightDS, toJSON(restriction), null);
/**
* Clears highlight.
* @param needRendering: if rendering the drawing.
*/
clearHighlight: function(needRendering)
this.bim3d.clearHighlight(true);
Label
/**
* Adds labels to specified objects by their category.
* @param: categoryCode, category code.
* @param: labels, Object like {'HQ;18;105': 'displayed label' ...}.
* @param: callback. call back function to be invoked after labeling is completed.
*/
addLabels: function(categoryCode, labels, callback)
//since labeling could take a while, add spinning progress indicator
this.bim3d.startSpinning();
//get label records from the label dataSource object
var records = View.dataSources.get(this.currentLabelDS).getRecords(restriction);
var record, labels={};
for(var i=0, ln=records.length; i<ln; i++){
record = records[i];
var value='';
for(var j=0, jn=fieldNames.length; j<lj; j++){
value += record.getValue(fieldNames[j]);
if(j !== jn - 1){
//multiple lines
value += '\n';
}
}
labels[record.getValue('rm.bl_id') +';'+ record.getValue('rm.fl_id') +';'+ record.getValue('rm.rm_id')] = value;
}
//add the labels to the 3D objects
this.bim3d.addLabels('Rooms', labels, function(){
//after labeling is done, stop the spinning
scope.bim3d.stopSpinning();
});
/**
* Clears displayed labels.
*/
clearLabels: function()
//clear labels
this.bim3d.clearLabels();
Isolate
Isolates 3D objects so that they can be reviewable and click-selectable even they are inside 3D structure.
/**
* Isolates objects by their categories.
*
* @param: categories, Array of category codes.
*/
isolate: function(categories)
this.bim3d.isolate(['Rooms']);
/**
* Isolates objects by their material name.
*
* @param: materialName, 3D object material name.
*/
isolateByMaterial: function(materialName)
//isolates highlighted objects
this.bim3d.isolateByMaterial('ab-highlight');
//isolates selected object
this.bim3d.isolateByMaterial('ab-selection');
/**
* Clears isolated objects.
*
* @param: callback, call back function.
*/|
clearIsolated: function(callback)
this.bim3d.clearIsolated();
Select
/**
* Selects an object by its id.
*
* @param id: 3D object id.
* @param colorCode: rgb color value.
* @param callback: call back function - pass object uuid.
*/
select: function(id, colorCode, callback)
//use primary key to get 3D object and then call API to do selection or zooming
this.bim3d.getObjectByPrimaryKey(pkValue, function(object){
//select
scope.bim3d.select(object.id);
scope.bim3d.render();
//scope.bim3d.zoomIn(object);
});
//gets the asset type of the selected object like 'rm' or 'eq'
var assetType = this.bim3d.getSelectedObjectAssetType();
//gets the asset primary key value of the selected object like 'HQ;18;105'
var pkValue = this.bim3d.getSelectedObjectPrimaryKey();
/**
* Clears selection.
*/
clearSelection: function()
this.bim3d.clearSelection();
Category
/**
* Shows specified Categories.
*
* @param: categoryCodes Array of category codes.
* @param: levels Array like ['LEVEL 1','LEVEL 2'].
* @param: show true/false.
* @param: showExcluded true/false.
* @param: forcedRendering true/false.
* @param: scenes Array of scene objects.
*/
showCategories: function(categoryCodes, levels, show, showExcluded, forcedRendering, scenes)
//hides shell by its categories
this.bim3d.showCategories(['Roofs','Walls','Curtain Panels', 'Doors'], null, false, false, false, scenes);
Dynamically update category panel
When loading a new model or building, sample code below fetches category data from corresponding
afm_enterprise_graphics
records.
API
rebuildContent(modelName)
updates Category panel's contents dynamically. When
modelName
is not null, its value appears in Category panel's top bar.
//when loading a new model or building, dynamically get category data from corresponding afm_enterprise_graphics records var superCategories = []; var exteriorSuperCategories = []; var site = this.getModelRecordInfoByFileName(bl_id, 'site'); if(site){ exteriorSuperCategories.push({title:'Site', name: 'Site', codes:site.categories, json:site.filename, functions: site.functions}); } var shell = this.getModelRecordInfoByFileName(bl_id, 'shell'); if(shell){ exteriorSuperCategories.push({title:'Shell', name: 'Shell', codes:shell.categories, json:shell.filename, functions: shell.functions}); } core = this.getModelRecordInfoByFileName(bl_id, 'core'); if(core){ exteriorSuperCategories.push({title:'Core', name: 'Core', codes:core.categories, json:'null', functions: core.functions}); } if(exteriorSuperCategories.length > 0){ superCategories.push({title:'Exterior/Core', name:'Exterior', superCategories: exteriorSuperCategories }); } var disciplinesSuperCategories = []; var hvac = this.getModelRecordInfoByFileName(bl_id, 'hvac'); if(hvac){ disciplinesSuperCategories.push({title:'HVAC', name: 'HVAC', codes:hvac.categories, json:hvac.filename}); } var plumbing = this.getModelRecordInfoByFileName(bl_id, 'plumbing'); if(plumbing){ disciplinesSuperCategories.push({title:'Plumbing', name: 'Plumbing', codes:plumbing.categories, json:plumbing.filename}); } if(disciplinesSuperCategories.length > 0){ superCategories.push({title:'Disciplines', name:'Disciplines', superCategories: disciplinesSuperCategories}); } var floorElementsSuperCategories = [{title:'Interior Walls', name: 'Interior Walls', codes: interiorWallCategory, functions:['Interior'], dual:'true', json:'null'}, {title:'Curtain Panels', name: 'Curtain Panels', codes:curtainPanelCategrory, functions:['Interior'], dual:'true', json:'null'}, {title:'Doors', name:'Doors', codes:doorCategrory, functions:['Interior'], dual:'true', json:'null'}]; if(core){ floorElementsSuperCategories.push({title:'Floors', name: 'Floors', dual:'true', codes:['-2000032'], functions:['Interior'], json:'null'}); floorElementsSuperCategories.push({title:'Ceilings', name: 'Ceilings', dual:'true', codes:['-2000038'], functions:['Interior'], json:'null'}); } var lighting = this.getModelRecordInfoByFileName(bl_id, 'lighting'); if(lighting){ floorElementsSuperCategories.push({title:'Lighting', name:'Lighting', codes:lighting.categories, dual:'false', functions:lighting.functions, json:lighting.filename}); } superCategories.push({title:'Floor Elements', name:'Floor', superCategories: floorElementsSuperCategories}); superCategories.push({title:'Assets', name:'Assets', superCategories:[{title:'Rooms', name: 'Rooms', codes:['-2000160'], functions:['Interior'],json:''}, {title:'Equipment', name: 'Equipment', codes: ['-2008085','-2008079', '-2001350','-2001160' ], functions:['Interior'], json:''}, {title:'Furniture', name: 'Furniture', codes: ['-2000080', '-2001100'], functions:['Interior'], json:''}]}); //update category panel with new data this.bim3d.setSuperCategories(superCategories); //if passed bl_id is not null, its value will be displayed on category panel's top bar this.bim3d.categoriesPanel.rebuildContent(bl_id);
Level
/**
* Shows specified level.
*
* @param: levelCode, level code from afm_dwgs.model_level record value.
* @param: excludedCategories, Array like ['Rooms','Equipment'].
* @param: show, true/false.
* @param: forcedRendering, true/false.
*/
showLevel: function(levelCode, excludedCategories, show, forcedRendering)
//gets all hidden categories from categories panel
var excludedCategories = scope.bim3d.categoriesPanel.getAllCategoryCodes(false)
//shows level 1 of NB building with exception of excludedCategories
this.bim3d.showLevel('nb-level 1', excludedCategories, true, true);
Zoom
/**
* Zooms in.
*
* @param object, 3D Object.
*/
zoomIn: function(object)
//use primary key value to find targeted 3D object and zoom in.
this.bim3d.getObjectByPrimaryKey(pkValue, function(object){
//zoom in
scope.bim3d.zoomIn(object);
});
/**
* Zooms out.
*
* @param object, 3D Object.
*/
zoomOut: function(object)
//use primary key value to find targeted 3D object and zoom out.
this.bim3d.getObjectByPrimaryKey(pkValue, function(object){
//zoom out
scope.bim3d.zoomOut(object);
});
/**
* Gets current 3D screen image in 64-based string format,
*/
getImageBytes: function()
//print 3D image in PPT
var slides = [];
var image = this.bim3d.getImageBytes();
slides.push({'title': 'Equipment 3D','images':[image]});
var jobId = Workflow.startJob('AbSystemAdministration-generatePaginatedReport-generatePpt', slides, {});
View.openJobProgressBar("Please wait...", jobId, null, function(status) {
var url = status.jobFile.url;
//window.location = url;
window.open(url);
});