###########################
Creating the printing plane
###########################

Summary
===========================

In this chapter, we will walk through how to use HC to dynamically create the printing plane object in the scene.


Concepts
========

* Instantiating and populating the ``Communicator.MeshData`` object
* Creating the mesh

-----------------------------------

In the previous section, we skipped over the step that creates the printing plane that our models will sit atop in our scene. We will address that in this section.

To begin, review the file *src/js/PrintingPlane.js*. We provide a new class ``PrintingPlane`` that builds a printing plane of a given size.

The constructor for this function should define three parameters, and the last two will be optional. The first parameter will be the ``WebViewer`` the printing plane will be added to. The second parameter will define the length and width of the square plane, and the last parameter will be the depth of the plane. Our ``PrintingPlane`` class will need an additional property to reference the ``nodeId`` returned when the ``MeshData`` is eventually created. We will set the initial value to null. Once all the properties for our class have been set, we will create the printing plane with a function called ``_createPrintingPlane``, which the constructor will invoke.

Your ``PrintingPlane`` class should now look like this:


.. code-block:: js

	class PrintingPlane {
		constructor(viewerInstance, size = 300, depth = 10) {
		  this._planeSize = size;
		  this._planeDepth = depth;
		  this._viewer = viewerInstance;
		  this._nodeId = null;
		  this._createPrintingPlane();
		}
	}

The ``_createPrintingPlane`` function will author the data for our printing plane, create the mesh, and add it to our scene. Add the following function as a class method:

.. code-block:: js

	_createPrintingPlane() {
	 
	}

There are four main parts to dynamically creating a mesh at run-time. If we look at the ``Communicator.Model`` class, we can see there is a ``Communicator.Model.createMesh`` function that receives an input parameter of type ``Communicator.MeshData``. We must first populate the ``Communicator.MeshData`` object we instantiate, then pass this object to the ``Communicator.Model.createMesh`` function. The ``Communicator.Model.createMesh`` function will then create a mesh based off the ``Communicator.MeshData`` provided, returning a promise with a ``Communicator.meshId`` to identify the mesh. This ``Communicator.meshId`` can then be passed to the ``Communicator.MeshInstanceData`` object, which is passed to ``Communicator.Model.createMeshInstance`` function, finally instancing the mesh and rendering it to the scene. Instancing a mesh returns a promise with a ``nodeId``, that we can then store to track the ``nodeId`` of the printing plane in our ``PrintingPlane`` class member.

Let’s begin by defining our mesh data with the ``Communicator.MeshData`` object. Add the following to our nearly created function ``_createPrintingPlane()``: 


.. code-block:: js

	let gridSize = this._planeSize;
	let d = this._planeDepth;
	let meshData = new Communicator.MeshData();

We also assigned the plane size and depth properties to new variables for this scope, so we do not have to type ``this`` over and over again when defining our mesh vertices.

We will set the face winding for our mesh to look for the clockwise declaration of vertices. This simply defines the order in which the vertices are specified relative to the face normal. We will also enable backfaces which renders the face of each facet on both sides, making the the correct ordering of vertices somewhat less important (since if we specify a triangle of vertices backwards, the face will still be rendered). 

.. code-block:: js

	meshData.setFaceWinding(Communicator.FaceWinding.Clockwise);
	meshData.setBackfacesEnabled(true);

Next, we will specify the faces and normal for our rectangular mesh. Because each face is actually made of two triangles, and there are 6 vertices per face, we need to define a total of 36 vertices in space. Each point will also have its own normal vector defined, though for vertices on the same face, the normal should be the same.


