principal developer consultant...display simplified 2d graphics in any browser ! edit furniture...

50
A Generic Cloud-based Round-trip Real-time 2D Revit BIM Editor Jeremy Tammik Principal Developer Consultant

Upload: others

Post on 08-Aug-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

A Generic Cloud-based Round-trip Real-time 2D Revit BIM Editor Jeremy Tammik Principal Developer Consultant

Page 2: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

Jeremy Tammik Principal Developer Consultant Developer Technical Services EMEA, Autodesk SARL

Jeremy is a member of the AEC workgroup of the Autodesk Developer Network ADN team, providing developer support, training, conference presentations, and blogging on the Revit API.

He joined Autodesk in 1988 as the technology evangelist responsible for European developer support to lecture, consult, and support AutoCAD application developers in Europe, the U.S., Australia, and Africa. He was a co-founder of ADGE, the AutoCAD Developer Group Europe, and a prolific author on AutoCAD application development. He left Autodesk in 1994 to work as an HVAC application developer, and then rejoined the company in 2005.

Jeremy graduated in mathematics and physics in Germany, worked as a teacher and translator, then as a C++ programmer on early GUI and multitasking projects. He is fluent in six European languages, vegetarian, has four kids, plays the flute, likes reading, travelling, theatre improvisation, yoga, carpentry, loves mountains, oceans, sports, dancing, and especially climbing.

About the Presenter

Page 3: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

Introduction

Page 4: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Determine simplified view of BIM rooms and furniture §  Store in cloud database §  Display simplified 2D graphics in any browser §  Edit furniture position and rotation §  Update database and BIM

Room Editor Base Functionality

Page 5: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Display sheet, views and floor plan geometry §  Revit add-in part implemented

§  Improved 2D graphical editing §  Integrated Raphaël.FreeTransform module §  Unfortunately it ignores SVG view box transformation

§  Store, edit and update non-graphical property data

Room Editor Update

Page 6: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Lazy §  ... develop the three great virtues of a programmer: laziness, impatience,

and hubris – Larry Wall §  Simple

§  Simplicity is the ultimate sophistication – Leonardo da Vinci §  There is no greatness where there is no simplicity – Leo Tolstoy §  KISS

§  Perfect §  Perfection is achieved, not when there is nothing more to add, but when

there is nothing left to take away – Antoine de Saint-Exupéry

Quotes on Three Fundamental Aspects

Page 7: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  BIM – Building Information Model §  Cloud-based data repository §  2D rendering on mobile device

Data Source, Repository and Consumer Client

Page 8: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Graphical room editor on mobile device §  Update cloud database §  Reflect real-time changes in BIM

Real-time Editing Triggers Database and BIM Update

Page 9: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Simple navigation §  Home page: list all models, select one §  Model selected: list all levels, select one §  Level selected: list all rooms, select one §  Room selected: display 2D graphical editor,

click and drag furniture §  Furniture selected: display and edit properties §  Save: update database

§  Note RESTful URLs in the address bar §  The database interaction is RESTful as well

Sixty Second First Impression Demo

Page 10: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

Free and Simple

§  100% open source §  200 hours research §  < 8 hours to rebuild

§  Install components §  Re-implement from scratch §  Two implementation files

§  index.html (474 lines) §  roomedit.js (358 lines)

