Below is an example demonstrating the use of the geometry pipeline to generate a geometric plane.
// Define an anonymous function; // serves as our main loop, // limits the scope of variables (function(){ /*********************************************************************/ // Number : A function to convert from meters/yards/feet/inches to centimeters function convertToCM( nVal, sFromUnit ) { switch( sFromUnit.lower() ){ case "m": return nVal * 100; case "yd": return nVal * 36.0 * 2.54; case "ft": return nVal * 12.0 * 2.54; case "in": return nVal * 2.54; } return nVal; }; /*********************************************************************/ // String : A function for finding a unique label in the scene function getUniqueLabel( sLabel ) { // Initialize var sUnqLabel = sLabel; // If a node by the same label already exists if( Scene.findNodeByLabel( sUnqLabel ) ){ // Create an array of the label parts var aLabel = sUnqLabel.split( " " ); // Initialize var sPreLabel = sUnqLabel; // Get the last label part var sLastPart = aLabel[ aLabel.length - 1 ]; // If the last label part is a number enclosed in parens if( sLastPart.startsWith( "(" ) && sLastPart.endsWith( ")" ) && !isNaN( sLastPart.substring( 1, sLastPart.length - 1 ) ) ){ // Get rid of the number aLabel.pop(); // Reconstruct the Label without the number sPreLabel = aLabel.join( " " ); } // Initialize a count var i = 2; // Until we cannot find a node with the label while( Scene.findNodeByLabel( String( "%1 (%2)" ).arg( sPreLabel ).arg( i ) ) ){ // Increment the count i += 1; } // Construct the unique Label sUnqLabel = String( "%1 (%2)" ).arg( sPreLabel ).arg( i ); } // Return the unique Label return sUnqLabel; }; /*********************************************************************/ // Get the user input var sOrigin = "Object Center"; // "World Center" var nSize = 10; var sUnit = "cm"; // "m", "yd", "ft", "in" var nDivisions = 10; // Convert the input value to centimeters nSize = convertToCM( nSize, sUnit ); // Sanity check the input values if ( nSize <= 0.0 || nDivisions < 1 ) { // We are done... return; } // Let the user know we are busy setBusyCursor(); // Create new node var oNode = new DzNode(); // Set the node name; // use a name that is consistent with the create primitive action oNode.setName( "Plane" ); // Build the label of the node var sLabel = String( "Plane %1x%2 %3%4" ) .arg( nDivisions ) .arg( nDivisions ) .arg( nSize ) .arg( sUnit ); oNode.setLabel( getUniqueLabel( sLabel ) ); // Create a new object var oObject = new DzObject(); // Set the object name; // use a name that is consistent with the create primitive action oObject.name = String( "pPlane(%1)%2" ).arg( nSize ).arg( nDivisions ); // Create a new polygonal shape var oFacetShape = new DzFacetShape(); // Set the shape name and label; // use a name that is consistent with the create primitive action oFacetShape.name = "Default"; oFacetShape.setLabel( oFacetShape.name ); // Create a new polygonal mesh var oFacetMesh = new DzFacetMesh(); // Create a new default material var oMaterial = new DzDefaultMaterial(); // Set the material name and label; // use a name that is consistent with the create primitive action oMaterial.name = "Default"; oMaterial.setLabel( oMaterial.name ); // Add the material to the shape oFacetShape.addMaterial( oMaterial ); // Begin editing the mesh oFacetMesh.beginEdit(); // Get the UV map var oMap = oFacetMesh.getUVs(); // Activate the material; all new geometry will be added to this oFacetMesh.activateMaterial( oMaterial.name ); // Declare some variables for generating the mesh var i, j, idx, numVerts = nDivisions + 1; var x, z, nHalfSize = nSize / 2; var vecUVs = new DzVec3( 0, 0, 0 ); // Pre-size the vertex array; faster than dynamic resizing oFacetMesh.preSizeVertexArray( numVerts * numVerts ); // Create the vertices/uvs for( i = 0; i < numVerts; i += 1 ){ z = i / nDivisions; vecUVs.y = z; for( j = 0; j < numVerts; j += 1 ){ x = j / nDivisions; vecUVs.x = x; oFacetMesh.addVertex( x * nSize - nHalfSize, 0, nHalfSize - z * nSize ); oMap.appendPnt2Vec( vecUVs ); } } // Pre-size the facet array; faster than dynamic resizing oFacetMesh.preSizeFacets( nDivisions * nDivisions ); var aVertexIndices = new Array( 4 ); // Create the faces for( i = 0; i < nDivisions; i += 1 ){ for( j = 0; j < nDivisions; j += 1 ){ aVertexIndices[0] = j + (i * numVerts); aVertexIndices[1] = j + (i * numVerts) + 1; aVertexIndices[2] = j + ((i + 1) * numVerts) + 1; aVertexIndices[3] = j + ((i + 1) * numVerts); oFacetMesh.addFacet( aVertexIndices, aVertexIndices ); } } // Finish editing the mesh oFacetMesh.finishEdit(); // Set the mesh for the shape oFacetShape.setFacetMesh( oFacetMesh ); // Add the shape to the object oObject.addShape( oFacetShape ); // Add the object to the node oNode.setObject( oObject ); // Get the local bounding box var boxLocal = oNode.getLocalBoundingBox(); var vecMax = boxLocal.max; var vecMin = boxLocal.min; // If the user chose the object center for the origin if( sOrigin == "Object Center" ){ // Get the middle of the height of the box var nMid = (vecMax.y + vecMin.y) * 0.5; // Set the origin; default and current var vecOrigin = new DzVec3(0, nMid, 0); oNode.setOrigin( vecOrigin, true ); oNode.setOrigin( vecOrigin ); } // If the height of the bounding box is less than // 1 unit (1cm) tall, set it to be 1 unit tall if( vecMax.y < 1 ){ vecMax.y = 1; } // Set the end point; default and current var vecEndPoint = new DzVec3( 0, vecMax.y, 0 ); oNode.setEndPoint( vecEndPoint, true ); oNode.setEndPoint( vecEndPoint ); // Get the presentation for the node var oPresentation = oNode.getPresentation(); // If the node did not have a presentation, // create one and assign it to the node if( !oPresentation ){ oPresentation = new DzPresentation(); oNode.setPresentation( oPresentation ); } // Set the type of node oPresentation.type = "Prop"; // Add the node to the scene Scene.addNode( oNode ); // Let the user know we are done clearBusyCursor(); // Finalize the function and invoke })();