.. code-block:: js

	meshData.addFaces([
		// +Z Normal Plane
		-gridSize, -gridSize, 0,
		-gridSize, gridSize, 0,
		gridSize, gridSize, 0,
		-gridSize, -gridSize, 0,
		gridSize, gridSize, 0,
		gridSize, -gridSize, 0,
		
		// -Z Normal Plane
		-gridSize, -gridSize, -d,
		-gridSize, gridSize, -d,
		gridSize, gridSize, -d,
		-gridSize, -gridSize, -d,
		gridSize, gridSize, -d,
		gridSize, -gridSize, -d,
		
		// +X Normal Plane
		gridSize, -gridSize, 0,
		gridSize, -gridSize, -d,
		gridSize, gridSize, -d,
		gridSize, -gridSize, 0,
		gridSize, gridSize, -d,
		gridSize, gridSize, 0,
		
		// -X Normal Plane
		-gridSize, -gridSize, 0,
		-gridSize, -gridSize, -d,
		-gridSize, gridSize, -d,
		-gridSize, -gridSize, 0,
		-gridSize, gridSize, -d,
		-gridSize, gridSize,  0,
		
		// +Y Normal Plane
		-gridSize, gridSize, 0,
		gridSize, gridSize, 0,
		-gridSize, gridSize, -d,
		gridSize, gridSize, 0,
		gridSize, gridSize, -d,
		-gridSize, gridSize, -d,
		
		// -Y Normal Plane
		-gridSize, -gridSize, 0,
		gridSize, -gridSize, 0,
		-gridSize, -gridSize, -d,
		gridSize, -gridSize, 0,
		gridSize, -gridSize, -d,
		-gridSize, -gridSize, -d,
	], [
		// +Z Normals
		0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,	0, 0, 1, 0, 0, 1,
		
		// -Z Normals
		0, 0, -1, 0, 0, -1,	0, 0, -1, 0, 0, -1,	0, 0, -1, 0, 0, -1,
		
		// +X Normals
		1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,	1, 0, 0, 1, 0, 0,
		
		// -X Normals
		-1, 0, 0, -1, 0, 0,	-1, 0, 0, -1, 0, 0,	-1, 0, 0, -1, 0, 0,
		
		// +Y Normals
		0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,	0, 1, 0, 0, 1, 0,
		
		// -Y Normals
		0, -1, 0, 0, -1, 0,	0, -1, 0, 0, -1, 0,	0, -1, 0, 0, -1, 0,
	]);

Technically, this would be enough information to render a mesh to our scene, but let’s add one more element to our mesh data: polylines. Adding polylines will give our ``PrintingPlane`` mesh a nice uniform grid look. We will specify the number of grid lines we want, and then equally divide the spacing by the size of the printing plane.

.. code-block:: js

	let gridCount = 15;
	let gridUnit = (gridSize / gridCount) * 2;
	for (let i = -gridCount / 2; i <= gridCount / 2; ++i) {
		let position = (gridUnit * i);
		meshData.addPolyline([
			-gridSize, position, 0,
			gridSize, position, 0,
		]);
		meshData.addPolyline([
			position, -gridSize, 0,
			position, gridSize, 0,
		]);
	}

This concludes the authoring of our mesh data. You can now pass this ``Communicator.MeshData`` into the ``Communicator.Model.createMesh`` function, to allow for subsequent instancing.

The function ``Communicator.Model.createMesh`` returns a promise with an assigned mesh ID of our created mesh. We will use this mesh ID to instance a mesh into our scene. Before instancing the mesh, we are able to set options for our mesh instance. Because the ``PrintingPlane`` is serving as a supplementary model, we do not want to give it the same interaction as other models loaded into our scene (for example, we don’t want to be able to select or move it around the scene, as opposed to our other loaded models on the plane).

Once the ``Communicator.Model.createMesh`` function has returned its promise and ``meshId``, we can use the ``then()`` function of the promise to execute our next section of code that will set the mesh instance flags and instantiate the mesh. The returned ``nodeId`` of this promise will then be assigned to the property value ``_nodeId`` of the ``PrintingPlane`` class.

.. code-block:: js

	this._viewer.model.createMesh(meshData).then((meshId) => {
		let flags = Communicator.MeshInstanceCreationFlags.DoNotOutlineHighlight |
			Communicator.MeshInstanceCreationFlags.ExcludeBounding |
			Communicator.MeshInstanceCreationFlags.DoNotCut |
			Communicator.MeshInstanceCreationFlags.DoNotExplode |
			Communicator.MeshInstanceCreationFlags.DoNotLight;
		let meshInstanceData = new Communicator.MeshInstanceData(meshId, null, "printingPlane", null, null, null, flags);
		meshInstanceData.setLineColor(new Communicator.Color(150, 150, 150));
		meshInstanceData.setFaceColor(new Communicator.Color(75, 75, 75));
		// Do not provide a node id since this will be out of hierarchy
		this._viewer.model.createMeshInstance(meshInstanceData, null, null, true)
			.then((nodeId) => {
			this._nodeId = nodeId;
		});
	});