<html>!<head>!<meta http-equiv="Content-Type" content="text/html; charset=utf-8">!</head>!<body>!!<h1>Room Editor</h1>!!<style>!table{! border-collapse: collapse;!}!!table, th, td{! border: 0px solid black;! padding: 5px;!}!!.pointer{! cursor: pointer;!}!!button:hover{! cursor: pointer;!}!!.disable {! opacity : .35;! background-color:lightgray;!}!</style>!!<div id="content"></div>!!<ul id="navigatorlist"></ul>!!<div id="editor"></div>!!<p id="current_furniture"></p>!!<script type="text/javascript" src="modules.js"></script>!<script type="text/javascript" src="raphael-min-jt.js"></script>!<script type="text/javascript" src="roomedit.js"></script>!<script type="text/javascript">!! var three_spaces = ' \u00a0 '; // unicode &nbsp;!! var db = require('db').current();! var $ = require('jquery');!! var furniture;! var current_furniture = null;! var current_furniture_doc = null;! var all_furniture = [];!! var xmin;! var ymin;! var xscale;! var yscale;! var tooltip;! var tooltip_bg;! var paper;!! // convert URL parameters to dictionary!! var url = this.location;!! var paramdict = {};! var params = url.href.split("?");!! if( 1 < params.length ) {! url = params[0];! paramdict = get_url_paramdict( params[1] );! }!! if (paramdict.hasOwnProperty('furnitureid')){!! //======================================================! // display and edit the selected element properties! //======================================================!! var fid = paramdict['furnitureid'];! db.getDoc( fid,! function(err,resp) {! if (err) {! alert(JSON.stringify(err));! }! current_furniture_doc = resp;! var rid = current_furniture_doc.roomId;! var a = current_furniture_doc.properties;!! var p = $('<p/>').appendTo('#content');! p.append( $('<a/>').text('Home').attr('href',url) );! p.append( document.createTextNode( three_spaces ) );! p.append( $('<a/>')! .text('Back')! .attr('href', url + '?roomid=' + rid ) );!! p = p.append($('<p/>').text(! 'Element properties of '! + current_furniture_doc.name + ':' ));!! var keys = jt_get_keys( a );! keys.sort();!! var table = p.append($('<table/>'));! var n = keys.length;! for( var i=0; i<n; ++i ) {! var key = keys[i];! var val = a[key];! var key_label = capitalise(key);! var key_id = unspace(key);! var readonly = ('r' == val[0]);! v = val.slice(2);! table.append( '<tr><td>' + key_label! + ':</td><td><input type="text" id="' + key_id! + '" value="' + v + '"'! + (readonly ? ' readonly class="disable"' : '')! + '></td></tr>' );! }! table.append($('<br/>'));!! table.append($('<input/>')! .attr( 'type', 'button')! .attr( 'value', 'OK')! .attr( 'onclick',! 'save_properties(current_furniture_doc,true)'));!! table.append( document! .createTextNode( three_spaces ) );!! table.append($('<input/>')!

