';
-```
-Run the server from the Node.js console, by running the following command:
-```
-node server.js
-```
-
-
-### View your model in a web browser
-
-Connect to your local server using a WebGL-compatible browser:
-
-[http://localhost:3000/](http://localhost:3000/)
-
-Note that we use port 3000 and not the default http port 80 because if you are on Mac OSX or use Skype, port 80 may already be in use.
-If you want to use port 80 to avoid having to specify the port in the URL, edit the server.js file, change the default port from 3000 to 80 and restart the node.js server.
-
-
-=========================
-[Next](chapter-2.md#Chapter2) -
-[Home](README.md)
\ No newline at end of file
diff --git a/chapter-3.md b/chapter-3.md
deleted file mode 100644
index 38795c8..0000000
--- a/chapter-3.md
+++ /dev/null
@@ -1,500 +0,0 @@
-
-# Customize the Viewer Behavior
-
-- [Step 1 Creating a basic extension](#Step1)
-- [Step 2 Reference the extension script](#Step2)
-- [Step 3 Load the extension in the viewer](#Step3)
-- [Step 4 Testing the extension](#Step4)
-- [Step 5 Adding a selection handler](#Step5)
-- [Step 6 Displaying a panel](#Step6)
-- [Step 7 (Bonus step) Moving the camera](#Step7)
-- [Even more bonus steps](#More)
-
-
-Now you've got a basic 2D/3D model displayed on your web page, let's customize the viewer behavior. The simplest way to customize behavior is through the Extension mechanism.
-Extensions allow you to encapsulate your customized behavior in a separate JavaScript file that you can 'load' into the viewer when it's running (you can unload it whenever you like too).
-
-
-
-## Step 1 Creating a basic extension
-
-Create a file named "Viewing.Extension.Workshop.js" (for example), and save it in the www subfolder of the project folder you cloned from GitHub (workflow-node.js-view.and.data.api).
-Then copy the following basic extension skeleton code into the file and save it:
-
- ///////////////////////////////////////////////////////////////////////////////
- // Demo Workshop Viewer Extension
- // by Philippe Leefsma, April 2015
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- AutodeskNamespace("Viewing.Extension");
-
- Viewing.Extension.Workshop = function (viewer, options) {
-
- /////////////////////////////////////////////////////////////////
- // base class constructor
- //
- /////////////////////////////////////////////////////////////////
-
- Autodesk.Viewing.Extension.call(this, viewer, options);
-
- var _self = this;
- var _viewer = viewer;
-
- /////////////////////////////////////////////////////////////////
- // load callback: invoked when viewer.loadExtension is called
- //
- /////////////////////////////////////////////////////////////////
-
- _self.load = function () {
-
- alert('Viewing.Extension.Workshop loaded');
- console.log('Viewing.Extension.Workshop loaded');
-
- return true;
-
- };
-
- /////////////////////////////////////////////////////////////////
- // unload callback: invoked when viewer.unloadExtension is called
- //
- /////////////////////////////////////////////////////////////////
-
- _self.unload = function () {
-
- console.log('Viewing.Extension.Workshop unloaded');
-
- return true;
-
- };
-
- };
-
- /////////////////////////////////////////////////////////////////
- // sets up inheritance for extension and register
- //
- /////////////////////////////////////////////////////////////////
-
- Viewing.Extension.Workshop.prototype =
- Object.create(Autodesk.Viewing.Extension.prototype);
-
- Viewing.Extension.Workshop.prototype.constructor =
- Viewing.Extension.Workshop;
-
- Autodesk.Viewing.theExtensionManager.registerExtension(
- 'Viewing.Extension.Workshop',
- Viewing.Extension.Workshop);
-
-
-
-## Step 2 Reference the extension script
-
-Reference the extension file in your index.html by adding the following script element to the header (change the path if you installed the file anywhere other than the www subfolder):
-
-
-
-
-
-## Step 3 Load the extension in the viewer
-
-All that remains for index.js is to add some code to load the extension into the viewer once it is initialized. If the extension relies on geometry in the model, you should set up an
-event to wait for the GOEMETRY_LOADED event, as some features may not be usable if the geometry in not fully loaded.
-
-Open index.js and locate the place where you load the viewable in your viewer code:
-
- viewer.load(pathInfoCollection.path3d[0].path);
- },
- onError);
- });
-
- function onError(error) {
- console.log('Error: ' + error);
- };
-
-and add the event handler immediately before this line of code, then add a method where you will load the extensions:
-
-
- viewer.addEventListener(
- Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
- function(event) {
- loadExtensions(viewer);
- });
-
-
- viewer.load(pathInfoCollection.path3d[0].path);
- },
- onError);
-
- });
-
- function loadExtensions(viewer) {
- viewer.loadExtension('Viewing.Extension.Workshop');
- }
-
-
- function onError(error) {
- console.log('Error: ' + error);
- };
-
-
-Note: If you copy the modified index.js file from the Step 3 folder in the tutorial [repository](https://github.com/Developer-Autodesk/tutorial-getting.started-view.and.data), make sure
-you edit the defaultURN on line 18 to use the URN of the translated file you created at the beginning of the tutorial.
-
-
-
-## Step 4 Testing the extension
-
-Your barebones extension should be ready to run now. All it does is display an alert when it's loaded. Test that the extension is loaded properly by running your sample.
-(Remember that you setup your node.js project to serve the client page to [http://localhost:3000/](http://localhost:3000/), so open your WebGL-enabled browser and type
-that address in the address bar). Since all our changes are on client side, you can just refresh your browser to test your changes.
-
-
-
-## Step 5 Adding a selection handler
-
-Now we will add some more interesting functionality to the basic extension:
-
-Start by adding a handler for the SELECTION_CHANGED event to the Extension (i.e. editing the file 'Viewing.Extension.Workshop.js'). This event is triggered when user
-selects a component in the model. Register your handler callback in the _self.load function, and then add the function definition below.
-
- _self.load = function () {
-
-
- _viewer.addEventListener(
- Autodesk.Viewing.SELECTION_CHANGED_EVENT,
- _self.onSelectionChanged);
-
-
- console.log('Viewing.Extension.Workshop loaded');
-
- return true;
- };
-
-
- /////////////////////////////////////////////////////////////////
- // selection changed callback
- //
- /////////////////////////////////////////////////////////////////
- _self.onSelectionChanged = function (event) {
-
- // event is triggered also when component is unselected
-
- // in that case event.dbIdArray is an empty array
- if(event.dbIdArray.length) {
-
- var dbId = event.dbIdArray[0];
-
- //do stuff with selected component
- }
- else {
-
-
- //all components unselected
- }
- }
-
-
-
-
-Every element in the displayed model has a unique ID called a dbId. The code you've just written simply stores the dbId of the first element in the list of elements that the
-user selected. (Usually, the user will only select a single element, but more complete code would handle multiple selected elements).
-
-You can test your code now, if you like. Put a breakpoint in the event handler to check its being called when you select an element. You can use Developer
-Tool of Chrome or similar tools in other modern browsers to do debugging like setting breaking point, watch variable values, etc. (Hint: You select a model
-element by clicking it with you mouse; elements are highlighted in blue when selected).
-
-
-
-## Step 6 Displaying a panel
-
-Now we'll get properties of selected component and display them in a custom viewer panel. Using the viewer UI to create your extensions will help migrating code from one
-project to another. It helps making your extension non-dependent of the client. However, you can manipulate any other component of your web application from the extension
-you could read or write information stored in a separate database, or update a table somewhere else on the webpage., etc, etc.
-
-Add some code to initialize an empty panel in the body of your extension:
-
-
- /////////////////////////////////////////////////////////////////
- // base class constructor
- //
- /////////////////////////////////////////////////////////////////
-
- Autodesk.Viewing.Extension.call(this, viewer, options);
-
- var _self = this;
-
- var _viewer = viewer;
-
- /////////////////////////////////////////////////////////////////
- // creates panel and sets up inheritance
- //
- /////////////////////////////////////////////////////////////////
-
- Viewing.Extension.Workshop.WorkshopPanel = function(
- parentContainer,
- id,
- title,
- options)
- {
- Autodesk.Viewing.UI.PropertyPanel.call(
- this,
- parentContainer,
- id, title);
- };
-
- Viewing.Extension.Workshop.WorkshopPanel.prototype = Object.create(
- Autodesk.Viewing.UI.PropertyPanel.prototype);
-
- Viewing.Extension.Workshop.WorkshopPanel.prototype.constructor =
- Viewing.Extension.Workshop.WorkshopPanel;
-
- /////////////////////////////////////////////////////////////////
- // load callback: invoked when viewer.loadExtension is called
- //
- /////////////////////////////////////////////////////////////////
-
- _self.load = function () {
-
-
-Instantiate the panel in your load method, uninitialize it in unload. Edit _self.load and _self.unload as follows
-
-
- /////////////////////////////////////////////////////////////////
- // load callback: invoked when viewer.loadExtension is called
- //
- /////////////////////////////////////////////////////////////////
- _self.load = function () {
-
-
- _viewer.addEventListener(
- Autodesk.Viewing.SELECTION_CHANGED_EVENT,
- _self.onSelectionChanged);
-
-
- _self.panel = new Viewing.Extension.Workshop.WorkshopPanel (
- _viewer.container,
- 'WorkshopPanelId',
- 'Workshop Panel');
-
-
- console.log('Viewing.Extension.Workshop loaded');
-
- return true;
- };
-
- /////////////////////////////////////////////////////////////////
- // unload callback: invoked when viewer.unloadExtension is called
- //
- /////////////////////////////////////////////////////////////////
- _self.unload = function () {
-
-
- _self.panel.setVisible(false);
-
-
- _self.panel.uninitialize();
-
-
- console.log('Viewing.Extension.Workshop unloaded');
-
-
- return true;
- };
-
-
-Replace the implementation of the selection handler with the following code, so the panel is populated with the properties of the selected element and displayed when an item is selected.
-Just for fun, we also isolate the component that is clicked:
-
-
- /////////////////////////////////////////////////////////////////
- // selection changed callback
- //
- /////////////////////////////////////////////////////////////////
- _self.onSelectionChanged = function (event) {
-
-
- function propertiesHandler(result) {
-
- if (result.properties) {
- _self.panel.setProperties(
- result.properties);
- _self.panel.setVisible(true);
- }
- }
-
-
- if(event.dbIdArray.length) {
- var dbId = event.dbIdArray[0];
-
- _viewer.getProperties(
- dbId,
- propertiesHandler);
-
- _viewer.fitToView(dbId);
- _viewer.isolateById(dbId);
- }
- else {
-
- _viewer.isolateById([]);
- _viewer.fitToView();
- _self.panel.setVisible(false);
- }
-
- }
-
-
-
-
-You've now finished writing your extension to respond to a user selecting a model element by displaying that element's properties in a panel and isolating that element in the view.
-Launch the client page and select a model element by clicking on it. The model and camera view reset if you clear your selection or click in space.
-
-
-
-## Step 7 (Bonus step) Moving the camera
-
-Finally, we'll add some camera animation orbiting the camera around the model. We will use a simple approach with setInterval. For a more robust approach, take a look at this blog post:
-
-[http://adndevblog.typepad.com/cloud_and_mobile/2015/04/how-to-create-animations-in-the-viewer.html](http://adndevblog.typepad.com/cloud_and_mobile/2015/04/how-to-create-animations-in-the-viewer.html)
-
-Add a property the extension to hold the interval Id, so we can cancel it.
-
- _self.load = function () {
-
- _viewer.addEventListener(
- Autodesk.Viewing.SELECTION_CHANGED_EVENT,
- _self.onSelectionChanged);
-
- _self.panel = new Viewing.Extension.Workshop.WorkshopPanel (
- _viewer.container,
- 'WorkshopPanelId',
- 'Workshop Panel');
-
-
- _self.interval = 0;
-
-
- console.log('Viewing.Extension.Workshop loaded');
-
- return true;
- };
-
-Add following methods to handle the animation immediately below the end of the _self.onSelectionChanged function implementation.
-
- /////////////////////////////////////////////////////////////////
- // rotates camera around axis with center origin
- //
- /////////////////////////////////////////////////////////////////
- _self.rotateCamera = function(angle, axis) {
- var pos = _viewer.navigation.getPosition();
-
- var position = new THREE.Vector3(
- pos.x, pos.y, pos.z);
- var rAxis = new THREE.Vector3(
- axis.x, axis.y, axis.z);
-
- var matrix = new THREE.Matrix4().makeRotationAxis(
- rAxis,
- angle);
-
- position.applyMatrix4(matrix);
-
- _viewer.navigation.setPosition(position);
-
- };
-
- /////////////////////////////////////////////////////////////////
- // start rotation effect
- //
- /////////////////////////////////////////////////////////////////
-
- _self.startRotation = function() {
- clearInterval(_self.interval);
-
- // sets small delay before starting rotation
-
- setTimeout(function() {
- _self.interval = setInterval(function () {
- _self.rotateCamera(0.05, {x:0, y:1, z:0});
- }, 100)}, 500);
-
- };
-
-Finally modify the selection handler to trigger the animation when a component is selected:
-
- /////////////////////////////////////////////////////////////////
- // selection changed callback
- //
- /////////////////////////////////////////////////////////////////
- _self.onSelectionChanged = function (event) {
-
- function propertiesHandler(result) {
-
- if (result.properties) {
-
- _self.panel.setProperties(
- result.properties);
-
- _self.panel.setVisible(true);
- }
- }
-
-
- if(event.dbIdArray.length) {
-
- var dbId = event.dbIdArray[0];
-
- _viewer.getProperties(
- dbId,
- propertiesHandler);
-
- _viewer.fitToView(dbId);
- _viewer.isolateById(dbId);
-
- _self.startRotation();
-
- }
- else {
-
- clearInterval(_self.interval);
-
- _viewer.isolateById([]);
- _viewer.fitToView();
- _self.panel.setVisible(false);
- }
- }
-
-
-
-
-
-Test your extension again. This time, in addition to displaying the panel, the camera (your view of the model) starts rotating when you select a model element.
-
-
-
-## Even more bonus steps
-
-If you've still got some time, go to [http://gallery.autodesk.io](http://gallery.autodesk.io) and play with some of the models and sample extensions available there.
-The 'Car' model is reasonably detailed ( [http://viewer.autodesk.io/node/gallery/#/viewer?id=551d0768be86fc2c1138b4d4](http://viewer.autodesk.io/node/gallery/#/viewer?id=551d0768be86fc2c1138b4d4)).
-To test one of the sample Extensions, click on the Extensions menu, then click Manage and click on an Extension's name to enable or disable it. We recommend you only
-enable one Extension at a time (i.e. disable the last Extension you used before enabling another), because not all the Extensions have been written to play nicely with
-other Extensions.
-
-To see the source code for those Extensions, go to Extensions and select Source. Then click on the name of the Extension you're interested in.
-
-Here are two YouTube videos explaining how to use the gallery sample and a couple of the extensions:
-
-[https://www.youtube.com/watch?v=SQJSuqRqiCg](https://www.youtube.com/watch?v=SQJSuqRqiCg)
-
-[https://www.youtube.com/watch?v=tK2ndbvchIM](https://www.youtube.com/watch?v=tK2ndbvchIM)
-
-
-
-## Solution
-
-You can get the final source code as zip from [here](https://github.com/Developer-Autodesk/workflow-node.js-view.and.data.api/archive/v1.0-workshop-extension.zip), or using git:
-```
-git checkout v1.0-workshop-extension
-```
-
-=========================
-[Home](README.md)
diff --git a/chapters/chapter-1.md b/chapters/chapter-1.md
new file mode 100644
index 0000000..069dc5f
--- /dev/null
+++ b/chapters/chapter-1.md
@@ -0,0 +1,163 @@
+
+# Chapter 1 – Get ready with Model Derivative API
+
+- [Create an App](#CreateAnApp)
+- [Prepare a model](#PrepareAModel)
+- [Create your web server](#CreateYourWebServer)
+
+
+
+## Create an App
+
+Before getting started with the Forge Platform, you need to set up an app and get your client ID and secret.
+
+* Step 1: Log in to the Dev Portal
+Go to the [Dev Portal](https://developer.autodesk.com/).
+
+
+
+*If You Already Have an Autodesk Account
+
+Click the “SIGN IN” button.
+In the next “Sign In” screen, enter your email address and password, and click “Sign In” to log in to the Dev Portal.
+
+
+
+* Step 2: Create an App
+Once you’re signed in, you can create your application.
+
+
+
+Click the “CREATE APP” button on the top-right in the “My Apps” page, in the next screen,
+
+
+
+Select APIs you are going to use.
+Enter your application name and description.
+Enter a callback URL. Note that wildcards are allowed in the path (but not in the hostname). For more information, see the “callback URL” definition in [API Basics](https://developer.autodesk.com/en/docs/oauth/v2/overview/basics).
+
+*Step 3: Note Your Client ID and Secret
+Once you set up an application, you will see a Client ID and Client Secret in your newly created app page. You will need these in all other OAuth flows and, by extension, to complete every other tutorial on this site!
+
+
+
+By default, a key can be used on any site and application. However, we strongly recommend that you restrict the use of your key to domains that you administer, to prevent
+use on unauthorized sites. We also recommend you create a new App (API key) for every new application rather than reuse the same key in multiple applications.
+
+If you want to learn more about OAuth 2 legged and 3 legged token, check out the rest of the [Step-by-Step guide](https://developer.autodesk.com/en/docs/oauth/v2/tutorials/).
+
+
+
+## Prepare a model
+
+Now you have your API key, the next step is to upload and translate a model so it can be displayed on your webpage.
+
+
+### Upload a model on the Autodesk server
+
+Upload one of your models to your account and get its URN using the following [web page](http://models.autodesk.io).
+
+Alternatively, you can use one of the following desktop solutions instead if you prefer:
+
+- [Windows .NET WPF application](https://github.com/Developer-Autodesk/workflow-wpf-view.and.data.api)
+- [Swift Mac OS application](https://github.com/Developer-Autodesk/workflow-macos-swift-view.and.data.api)
+- [Mac OS cURL command line scripts](https://github.com/Developer-Autodesk/workflow-curl-view.and.data.api)
+
+If you prefer using other programming languages or methods, there are even more samples in our
+[GitHub collection](https://github.com/Developer-Autodesk?utf8=%E2%9C%93&query=workflow)
+and on the [developer page](http://developer-autodesk.github.io).
+
+If you don't have your own model to work with, some 2D and 3D sample models are provided with this workshop, in the
+[Sample files](
+https://github.com/Developer-Autodesk/tutorial-getting.started-view.and.data/tree/master/Sample%20files) folder.
+
+Each of these solutions will upload and translate models on your account which you can use and view later.
+
+
+### Steps to translate a model using the [web page](http://models.autodesk.io).
+
+1. Enter your Client Id and Client Secret, and press the 'Get my access token' button
+
+2. Select one of the models from the 'Samples' list. For example the 'Robot Arm' sample. Or Drag 'n Drop one of yours on the gray area. Then press the 'Translation this one for me' button.
+
+3. You should see a progress bar in the 'Currently translating...' area, please give it some time, ...
+
+4. Once the translation is over, You would see your model listed in the 'Ready"' section with the 'urn' that you need later. Make sure to copy and save that urn somewhere for later use.
+
+
+
+## Create your web server
+
+For this tutorial, we'll create a minimal Node.js web server to serve your html/css/js files as usual as well as provide code to access your translated files.
+
+If you prefer to use another web server technology, you can adapt these instructions yourself to serve the index.html file included with the project.
+
+
+### Download the node.js basic server sample
+
+Check out the appropriate workshop starting point version of the node.js skeleton application from the
+[View and Data API Node.js basic sample](https://github.com/Developer-Autodesk/workflow-node.js-view.and.data.api)
+as explained in [Prerequisites - Get the sources](../prerequisites.md#GetTheSources):
+
+```
+$ git clone https://github.com/Developer-Autodesk/workflow-node.js-view.and.data.api
+$ cd workflow-node.js-view.and.data.api
+$ git checkout v1.0-workshop
+```
+
+
+
+### Download the sample node.js dependencies
+
+Before you can run the sample, you need to download the node.js dependency modules used by the sample. You do this by executing the following command:
+```
+npm install
+```
+This command will download the following modules into the node_modules directory:
+
+* express: Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
+* request: Request is designed to be the simplest way possible to make Http calls. It supports HTTPS and follows redirects by default.
+* serve-favicon: Node.js middleware for serving a favicon.
+
+### Set up your local server
+
+Rename or copy the ./credentials_.js file into ./credentials.js
+
+Windows
+```
+copy credentials_.js credentials.js
+```
+OSX/Linux
+```
+cp credentials_.js credentials.js
+```
+Configure your local server with your keys. Replace the placeholder with your own keys in credentials.js, line #29 and #30
+```
+client_id: process.env.CONSUMERKEY || '',
+
+client_secret: process.env.CONSUMERSECRET || '',
+```
+Copy the URN which you generated prior to installing the server in file /www/index.js at line #18
+Note: the URN given to you by using [models.autodesk.io] (http://models.autodesk.io) is already base64 encoded. In case it is not, you will need to encode it to base 64 as mention [here](https://developer.autodesk.com/en/docs/model-derivative/v2/tutorials/prepare-file-for-viewer/) under "Step 1: Convert the source URN into a Base64-Encoded URN"
+```
+var defaultUrn = '';
+```
+Run the server from the Node.js console, by running the following command:
+```
+node server.js
+```
+
+
+### View your model in a web browser
+
+Connect to your local server using a WebGL-compatible browser:
+
+[http://localhost:3000/](http://localhost:3000/)
+
+Note that we use port 3000 and not the default http port 80 because if you are on Mac OSX or use Skype, port 80 may already be in use.
+If you want to use port 80 to avoid having to specify the port in the URL, edit the server.js file, change the default port from 3000 to 80 and restart the node.js server.
+
+
+=========================
+[Next](chapter-2.md#Chapter2) -
+[Home](../README.md)
diff --git a/chapter-2.md b/chapters/chapter-2.md
similarity index 99%
rename from chapter-2.md
rename to chapters/chapter-2.md
index ef897ee..0837c2d 100644
--- a/chapter-2.md
+++ b/chapters/chapter-2.md
@@ -45,4 +45,4 @@ git checkout yourbranchname
=========================
[Next](chapter-3.md#Chapter3) –
-[Home](README.md)
\ No newline at end of file
+[Home](../README.md)
\ No newline at end of file
diff --git a/chapter-2a.md b/chapters/chapter-2a.md
similarity index 96%
rename from chapter-2a.md
rename to chapters/chapter-2a.md
index 5980066..2d1c408 100644
--- a/chapter-2a.md
+++ b/chapters/chapter-2a.md
@@ -1,8 +1,9 @@
-# Chapter 2 – Translating from the client
+# Chapter 2 – (Optional) Translating from the client
-Step 1: Create a new html page and JavaScript file – i.e. upload.html and upload.js in *www* directory. Then copy the following basic html skeleton code into the file and save it.
+Step 1: Create a new html page and JavaScript file – i.e. upload.html and upload.js in *www* directory.
+Then copy the following basic html skeleton code into the file and save it.
upload.html
```
@@ -246,5 +247,5 @@ and continue with the section [Customize the Viewer Behavior](chapter-3.md#Chapt
=========================
[Next](chapter-3.md#Chapter3) –
-[Parent](chapter-2.md#Chapter2) –
-[Home](README.md)
+[Parent](chapter-2.md#Chapter2) –
+[Home](../README.md)
diff --git a/chapter-2b.md b/chapters/chapter-2b.md
similarity index 98%
rename from chapter-2b.md
rename to chapters/chapter-2b.md
index 453d900..2f2ec62 100644
--- a/chapter-2b.md
+++ b/chapters/chapter-2b.md
@@ -86,11 +86,8 @@ $(document).ready (function () {
"serve-favicon": "*",
"body-parser": ">= 1.11.0",
"formidable": ">= 1.0.17",
- "fs": ">= 0.0.2",
"unirest": ">= 0.4.0",
- "async": ">= 0.9.0",
- "util": ">= 0.10.3",
- "path": ">=0.11.14"
+ "async": ">= 0.9.0"
}
```
Press "Ctrl + C" to exit the node server first if it is running, and execute the command,
@@ -361,4 +358,4 @@ and continue with the section [Customize the Viewer Behavior](chapter-3.md#Chapt
=========================
[Next](chapter-3.md#Chapter3) –
[Parent](chapter-2.md#Chapter2) –
-[Home](README.md)
\ No newline at end of file
+[Home](../README.md)
\ No newline at end of file
diff --git a/chapters/chapter-3.md b/chapters/chapter-3.md
new file mode 100644
index 0000000..e2610be
--- /dev/null
+++ b/chapters/chapter-3.md
@@ -0,0 +1,488 @@
+
+# Chapter 3 - Customize the Viewer Behavior
+
+- [Step 1 – Creating a basic extension](#Step1)
+- [Step 2 – Reference the extension script](#Step2)
+- [Step 3 – Load the extension in the viewer](#Step3)
+- [Step 4 – Testing the extension](#Step4)
+- [Step 5 – Adding a selection handler](#Step5)
+- [Step 6 – Displaying a panel](#Step6)
+- [Step 7 (Bonus step) – Moving the camera](#Step7)
+- [Even more bonus steps](#More)
+
+
+Now you've got a basic 2D/3D model displayed on your web page, let's customize the viewer behavior.
+The simplest way to customize behavior is through the Extension mechanism.
+Extensions allow you to encapsulate your customized behavior in a separate JavaScript file that you can 'load' into the viewer when it's running (you can unload it whenever you like too).
+
+
+
+## Step 1 – Creating a basic extension
+
+Create a file named "Viewing.Extension.Workshop.js" (for example), and save it in the www subfolder of the project folder you cloned from GitHub (workflow-node.js-view.and.data.api).
+Then copy the following basic extension skeleton code into the file and save it:
+
+```js
+ ///////////////////////////////////////////////////////////////////////////////
+ // Demo Workshop Viewer Extension
+ // by Philippe Leefsma, April 2015
+ //
+ ///////////////////////////////////////////////////////////////////////////////
+
+ AutodeskNamespace("Viewing.Extension");
+
+ Viewing.Extension.Workshop = function (viewer, options) {
+
+ /////////////////////////////////////////////////////////////////
+ // base class constructor
+ //
+ /////////////////////////////////////////////////////////////////
+
+ Autodesk.Viewing.Extension.call(this, viewer, options);
+
+ var _self = this;
+ var _viewer = viewer;
+
+ /////////////////////////////////////////////////////////////////
+ // load callback: invoked when viewer.loadExtension is called
+ //
+ /////////////////////////////////////////////////////////////////
+
+ _self.load = function () {
+
+ alert('Viewing.Extension.Workshop loaded');
+ console.log('Viewing.Extension.Workshop loaded');
+
+ return true;
+
+ };
+
+ /////////////////////////////////////////////////////////////////
+ // unload callback: invoked when viewer.unloadExtension is called
+ //
+ /////////////////////////////////////////////////////////////////
+
+ _self.unload = function () {
+
+ console.log('Viewing.Extension.Workshop unloaded');
+
+ return true;
+
+ };
+
+ };
+
+ /////////////////////////////////////////////////////////////////
+ // sets up inheritance for extension and register
+ //
+ /////////////////////////////////////////////////////////////////
+
+ Viewing.Extension.Workshop.prototype =
+ Object.create(Autodesk.Viewing.Extension.prototype);
+
+ Viewing.Extension.Workshop.prototype.constructor =
+ Viewing.Extension.Workshop;
+
+ Autodesk.Viewing.theExtensionManager.registerExtension(
+ 'Viewing.Extension.Workshop',
+ Viewing.Extension.Workshop);
+```
+
+
+## Step 2 – Reference the extension script
+
+Reference the extension file in your index.html by adding the following script element to the header (change the path if you installed the file anywhere other than the www subfolder):
+
+```js
+
+```
+
+
+## Step 3 – Load the extension in the viewer
+
+All that remains for index.js is to add some code to load the extension into the viewer once it is initialized. If the extension relies on geometry in the model, you should set up an
+event to wait for the GEOMETRY_LOADED event, as some features may not be usable if the geometry in not fully loaded.
+
+Open index.js and locate the place where you load the viewable in your viewer code:
+
+```js
+ viewer.load(pathInfoCollection.path3d[0].path);
+ },
+ onError);
+ });
+
+ function onError(error) {
+ console.log('Error: ' + error);
+ };
+```
+
+Add the event handler immediately before the call to viewer.load:
+
+```js
+ viewer.addEventListener(
+ Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
+ function(event) {
+ loadExtensions(viewer);
+ });
+
+ viewer.load(pathInfoCollection.path3d[0].path);
+ },
+ onError);
+
+ });
+```
+
+Add a method that loads the extension:
+
+```js
+ function loadExtensions(viewer) {
+ viewer.loadExtension('Viewing.Extension.Workshop');
+ }
+
+ function onError(error) {
+ console.log('Error: ' + error);
+ };
+```
+
+
+## Step 4 – Testing the extension
+
+Your barebones extension should be ready to run now.
+All it does is display an alert when it's loaded.
+Test that the extension is loaded properly by running your sample.
+(Remember that you setup your node.js project to serve the client page to [http://localhost:3000/](http://localhost:3000/), so open your WebGL-enabled browser and type
+that address in the address bar).
+Since all our changes are on client side, you can just refresh your browser to test your changes.
+
+
+
+## Step 5 – Adding a selection handler
+
+Now we will add some more interesting functionality to the basic extension:
+
+Start by adding a handler for the SELECTION_CHANGED event to the Extension (i.e. editing the file 'Viewing.Extension.Workshop.js'). This event is triggered when user
+selects a component in the model. Register your handler callback in the _self.load function, and then add the function definition below.
+
+```js
+ _self.load = function () {
+
+ _viewer.addEventListener(
+ Autodesk.Viewing.SELECTION_CHANGED_EVENT,
+ _self.onSelectionChanged);
+
+ console.log('Viewing.Extension.Workshop loaded');
+
+ return true;
+ };
+
+ /////////////////////////////////////////////////////////////////
+ // selection changed callback
+ //
+ /////////////////////////////////////////////////////////////////
+ _self.onSelectionChanged = function (event) {
+
+ // event is triggered also when component is unselected
+
+ // in that case event.dbIdArray is an empty array
+ if(event.dbIdArray.length) {
+
+ var dbId = event.dbIdArray[0];
+
+ // do stuff with selected component
+ }
+ else {
+ // all components unselected
+ }
+ }
+```
+
+Every element in the displayed model has a unique ID called a dbId. The code you've just written simply stores the dbId of the first element in the list of elements that the
+user selected. (Usually, the user will only select a single element, but more complete code would handle multiple selected elements).
+
+You can test your code now, if you like. Put a breakpoint in the event handler to check its being called when you select an element. You can use Developer
+Tool of Chrome or similar tools in other modern browsers to do debugging like setting breaking point, watch variable values, etc. (Hint: You select a model
+element by clicking it with you mouse; elements are highlighted in blue when selected).
+
+
+
+## Step 6 – Displaying a panel
+
+Now we'll get properties of selected component and display them in a custom viewer panel. Using the viewer UI to create your extensions will help migrating code from one
+project to another. It helps making your extension independent of the client. However, you can manipulate any other component of your web application from the extension –
+you could read or write information stored in a separate database, or update a table somewhere else on the webpage, etc.
+
+Add some code to initialize an empty panel in the body of your extension:
+
+```js
+ /////////////////////////////////////////////////////////////////
+ // base class constructor
+ //
+ /////////////////////////////////////////////////////////////////
+
+ Autodesk.Viewing.Extension.call(this, viewer, options);
+
+ var _self = this;
+
+ var _viewer = viewer;
+
+ /////////////////////////////////////////////////////////////////
+ // create panel and set up inheritance
+ //
+ /////////////////////////////////////////////////////////////////
+
+ Viewing.Extension.Workshop.WorkshopPanel = function(
+ parentContainer,
+ id,
+ title,
+ options)
+ {
+ Autodesk.Viewing.UI.PropertyPanel.call(
+ this,
+ parentContainer,
+ id, title);
+ };
+
+ Viewing.Extension.Workshop.WorkshopPanel.prototype = Object.create(
+ Autodesk.Viewing.UI.PropertyPanel.prototype);
+
+ Viewing.Extension.Workshop.WorkshopPanel.prototype.constructor =
+ Viewing.Extension.Workshop.WorkshopPanel;
+
+ /////////////////////////////////////////////////////////////////
+ // load callback: invoked when viewer.loadExtension is called
+ //
+ /////////////////////////////////////////////////////////////////
+
+ _self.load = function () {
+```
+
+Instantiate the panel in your load method and uninitialize it in unload.
+Edit _self.load and _self.unload as follows:
+
+```js
+ /////////////////////////////////////////////////////////////////
+ // load callback: invoked when viewer.loadExtension is called
+ //
+ /////////////////////////////////////////////////////////////////
+ _self.load = function () {
+
+ _viewer.addEventListener(
+ Autodesk.Viewing.SELECTION_CHANGED_EVENT,
+ _self.onSelectionChanged);
+
+ _self.panel = new Viewing.Extension.Workshop.WorkshopPanel (
+ _viewer.container,
+ 'WorkshopPanelId',
+ 'Workshop Panel');
+
+ console.log('Viewing.Extension.Workshop loaded');
+
+ return true;
+ };
+
+ /////////////////////////////////////////////////////////////////
+ // unload callback: invoked when viewer.unloadExtension is called
+ //
+ /////////////////////////////////////////////////////////////////
+ _self.unload = function () {
+
+ _self.panel.setVisible(false);
+
+ _self.panel.uninitialize();
+
+ console.log('Viewing.Extension.Workshop unloaded');
+
+ return true;
+ };
+```
+
+Replace the implementation of the selection handler with the following code, so the panel is populated with the properties of the selected element and displayed when an item is selected.
+Just for fun, we also isolate the component that is clicked:
+
+```js
+ /////////////////////////////////////////////////////////////////
+ // selection changed callback
+ //
+ /////////////////////////////////////////////////////////////////
+ _self.onSelectionChanged = function (event) {
+
+ function propertiesHandler(result) {
+
+ if (result.properties) {
+ _self.panel.setProperties(
+ result.properties);
+ _self.panel.setVisible(true);
+ }
+ }
+
+ if(event.dbIdArray.length) {
+ var dbId = event.dbIdArray[0];
+
+ _viewer.getProperties(
+ dbId,
+ propertiesHandler);
+
+ _viewer.fitToView(dbId);
+ _viewer.isolateById(dbId);
+ }
+ else {
+ _viewer.isolateById([]);
+ _viewer.fitToView();
+ _self.panel.setVisible(false);
+ }
+ }
+```
+
+You've now finished writing your extension to respond to a user selecting a model element by displaying its properties in a panel and isolating it in the view.
+Launch the client page and select a model element by clicking on it.
+The model and camera view reset if you clear your selection or click in space.
+
+
+
+## Step 7 (Bonus step) – Moving the camera
+
+Finally, we'll add some camera animation orbiting the camera around the model.
+We will use a simple approach with setInterval.
+For a more robust approach, take a look at the blog post article describing
+[how to create animations in the viewer](http://adndevblog.typepad.com/cloud_and_mobile/2015/04/how-to-create-animations-in-the-viewer.html).
+
+Add a property the extension to hold the interval Id, so we can cancel it.
+
+```js
+ _self.load = function () {
+
+ _viewer.addEventListener(
+ Autodesk.Viewing.SELECTION_CHANGED_EVENT,
+ _self.onSelectionChanged);
+
+ _self.panel = new Viewing.Extension.Workshop.WorkshopPanel (
+ _viewer.container,
+ 'WorkshopPanelId',
+ 'Workshop Panel');
+
+ _self.interval = 0;
+
+ console.log('Viewing.Extension.Workshop loaded');
+
+ return true;
+ };
+```
+
+Add following methods to handle the animation immediately below the end of the _self.onSelectionChanged function implementation.
+
+```js
+ /////////////////////////////////////////////////////////////////
+ // rotate camera around axis with center origin
+ //
+ /////////////////////////////////////////////////////////////////
+ _self.rotateCamera = function(angle, axis) {
+ var pos = _viewer.navigation.getPosition();
+
+ var position = new THREE.Vector3( // Point?
+ pos.x, pos.y, pos.z);
+
+ var rAxis = new THREE.Vector3(
+ axis.x, axis.y, axis.z);
+
+ var matrix = new THREE.Matrix4().makeRotationAxis(
+ rAxis,
+ angle);
+
+ position.applyMatrix4(matrix);
+
+ _viewer.navigation.setPosition(position);
+ };
+
+ /////////////////////////////////////////////////////////////////
+ // start rotation effect
+ //
+ /////////////////////////////////////////////////////////////////
+
+ _self.startRotation = function() {
+ clearInterval(_self.interval);
+
+ // sets small delay before starting rotation
+
+ setTimeout(function() {
+ _self.interval = setInterval(function () {
+ _self.rotateCamera(0.05, {x:0, y:1, z:0});
+ }, 100)}, 500);
+ };
+```
+
+Finally modify the selection handler to trigger the animation when a component is selected:
+
+```js
+ /////////////////////////////////////////////////////////////////
+ // selection changed callback
+ //
+ /////////////////////////////////////////////////////////////////
+ _self.onSelectionChanged = function (event) {
+
+ function propertiesHandler(result) {
+
+ if (result.properties) {
+
+ _self.panel.setProperties(
+ result.properties);
+
+ _self.panel.setVisible(true);
+ }
+ }
+
+ if(event.dbIdArray.length) {
+
+ var dbId = event.dbIdArray[0];
+
+ _viewer.getProperties(
+ dbId,
+ propertiesHandler);
+
+ _viewer.fitToView(dbId);
+ _viewer.isolateById(dbId);
+
+ _self.startRotation();
+ }
+ else {
+ clearInterval(_self.interval); // where is this function defined?
+
+ _viewer.isolateById([]);
+ _viewer.fitToView();
+ _self.panel.setVisible(false);
+ }
+ }
+```
+
+Test your extension again.
+This time, in addition to displaying the panel, the camera (your view of the model) starts rotating when you select a model element.
+
+
+
+## Even more bonus steps
+
+If you've still got some time, go to [http://gallery.autodesk.io](http://gallery.autodesk.io) and play with some of the models and sample extensions available there.
+The [Car](http://viewer.autodesk.io/node/gallery/#/viewer?id=551d0768be86fc2c1138b4d4) model is reasonably detailed.
+To test one of the sample Extensions, click on the Extensions menu, then click Manage and click on an Extension's name to enable or disable it. We recommend you only
+enable one Extension at a time (i.e. disable the last Extension you used before enabling another), because not all the Extensions have been written to play nicely with
+other Extensions.
+
+To see the source code for those Extensions, go to Extensions and select Source. Then click on the name of the Extension you're interested in.
+
+Here are two YouTube videos explaining how to use the gallery sample and a couple of the extensions:
+
+[Viewer Gallery Sample](https://www.youtube.com/watch?v=SQJSuqRqiCg)
+
+[Viewer Physics Engine](https://www.youtube.com/watch?v=tK2ndbvchIM)
+
+Here is a tutorial on how to add a Toolbar button [Toolbar Extension](https://developer.autodesk.com/en/docs/viewer/v2/tutorials/toolbar-button/)
+
+
+## Solution
+
+You can get the final source code as zip from [here](https://github.com/Developer-Autodesk/workflow-node.js-view.and.data.api/archive/v1.0-workshop-extension.zip), or using git:
+```
+git checkout v1.0-workshop-extension
+```
+
+=========================
+[Home](../README.md)
diff --git a/img/create-app.png b/img/create-app.png
new file mode 100644
index 0000000..93267bd
Binary files /dev/null and b/img/create-app.png differ
diff --git a/img/githubClone.png b/img/githubClone.png
index 5f1029c..df37e5e 100644
Binary files a/img/githubClone.png and b/img/githubClone.png differ
diff --git a/img/githubCloneURL.png b/img/githubCloneURL.png
index fc67805..45238aa 100644
Binary files a/img/githubCloneURL.png and b/img/githubCloneURL.png differ
diff --git a/img/githubDownload.png b/img/githubDownload.png
index b656eb0..3b27b3a 100644
Binary files a/img/githubDownload.png and b/img/githubDownload.png differ
diff --git a/img/githubFork.png b/img/githubFork.png
index 07a535b..ea341b4 100644
Binary files a/img/githubFork.png and b/img/githubFork.png differ
diff --git a/img/heroku-settings-vars.png b/img/heroku-settings-vars.png
new file mode 100644
index 0000000..eb13bce
Binary files /dev/null and b/img/heroku-settings-vars.png differ
diff --git a/img/heroku-vars.png b/img/heroku-vars.png
new file mode 100644
index 0000000..f91a7cf
Binary files /dev/null and b/img/heroku-vars.png differ
diff --git a/img/signed-in.png b/img/signed-in.png
new file mode 100644
index 0000000..f3d14cc
Binary files /dev/null and b/img/signed-in.png differ
diff --git a/img/signin.png b/img/signin.png
new file mode 100644
index 0000000..7219b32
Binary files /dev/null and b/img/signin.png differ
diff --git a/img/signup.png b/img/signup.png
new file mode 100644
index 0000000..24bee30
Binary files /dev/null and b/img/signup.png differ
diff --git a/img/view-app.png b/img/view-app.png
new file mode 100644
index 0000000..3311c9d
Binary files /dev/null and b/img/view-app.png differ
diff --git a/prerequisites.md b/prerequisites.md
index 89573bd..d27d49f 100644
--- a/prerequisites.md
+++ b/prerequisites.md
@@ -29,10 +29,9 @@ If you do not have git installed already, you can get it from here:
Here are some [additional setup instructions](https://help.github.com/articles/set-up-git), and many other questions are covered by the [GitHub Help](https://help.github.com).
-Here is a [github quick learning tutorial](https://try.github.io/levels/1/challenges/1) if you never used git before. Note it is a command line tutorial, but you may prefer the GUI or WEB interfaces.
+Here is a [github quick learning tutorial](https://try.github.io/levels/1/challenges/1) if you never used git before. Note it is a command line tutorial; you may prefer the GUI or WEB interfaces instead.
-Once you have a GitHub client installed, you can clone
-a repository from GitHub.
+Once you have a GitHub client installed, you can clone a repository from GitHub.
Go to the the repository you want to download locally and clone the source code by clicking the 'Clone in Desktop' button.
@@ -43,40 +42,42 @@ Here is the equivalent command line:
git clone
```
-Your repository git url can be obtain from the 'HTTPs clone URL' box.
+Your repository git url can be obtain from the 'HTTPs clone URL' box or by copying it from the GitHub repository web page.

-This creates the a copy of all the source of the repository on your local drive. In this 'clone' directory, you can find the files from the repository which you can work with.
-However, it is important to note here that unless you got write permission, you would not be able to save your changes in the repo. To be able to save in the repo you clone,
-you either need to be a contributor on that repo, or have cloned one of your own repo. If you want to work from someone else repo, and be able to edit and save your changes,
-please consider to 'fork' the repo in your account, and clone that repo instead from your account. See below instructions [how to fork a repo](#Fork).
+This creates a copy of the entire repository source on your local drive.
+This 'clone' directory contains copies of the repository files for you to work with.
+However, it is important to note here that you cannot save your changes back to the source repo unless you have write permission.
+To be able to save back to the repo you cloned, you either need to be a contributor to that repo, or have cloned one of your own repos.
+If you want to work from somebody else's repo and be able to edit and save your changes, please consider 'forking' the repo in your own account, then cloning that repo instead.
+See the instructions below on [how to fork a repo](#Fork).
If you prefer not to install git, you can download a zip file instead by clicking the 'Download ZIP' button.

-In this workshop, we will provide the command line instructions, but feel free to use the method you prefer.
+In this workshop, we will provide the command line instructions, but please feel free to use whichever method you prefer.
-### Major 'git' operations
+### Main 'git' operations
```
git status
```
-Gives you the list of changes in your working tree vs the repo on GitHub
+Displays the list of changes in your working tree vs the repo on GitHub.
```
git add [] ...
```
This command updates the index using the current content found in the working tree, to prepare the content staged for the next commit.
-A shortcut to add all changes for the next commit is to use `git add -A`
+A shortcut to add all changes for the next commit is to use `git add -A`.
```
git commit -m "my message"
```
Stores the current contents of the index in a new commit along with a log message from the user describing the changes.
-
+ -m = this means you need to add a message to your commit.
```
git push
```
@@ -85,7 +86,7 @@ Updates the remote repo with your commit.
```
git pull
```
-Get changes from the remote repo in your working tree.
+Retrieves changes from the remote repo into your working tree.
```
git checkout
@@ -95,17 +96,21 @@ Either checkout a tag version or a branch. Updates files in the working tree to
### git command line
-Using git from the command line on Mac OSX or Linux is straight forward, just open a terminal window (on Mac OSx - Applications -> Utilities -> Terminal.app). git, node, and npm commands should work from there if present on your system.
-On Windows, you can choose between few options: a bash console, a powershell console, or the standard command prompt. You can decide which one to use from the Github tool in the settings panel.
-You would access the git console by running the 'Git Shell' icon which should be on your Desktop or in your Programs list. Node and npm commands have their own command prompt window which is
-different from GitHub.
+Using git from the command line on Mac OSX or Linux is straight forward; just open a terminal window (on Mac OSx - Applications -> Utilities -> Terminal.app).
+git, node, and npm commands should work from there if present on your system.
+
+On Windows, you can choose between few options: a bash console, a powershell console, or the standard command prompt.
+You can decide which one to use from the GitHub tool in the settings panel.
+You would access the git console by running the 'Git Shell' icon which should be on your Desktop or in your Programs list.
+Node and npm commands have their own command prompt window which is different from GitHub.
### Fork option
-Last, someone may want to work on the wokshop and saves this results on his own github account - in this case, you need to 'fork' the repository from your account and clone the 'forked' repository.
-To fork a repository, log in Github using your account, go to the repository you want to fork, and press the 'Fork' button.
+Last, someone may want to work with the workshop material and save modifications to it to their own github account.
+In this case, you need to 'fork' the repository from your account and clone the 'forked' repository.
+To fork a repository, log in to GitHub using your account, go to the repository you want to fork, and press the 'Fork' button.

@@ -113,19 +118,21 @@ To fork a repository, log in Github using your account, go to the repository you
## Install Node.js
-If you want to run the preconfigured local web-server and the test tools then you will also need [Node.js v0.12.2+](https://nodejs.org/download/).
+If you want to run the preconfigured local web-server and the test tools then you will also need [Node.js v5+](https://nodejs.org/download/).
-You can download a Node.js installer for your operating system from [nodejs.org](http://nodejs.org/download/). Check the version of Node.js that you have installed by running the following command:
+You can download a Node.js installer for your operating system from [nodejs.org](http://nodejs.org/download/).
+Check the version of Node.js that you have installed by running the following command:
node --version
-In Debian based distributions, there is a name clash with another utility called node. The suggested solution is to also install the nodejs-legacy apt package, which renames node to nodejs:
+In Debian based distributions, there is a name clash with another utility called node.
+The suggested solution is to also install the nodejs-legacy apt package, which renames node to nodejs:
apt-get install nodejs-legacy npm
nodejs --version
- npm version
+ npm –version
If you need to run different versions of node.js in your local environment, consider installing [Node Version Manager (nvm)](https://github.com/creationix/nvm).
@@ -133,46 +140,54 @@ If you need to run different versions of node.js in your local environment, cons
## Install a code editor
-If you have programmed before, you may already have a favorite programmer's editor. However, if you do not, or were thinking about trying other editors anyway,
+If you have programmed before, you may already have a favorite programmer's editor.
+However, if you do not, or were thinking about trying other editors anyway,
spend some time trying and considering these options common in the javascript/node.js community ...
-Note, they are not listed in the order of preference.
+Note that they are listed in alphabetical order, not in any order of preference.
- | Windows | Mac OSX | Linux | Free/Paid
---- | ------------- | -------------- | -------- | --------------
-[Brackets](http://brackets.io/) | X | X | X | Free
-[Eclipse](http://eclipse.org/) | X | X | X | Free
-[Emacs](http://www.gnu.org/software/emacs/) | X | X | X | Free
-[Notepad++](http://notepad-plus-plus.org/) | X | - | - | Free
-[textmate](http://macromates.com/) | - | X | - | Paid
-[Sublime Text](http://www.sublimetext.com/) | X | X | X | Paid
-[WebStorm](https://www.jetbrains.com/webstorm/) | X | X | X | Paid
+ | Windows | Mac OSX | Linux | Free/Paid | Git integration | Includes a node.js server
+--- | ------------- | -------------- | -------- | -------------- | -------------------- | ----------------------------------
+[Brackets](http://brackets.io/) | yes | yes | yes | Free | yes | yes
+[Eclipse](http://eclipse.org/) | yes | yes | yes | Free | yes | yes
+[Emacs](http://www.gnu.org/software/emacs/) | yes | yes | yes | Free | yes | -
+[Notepad++](http://notepad-plus-plus.org/) | yes | - | - | Free | - | -
+[textmate](http://macromates.com/) | - | yes | - | Paid | via scripting | -
+[Sublime Text](http://www.sublimetext.com/) | yes | yes | yes | Paid | via a plugin | -
+[VSStudio](https://www.visualstudio.com/) | yes | yes | yes | Free | yes | yes
+[WebMatrix](http://www.microsoft.com/web/webmatrix/) | yes | - | - | Free | yes | yes
+[WebStorm](https://www.jetbrains.com/webstorm/) | yes| yes | yes | Paid | yes | yes
## Get the sources
-We assume you want to start a project and work as a team. For this reason, you want to use 'git' and be able to share the sources across the members of your team,
-and later deploy it on a web server. Your first action will be to fork the material repository on your 'github' account.
+We assume you want to start a project and work as a team.
+For this reason, you want to use 'git' and be able to share the sources across the members of your team,
+and later deploy it on a web server.
+Your first action will be to fork the material repository on your 'github' account.
If you prefer not to use git, you can still download the zip files and inflate their contents on your local drive.
+Note: This tutorial is having its own set of instructions, please ignore any of the instructions you will find
+in the sample repo you are going to fork.
+
* Using git
- - Sign in using your Github account at [http://www.github.com](http://www.github.com)
- - Go to the [Node.js simple server project](https://github.com/Developer-Autodesk/workflow-node.js-view.and.data.api)
- - Fork the project
- - Copy your fork 'HTTPS clone URL'
- - In the git console, run the following commands:
- ```
- git clone
-
- git checkout v1.0-workshop
- ```
- The first command creates the workflow-node.js-view.and.data.api in your current directory. The second command is optional and is there to make sure we work on
- the correct version of the material made for this instructions.
- - Change your working directory
- ```
- cd workflow-node.js-view.and.data.api
- ```
+ - Sign in using your GitHub account at [http://www.github.com](http://www.github.com)
+ - Go to the [Node.js simple server project](https://github.com/Developer-Autodesk/workflow-node.js-view.and.data.api)
+ - Fork the project
+ - Copy your fork URL, e.g. `https://github.com/myusername/workflow-node.js-view.and.data.api`
+ - Clone your fork locally to a new directory. If no directory name is specified, the repository name is used:
+ ```
+ git clone https://github.com/myusername/workflow-node.js-view.and.data.api
+ ```
+ - Enter the new directory:
+ ```
+ cd workflow-node.js-view.and.data.api
+ ```
+ - Check out the workshop starting point to ensure you have the correct version of the material for the following instructions:
+ ```
+ git checkout v1.0-workshop
+ ```
* Not using git
- Go to the [Node.js simple server project](https://github.com/Developer-Autodesk/workflow-node.js-view.and.data.api)
@@ -180,11 +195,10 @@ If you prefer not to use git, you can still download the zip files and inflate t
- Inflate the ZIP file on your hard drive
- Make the inflated directory your current directory
-
The tutorial instructions, from now on, assume you are running all commands from the *workflow-node.js-view.and.data.api* directory.
=========================
-[Next](chapter-1.md#Chapter1) -
-[Home](README.md)
\ No newline at end of file
+[Next](chapters/chapter-1.md#Chapter1) -
+[Home](README.md)