This wraps up the ``_createPrintingPlane`` function. We can also add a couple accessor functions to get a couple properties of the ``PrintingPlane`` object. Our final ``PrintingPlane`` class should look something like this (note the ``addFaces`` data has been omitted for readability):

.. code-block:: js

	class PrintingPlane {
		constructor(viewerInstance, size = 300, depth = 10) {
			this._planeSize = size;
			this._planeDepth = depth;
			this._viewer = viewerInstance;
			this._nodeId = null;
			this._createPrintingPlane();
		}
		_createPrintingPlane() {
			let gridSize = this._planeSize;
			let d = this._planeDepth;
			let meshData = new Communicator.MeshData();
			meshData.setFaceWinding(Communicator.FaceWinding.Clockwise);
			meshData.setBackfacesEnabled(true);
			let gridCount = 15;
			let gridUnit = (gridSize / gridCount) * 2;
			for (let i = -gridCount / 2; i <= gridCount / 2; ++i) {
				let position = (gridUnit * i);
				meshData.addPolyline([
					-gridSize, position, 0,
					gridSize, position, 0,
				]);
				meshData.addPolyline([
					position, -gridSize, 0,
					position, gridSize, 0,
				]);
			}
			meshData.addFaces([...]); 
			this._viewer.model.createMesh(meshData).then((meshId) => {
				let flags = Communicator.MeshInstanceCreationFlags.DoNotOutlineHighlight |
					Communicator.MeshInstanceCreationFlags.ExcludeBounding |
					Communicator.MeshInstanceCreationFlags.DoNotCut |
					Communicator.MeshInstanceCreationFlags.DoNotExplode |
					Communicator.MeshInstanceCreationFlags.DoNotLight;
				let meshInstanceData = new Communicator.MeshInstanceData(meshId, null, "printingPlane", null, null, null, flags);
				meshInstanceData.setLineColor(new Communicator.Color(150, 150, 150));
				meshInstanceData.setFaceColor(new Communicator.Color(75, 75, 75));
				// Do not provide a node id since this will be out of hierarchy
				this._viewer.model.createMeshInstance(meshInstanceData, null, null, true)
					.then((nodeId) => {
					this._nodeId = nodeId;
				});
			});
		}
		
		getDimensions() {
			return ({
				planeSize: this._planeSize,
				planeDepth: this._planeDepth,
			});
		}
		
		getNodeId() {
			return this._nodeId;
		}
	}

You'll notice a couple new helper functions as well, ``getDimensions()`` and ``getNodeId()``. These will be used later in this tutorial, go ahead and add those now.

Find the placeholder comment "Create Printing Plane" in our ``main`` class. We can now instantiate our ``PrintingPlane``, passing in each viewer and the dimensions we want. To track each plane, we will store them in an array property of the ``main`` class, much like we did with the model names and viewers.

Let's create a new ``PrintingPlane`` during the ``modelStructureReady`` event:

.. code-block:: js

	viewer.start();
	viewer.setCallbacks({
		modelStructureReady: () => {
			// Create Printing Plane
			this._printSurfaces.push(new PrintingPlane(viewer, 300, 10));
	 
			// Load Model
			this.loadModel("microengine", viewer);
		}

Notice we are pushing the newly created ``PrintingPlane`` into an array. Let's make sure we add that array to our ``main``'s constructor:

.. code-block:: js

	// Set class properties
	this._viewerList = [mainViewer, overheadViewer];
	this._modelList = [];
	this._printSurfaces = [];

In your application, you should see our models loading at the origin and flush with the plane:

.. image:: images/additive-manufacturing-printing-plane-with-model.png