.attr( 'type', 'button')! .attr( 'value', 'Cancel')! .attr( 'onclick',! 'save_properties(current_furniture_doc,false)'));! }! );! }! else if (paramdict.hasOwnProperty('roomid')){!! //======================================================! // display the selected room and its furniture! //======================================================!! var rid = paramdict['roomid'];! db.getDoc( rid,! function(err,resp) {! if (err) {! alert(JSON.stringify(err));! }! var roomdoc = resp;! var lid = roomdoc.levelId;! db.getDoc( lid,! function(err,resp) {! if (err) {! alert(JSON.stringify(err));! }! var leveldoc = resp;! var mid = leveldoc.modelId;! db.getDoc( mid,! function(err,resp) {! if (err) {! alert(JSON.stringify(err));! }! var modeldoc = resp;! var q = { key: JSON.stringify(rid) };! db.getView('roomedit', 'map_room_to_furniture', q,! function (err, data) {! if (err) {! alert(JSON.stringify(err));! }! var furniture=[];! var symbol_ids = [];! var n = data.rows.length;! for (var i = 0; i < n; ++i) {! var instdoc = data.rows[i].value;! var fid = instdoc._id;! console.log( 'doc id ' + fid + ' ' + instdoc.name );! if( instdoc.roomId != rid ) {! alert( 'room ids differ in furniture ' + instdoc._id! + ':\ndoc ' + instdoc.roomId + "\nurl " + rid );! }! var sid = instdoc.symbolId;! furniture.push(instdoc);! symbol_ids.push( sid );! }! var q2 = { keys: JSON.stringify(symbol_ids) };! db.getView('roomedit', 'symbols', q2,! function (err, data) {! if (err) {! alert(JSON.stringify(err));! }! var n2 = data.rows.length;! var map_symbid_to_loop = {};! for( var i = 0; i < n2; ++i ) {! var symbdoc = data.rows[i].value;! map_symbid_to_loop[symbdoc._id] = symbdoc.loop;! }! for( var i = 0; i < furniture.length; ++i ) {! furniture[i].loop = map_symbid_to_loop[furniture[i].symbolId];! }! var url_model = url + '?modelid=' + mid;! var url_level = url + '?levelid=' + lid;! var url_room = url + '?roomid=' + rid;!! $('#content').append( $('<table/>')! .append( $('<tr>')! .append( $('<td>').text( 'Start:' ) )! .append( $('<td>')! .append( $('<a>')! .text('Home')! .attr('href',url) )))! .append( $('<tr>')! .append( $('<td>').text( 'Model:' ) )! .append( $('<td>')! .append( $('<a>')! .text(modeldoc.name)! .attr('href',url_model) )))! .append( $('<tr>')! .append( $('<td>').text( 'Level:' ) )! .append( $('<td>')! .append( $('<a>')! .text(leveldoc.name)! .attr('href',url_level) )))! .append( $('<tr>')! .append( $('<td>').text( 'Room:' ) )! .append( $('<td>')! .append( $('<a>')! .text(roomdoc.name)! .attr('href',url_room) ))))! .append($('<p/>')! .text( n.toString()! + ' furniture and equipment item' + pluralSuffix( n )! + ' in room ' )! .append( $('<i/>').text( roomdoc.name ) )! .append( document.createTextNode( ' on level ' ) )! .append( $('<i/>').text( leveldoc.name ) )! .append( document.createTextNode( ' in model ' ) )! .append( $('<i/>').text( modeldoc.name ) )! .append( document.createTextNode( '.' ) ) )! .append($('<p/>')! .text( 'Please pick and drag furniture '! + 'and equipment around to select

and move it, '! + 'then click the buttons to rotate clockwise, '! + 'counter-clockwise, refresh, and save.' ));!! var p = $('<p/>').appendTo('#content');!! p.append( $('<button/>').text('Properties')! .attr('onclick', 'edit_properties_current(url)' ) );! p.append( document.createTextNode( three_spaces ) );! p.append( $('<button/>').text('Rotate')! .attr('onclick', 'rotate_current_cw()' ) );! p.append( document.createTextNode( three_spaces ) );! p.append( $('<button/>').text('Ccw')! .attr('onclick', 'rotate_current_ccw()' ) );! p.append( document.createTextNode( three_spaces ) );! p.append( $('<button/>').text('Refresh')! .attr('onclick', 'refresh()' ) );! p.append( document.createTextNode( three_spaces ) );! p.append( $('<button/>').text('Save')! .attr('id', 'save')! .attr('onclick', 'save_all()' ) );!! raphael( roomdoc, furniture );! }! );! }! );! }! );! }! );! }! );! }! else if( paramdict.hasOwnProperty( 'levelid' ) ) {!! //======================================================! // display a menu of all rooms on selected level! //======================================================!! var lid = paramdict['levelid'];! db.getDoc( lid,! function(err,resp) {! if (err) {! alert(JSON.stringify(err));! }! var leveldoc = resp;! var mid = leveldoc.modelId;! db.getDoc( mid,! function(err,resp) {! if (err) {! alert(JSON.stringify(err));! }! var modeldoc = resp;! db.getView('roomedit',! 'map_level_to_room',! { key: JSON.stringify(lid) },!! function (err, data) {! if (err) {! alert(JSON.stringify(err));! }!! var url_model = url + '?modelid=' + mid;! var url_level = url + '?levelid=' + lid;!! $('#content').append( $('<table/>')! .append( $('<tr>')! .append( $('<td>').text( 'Start:' ) )! .append( $('<td>')! .append( $('<a>')! .text('Home')! .attr('href',url) )))! .append( $('<tr>')! .append( $('<td>').text( 'Model:' ) )! .append( $('<td>')! .append( $('<a>')! .text(modeldoc.name)! .attr('href',url_model) )))! .append( $('<tr>')! .append( $('<td>').text( 'Level:' ) )! .append( $('<td>')! .append( $('<a>')! .text(leveldoc.name)! .attr('href',url_level) ))));!! var n = data.rows.length;!! var p = $('<p/>').text( n.toString()! + ' room' + pluralSuffix( n )! + ' on level ' ).appendTo('#content');! p.append( $('<i/>').text( leveldoc.name ) );! p.append( document.createTextNode( ' in model ' ) );! p.append( $('<i/>').text( modeldoc.name ) );! p.append( document.createTextNode( '.' ) );! p.append( $('<p/>').text( 'Please select one:' ));!! for (var i = 0; i < n; ++i) {! var doc = data.rows[i].value;! if( doc.levelId != lid ) {! alert( 'model ids differ: doc ' + doc.levelId! + ", url " + lid );! }! var s = url + '?roomid=' + doc._id;! $('<li/>')! .append($('<a>')! .attr('href',s)! .text(doc.name))! .appendTo('#navigatorlist');! }! }! );! }! );! }! );! }! else if ( paramdict.hasOwnProperty( 'modelid' ) ) {!

! //===========================================================! // display a menu of all levels and sheets in selected model! //===========================================================!! var mid = paramdict['modelid'];! db.getDoc( mid,! function(err,resp) {! if (err) {! alert(JSON.stringify(err));! }! var modeldoc = resp;! db.getView('roomedit',! 'map_model_to_level_and_sheet',! { key: JSON.stringify(mid) },!! function (err, data) {! if (err) {! alert(JSON.stringify(err));! }! var url_model = url + '?modelid=' + mid;!! $('#content').append( $('<table/>')! .append( $('<tr>')! .append( $('<td>').text( 'Start:' ) )! .append( $('<td>')! .append( $('<a>')! .text('Home')! .attr('href',url) )))! .append( $('<tr>')! .append( $('<td>').text( 'Model:' ) )! .append( $('<td>')! .append( $('<a>')! .text(modeldoc.name)! .attr('href',url_model) ))));!! var n = data.rows.length;! var nLevel = 0;! var nSheet = 0;! for (var i = 0; i < n; ++i) {! var doc = data.rows[i].value;! if( doc.modelId != mid ) {! alert( 'model ids differ: doc '! + doc.modelId + ", url " + mid );! }! var t = doc.type; // level or sheet! var s = url;!! if( 'level' == t ) {! ++nLevel;! }! else {! ++nSheet;! s = s.replace( 'index.html', 'index2.html' );! }!! s += '?' + t + 'id=' + doc._id;!! t = t.substr(0,1).toUpperCase() + t.substr(1);!! $('<li/>')! .append(document.createTextNode(t + ': '))! .append($('<a>').attr('href',s).text(doc.name))! .appendTo('#navigatorlist');! }! var prompt =! nLevel.toString() + ' level' + pluralSuffix( nLevel ) + ' and ' +! nSheet.toString() + ' sheet' + pluralSuffix( nSheet ) + ' in model ';!! $('#content')! .append($('<p/>')! .text( prompt )! .append( $('<i/>').text( modeldoc.name ) )! .append( document.createTextNode( '.' ) ) )! .append($('<p/>')! .text( 'Please select a level or sheet:' ) );! }! );! }! );! }! else {!! //======================================================! // display a menu of all available models! //======================================================!! db.getView('roomedit', 'models',! function (err, data) {! if (err) {! alert(JSON.stringify(err));! }! var n = data.rows.length;!! $('#content')! .append($('<p/>')! .text( n.toString() + ' model' + pluralSuffix( n )! + ' available. Please select one:' ));!! var list = $('#navigatorlist');!! for (var i = 0; i < n; ++i) {! var doc = data.rows[i].key;! var s = url + '?modelid=' + doc._id;! list.append($('<li/>')! .append($('<a>').attr('href',s).text(doc.name)));! }! }! );! }!</script>!</body>!</html>!!

Page 11: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Index.html §  Roomedit.js §  One day to extract data from Revit §  One day to enhance database, editor, update etc.

Update Splits Functionality

Page 12: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

Architecture

Page 13: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  BIM – Revit §  Data repository – NoSQL §  Rendering and editing – HTML and SVG

Base Technologies

Page 14: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Revit BIM – Revit .NET add-in §  NoSQL Database – Apache CouchDB §  HTML, SVG – JavaScript, jquery, db, Raphaël

Implementation Environment

Page 15: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Same origin policy §  Server-side scripting §  Two components instead of three

Simpler Still

js  

Page 16: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Revit add-in §  CouchDB database

The Two and Only Projects

Page 17: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

Cloud Database

Page 18: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  “Not only SQL” §  Next generation database paradigm §  Address some of the points: non-relational, distributed,

open-source, scalable, huge amounts of data §  Frequent other characteristics: schema-free, easy

replication support, simple API, eventually consistent, i.e., BASE, not ACID §  http://nosql-database.org, https://en.wikipedia.org/wiki/NoSQL,

http://www.mongodb.com/nosql-explained

NoSQL

Page 19: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  ACID §  Atomicity, Consistency, Isolation and Durability guarantee that database

transactions are processed reliably

§  CAP Theorem §  The ACID paradigm cannot simultaneously guarantee consistency,

availability and partition tolerance (distributed system)

§  BASE §  Basic Availability, Soft-state, Eventual consistency §  Not guaranteed to be in a consistent state at a given moment §  Consistency is guaranteed, eventually

http://thebuildingcoder.typepad.com/blog/2014/05/views-displaying-given-element-svg-and-nosql.html#5

ACID versus Base and CAP Theorem

Page 20: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Everything is a document §  All documents are JSON §  Every document has built-in id and revision §  The database design is also a document §  The design defines views and attachments

CouchDB Database Implementation

Page 21: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Relax! §  All interactions are REST §  Management console is Futon

http://127.0.0.1:5984/_utils/!

§  Access all documents http://127.0.0.1:5984/roomedit/_all_docs!

§  Include full doc data, not just id and revision http://127.0.0.1:5984/roomedit/_all_docs?include_docs=true!!!

CouchDB Database Interaction

Page 22: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Model – a RVT project file §  Level §  Room §  FamilyInstance represents furniture or equipment §  FamilySymbol defines geometry

BIM Model

Page 23: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Room has boundary loops and can contain holes §  FamilySymbol has a single boundary loop §  FamilyInstance has a 2D placement

§  Translation §  Rotation

BIM Object Graphics

Page 24: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  CouchDB ids are Revit unique ids §  Family instance → room → level → model §  Family instance → symbol

BIM Object Relationships

Page 25: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  DbObj base class §  DbModel §  DbLevel §  DbRoom §  DbFurniture §  DbSymbol

NoSQL Database Structure

Page 26: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  DbFurniture.symbolId → DbSymbol §  DbFurniture.roomId → DbRoom §  DbRoom.levelId → DbLevel §  DbLevel.modelId → DbModel

Database Object Relationships

Page 27: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  All graphics represented by SVG path element data !<svg width="4cm" height="4cm" viewBox="0 0 400 400"! xmlns="http://www.w3.org/2000/svg" version="1.1">! <rect x="1" y="1" width="398" height="398"! fill="none" stroke="blue" />! <path d="M 100 100 L 300 100 L 200 300 z"! fill="red" stroke="blue" stroke-width="3" />!</svg>!

Database Object Graphics and Placement

Page 28: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Family symbol §  Define geometry

!{! "_id": "11cc6e52-519e-49b2-9813-c9561b59a1fd-0005f5fc",! "_rev": "1-d575ca095533db4ccbed9f7ab2607a12",! "loop": "M-191 922 L190 922 216 862 190 859 -191 859 -216 862 -216 919Z",! "type": "symbol",! "description": "FamilySymbol Furniture <390652 Table ronde a chaises>",! "name": "Table ronde avec chaises - 01"!}!!!

JSON Symbol Database Document

Page 29: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Furniture doc represents family instance and defines §  Relationship to room and family symbol §  Placement = transform = translation + rotation

!{! "_id": "11cc6e52-519e-49b2-9813-c9561b59a1fd-0005f65b",! "_rev": "1-c1b4fc969181267b55dab4c6857fc5d7",! "roomId": "cbe571b0-0593-4350-a8e6-abf3c9239325-00061210",! "symbolId": "11cc6e52-519e-49b2-9813-c9561b59a1fd-0005fe6d",! "transform": "R-90T-10429,1020",! "type": "furniture",! "description": "FamilyInstance Furniture <390747 Canapé 3 places>",! "name": "Canapé 3 places"!}!!

JSON Instance Database Document

Page 30: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  A view defines a map and optional reduce function §  The map produces key-value pairs §  Reduce produces an accumulation

!exports.models = {! map: function (doc) {! if( 'model' == doc.type ) {! emit(doc, null);! }! }, ! reduce: function (key, values, rereduce) {! return sum(values);! }!}!

CouchDB Views

Page 31: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

Room Editor Views

§  models §  levels §  rooms §  furniture §  symbols §  map_room_to_furniture §  map_level_to_room §  map_model_to_level

rooms = {! map: function (doc) {! if( 'room' == doc.type ) {! emit(doc, null);! }! }!};!!!map_level_to_room = {! map: function (doc) {! if( 'room' == doc.type ) {! emit(doc.levelId, doc);! }! }!};!!

Page 32: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Specific document !http://127.0.0.1:5984/roomedit/11cc6e52-519e-49b2-9813-c9561b59a1fd-0005f5fc!!

§  Specific view !http://127.0.0.1:5984/roomedit/_design/roomedit/_view/models!!

§  Specific key in view !http://127.0.0.1:5984/roomedit/_design/roomedit/_view/map_level_to_room?key=%22933c4a06-93b8-11d3-80f8-00c04f8efc32-0000001e%22!

RESTful CouchDB Document and View Access URLs

Page 33: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

Entire CouchDB Application Definition

§  Kanso loads CouchDB roomedit/data/room_model_9.json!roomedit/index.html!roomedit/kanso.json!roomedit/lib/app.js!roomedit/lib/views.js!roomedit/raphael-min-jt.js!roomedit/roomedit.js!

http://kan.so!!

§  kanso.json !{! "name": "roomedit",! "attachments": ["index.html",! "raphael-min-jt.js"],! "modules": ["lib"],! "load": "lib/app",! "dependencies": {! "attachments": null,! "modules": null,! "properties": null,! "db": null,! "jquery": null! }!}!

Page 34: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  HTML scaffolding §  JavaScript query section §  Raphaël SVG generation and interaction §  RESTful database updates §  Called with

§  No argument: list all models §  Model id: list all levels in model §  Level id: list all rooms on level §  Room id: display graphical editor and enable database updates

Index.html

Page 35: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

<h1>Room Editor</h1>!!<div id="content"></div>!!<ul id="navigatorlist"></ul>!!<div id="editor"></div>!!<p id="current_furniture"></p>!!<script type="text/javascript" src="modules.js"></script>!<script type="text/javascript" src="raphael-min-jt.js"></script>!!

§  Populated entirely using JavaScript adding HTML and SVG nodes using jquery, raphael and db for CouchDB queries

Minimal Predefined HTML Scaffolding

Page 36: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

List all Models

§  No input parameter §  View ‘models’, no key §  Populate navigator list

db.getView('roomedit', 'models',! function (err, data) {! if (err) {!

return alert(err);! }! var n = data.rows.length;! for (var i = 0; i < n; ++i) {! var doc = data.rows[i].key;! var s = url + '?modelid=' + doc._id;!

$('<li/>').append($('<a>')! .attr('href',s)! .text(doc.name))! .appendTo('#navigatorlist');! }! var p = $('<p/>').appendTo('#content');!

p.append( $('<a/>').text('Home').attr('href',url) );! p.append( document.createTextNode( three_spaces ) );! p.append( $('<a/>').text('Back').attr('href',url) );!! $('<p/>')! .text( 'Please select a model in the list below.' )! .appendTo('#content');!

! $('<p/>')! .text(n.toString() + ' model’ + pluralSuffix( n ) + dotOrColon( n ) )! .appendTo('#content');! }!);!

!!

Page 37: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Input parameter ‘modelId’ §  Get model document itself

§  Display current selection §  View ‘map_model_to_level’ with model id key

§  Populate navigator list

List all Levels in Selected Model

Page 38: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Input parameter ‘levelId’ §  Get level document itself → model id §  Get model document

§  Display current selection §  View ‘map_level_to_room’ with level id key

§  Populate navigator list

List all Rooms on Selected Level

Page 39: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Input parameter ‘roomId’ §  Get room document itself → level id §  Get level document → model id §  Get model document

§  Display current selection §  View ‘map_room_to_furniture’ with key room id §  Retrieve family instances → symbol ids §  View ‘symbols’ with list of symbol keys

§  Populate and display SVG editor

Display and Edit a Selected Room

Page 40: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Nested asynchronous database queries §  Each nested query depends on previous results §  Page cannot be displayed until all complete §  Nested callback functions

Nested Database Queries and Callback Functions

Page 41: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Using jquery and Raphaël §  Input room + furniture populated with symbol SVG path §  Determine size and aspect ratio §  Instantiate paper = canvas §  Place room and attach tooltip events mouseover + out §  Place furniture and attach identification, drag and

tooltip events

SVG Room Editor

Page 42: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

Revit Add-in

Page 43: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Determine 2D boundary polygon loops §  Upload model to database §  Download changes from database §  Subscribe to real-time updates §  Timer and external event

Revit Add-in

Page 44: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  How does the Revit add-in access CouchDB? §  Upload model data §  Retrieve database changes §  Subscribe to changes

§  DreamSeat https://github.com/vdaron/DreamSeat!

§  Easy! §  Good job!

Revit Add-in Interaction with CouchDB

Page 45: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

Conclusion

Page 46: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  Many! §  NoSQL, CouchDB, views, CouchApp and Kanso §  JavaScript, SVG, event handling, mobile devices §  Mapping to negative Y axis and restore for update §  Handle nested database callback functions §  Retrieving database changes §  Idling versus external event §  This is a simple learning sample §  Infinite possible real-life applications

Challenges

Page 47: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  PouchDB – put it in your pocket §  Open-source JavaScript database §  Inspired by Apache CouchDB §  Designed to run in the browser §  Work offline as well as online §  Store data locally while offline §  Synchronize with CouchDB when online §  Keep data in sync no matter where

§  http://pouchdb.com

Latest News – On the Road

Page 48: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  NoSQL is great! §  Open source is free and effective §  REST and JSON is powerful and simple to work with §  Server-side scripting pays off

§  Avoid programming on the mobile device itself §  KISS!

Conclusion

Page 49: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

§  The Building Coder Revit API blog and categories §  http://thebuildingcoder.typepad.com

§  Cloud §  Desktop §  Mobile

§  GitHub repositories §  https://github.com/jeremytammik

§  RoomEditorApp – Revit add-in §  Roomedit – CouchDB definition

§  Room editor playground §  http://jt.iriscouch.com/roomedit/_design/roomedit/index.html

Room Editor Documentation and Materials

Page 50: Principal Developer Consultant...Display simplified 2D graphics in any browser ! Edit furniture position and rotation ... Integrated Raphaël.FreeTransform module ! Unfortunately it

Autodesk is a registered trademark of Autodesk, Inc., and/or its subsidiaries and/or affiliates in the USA and/or other countries. All other brand names, product names, or trademarks belong to their respective holders. Autodesk reserves the right to alter product and services offerings, and specifications and pricing at any time without notice, and is not responsible for typographical or graphical errors that may appear in this document. © 2014 Autodesk, Inc. All rights reserved.