Below is an example demonstrating the use of the geometry pipeline to generate polylines for edges of a polygonal mesh.
// DAZ Studio version 4.11.0.36 filetype DAZ Script // Define an anonymous function; // serves as our main loop, // limits the scope of variables (function(){ // Initialize 'static' variables that hold modifier key state var s_bShiftPressed = false; var s_bControlPressed = false; var s_bAltPressed = false; var s_bMetaPressed = false; // If the "Action" global transient is defined, and its the correct type if( typeof( Action ) != "undefined" && Action.inherits( "DzScriptAction" ) ){ // If the current key sequence for the action is not pressed if( !App.isKeySequenceDown( Action.shortcut ) ){ updateModifierKeyState(); } // If the "Action" global transient is not defined } else if( typeof( Action ) == "undefined" ) { updateModifierKeyState(); } /*********************************************************************/ // void : A function for updating the keyboard modifier state function updateModifierKeyState() { // Get the current modifier key state var nModifierState = App.modifierKeyState(); // Update variables that hold modifier key state s_bShiftPressed = (nModifierState & 0x02000000) != 0; s_bControlPressed = (nModifierState & 0x04000000) != 0; s_bAltPressed = (nModifierState & 0x08000000) != 0; s_bMetaPressed = (nModifierState & 0x10000000) != 0; }; /*********************************************************************/ // void : A function for printing only if debugging function debug() { // If we are not debugging if( !s_bAltPressed ){ // We are done... return; } // Convert the arguments object into an array var aArguments = [].slice.call( arguments ); // Print the array print( aArguments.join(" ") ); }; /*********************************************************************/ // Boolean : A function for testing whether or not a QObject instance // inherits one of a list of types function inheritsType( oObject, aTypeNames ) { // If the object does not define the 'inherits' function if( !oObject || typeof( oObject.inherits ) != "function" ){ // We are done... it is not a QObject return false; } // Iterate over the list of type names for( var i = 0, nTypes = aTypeNames.length; i < nTypes; i += 1 ){ // If the object does not inherit the 'current' type if( !oObject.inherits( aTypeNames[i] ) ){ // Next!! continue; } // Return the result return true; } // Return the result return false; }; /*********************************************************************/ // DzNode : A function for getting the root of a node function getRootNode( oNode ) { // If we have a node and it is a bone if( oNode && inheritsType( oNode, ["DzBone"] ) ){ // We want the skeleton return oNode.getSkeleton(); } // Return the original node return oNode; }; /*********************************************************************/ // DzObject : A function for getting the object for a node function getObjectForNode( oNode, bRoot ) { // Get the node var oContextNode = bRoot ? getRootNode( oNode ) : oNode; // If we do not have a root node if( !oContextNode ){ // We are done... return null; } // Get the object of the root node var oObject = oContextNode.getObject(); // If we do not have an object if( !oObject ){ // We are done... return null; } // Return the object return oObject; }; /*********************************************************************/ // DzShape : A function for getting the shape for a node function getShapeForNode( oNode, bRoot ) { // Get the object of the node var oObject = getObjectForNode( oNode, bRoot ); // If we do not have an object if( !oObject ){ // We are done... return null; } // Get the shape of the root node var oShape = oObject.getCurrentShape(); // If we do not have a shape if( !oShape ){ // We are done... return null; } // Return the shape return oShape; }; /*********************************************************************/ // DzGeometry : A function for getting the geometry for the root of a node function getGeometryForNode( oNode, bRoot, bCached ) { // Get the shape of the root node var oShape = getShapeForNode( oNode, bRoot ); // If we do not have a shape if( !oShape ){ // We are done... return null; } // If we are getting the cached geometry if( bCached ){ // Update the working mesh //oShape.invalidateWorkingMesh(); // Get the object of the root node var oObject = getObjectForNode( oNode, bRoot ); // Return the geometry return oObject.getCachedGeom(); } // Get the geometry of the root node var oGeometry = oShape.getGeometry(); // If we do not have a geometry if( !oGeometry ){ // We are done... return null; } // Return the geometry return oGeometry; }; /*********************************************************************/ // DzFacetMesh : A function for getting the facet mesh for a node function getFacetMeshForNode( oNode, bRoot, bCached ) { // Get the geometry of the node var oGeometry = getGeometryForNode( oNode, bRoot, bCached ); // If we do not have a facet mesh if( !inheritsType( oGeometry, ["DzFacetMesh"] ) ){ // We are done... return null; } // Return the geometry return oGeometry; }; /*********************************************************************/ // Get the primary selection var oSrcNode = Scene.getPrimarySelection(); // If nothing is selected if( !oSrcNode ){ // We are done... return; } // Get the base mesh of the root node var oSrcBaseMesh = getFacetMeshForNode( oSrcNode, true, false ); // If we do not have a base mesh if( !oSrcBaseMesh ){ // We are done... return; } // Let the user know we are busy setBusyCursor(); // Create a new target figure; // it must be a figure because we need a grafting figure shape var oTgtFigure = new DzFigure(); // Set the target node name oTgtFigure.setName( String("%1_polylines").arg( oSrcNode.objectName ) ); // Get the label of the source node var sLabel = oSrcNode.getLabel(); // Strip the number from the label sLabel = Scene.stripLabelNumber( sLabel ); // Get a unique label sLabel = Scene.getUniqueTopLevelLabel( String("%1 Polylines").arg( sLabel ) ); // Set the label of the shell node oTgtFigure.setLabel( sLabel ); // Get the source object var oSrcObject = getObjectForNode( oSrcNode, true ); // Create a new target object var oTgtObject = new DzObject(); // Set the target object name oTgtObject.name = oSrcObject.name + "_polylines"; // Get the source shape var oSrcShape = getShapeForNode( oSrcNode, true ); // Create a new grafting figure shape for the target var oTgtFigureShape = new DzGraftingFigureShape(); // Set the target shape name and label oTgtFigureShape.name = oSrcShape.name; oTgtFigureShape.setLabel( oSrcShape.getLabel() ); // Get the source facet mesh var oSrcMesh = getFacetMeshForNode( oSrcNode, true, false ); // Create a new target facet mesh var oTgtMesh = new DzFacetMesh(); // Define the material name var sMaterialName = "Default"; // Create a newtarget default material var oTgtMaterial = new DzDefaultMaterial(); // Set the material name and label; // use a name that is consistent with the create primitive action oTgtMaterial.name = sMaterialName; oTgtMaterial.setLabel( oTgtMaterial.name ); // Add the material to the shape oTgtFigureShape.addMaterial( oTgtMaterial ); // Begin editing the target mesh oTgtMesh.beginEdit(); // Activate the material; all new geometry will be added to this oTgtMesh.activateMaterial( sMaterialName ); // Define whether we want selected edges var bSelectedEdges = true; // Initialize a local edge index array var aSrcEdges = []; // If we want just the selected edges if( bSelectedEdges ){ // Get the selected edge indices aSrcEdges = oSrcBaseMesh.getSelectedEdges(); } // Get whether or not we have selected edges var bHasEdgeList = aSrcEdges.length > 0; // Get the number of edges; // if we have selected edges use those, otherwise use the full list var nSrcEdges = (bHasEdgeList ? aSrcEdges.length : oSrcBaseMesh.getNumEdges()); // Pre-size the vertex array oTgtMesh.preSizeVertexArray( nSrcEdges * 2 ); // Pre-size the polylines array oTgtMesh.preSizePolylines( nSrcEdges, nSrcEdges ); // Declare working variables var nSrcEdgeIdx, nTgtVertices; var oSrcEdge; var vecVertex1, vecVertex2; var aTgtVertexIndices, aTgtUVIndices; // Iterate over the source edges for( var i = 0; i < nSrcEdges; i += 1 ){ // Get the 'current' edge index nSrcEdgeIdx = (bHasEdgeList ? aSrcEdges[i] : i); // Provide feedback debug( String("Edge #%1").arg( nSrcEdgeIdx ) ); // Get the number of vertices in the target mesh nTgtVertices = oTgtMesh.getNumVertices(); // Get the source edge oSrcEdge = oSrcBaseMesh.getEdge( nSrcEdgeIdx ); // Provide feedback debug( String("\tVertex #%1").arg( oSrcEdge.vertIdx1 ) ); debug( String("\tVertex #%1").arg( oSrcEdge.vertIdx2 ) ); // Get the position of the source vertices vecVertex1 = oSrcBaseMesh.getVertex( oSrcEdge.vertIdx1 ); vecVertex2 = oSrcBaseMesh.getVertex( oSrcEdge.vertIdx2 ); // Add the vertex to the target mesh oTgtMesh.addVertex( vecVertex1 ); // Add the vertex to the target mesh oTgtMesh.addVertex( vecVertex2 ); // Assign the vertex indices aTgtVertexIndices = [ nTgtVertices, nTgtVertices + 1 ]; // Assign the UV indices; // trying to use UV positions from the source mesh // would be pointless, since the discontinuous edges // will just leave you waffling back and forth on // which one is 'better', but because we need default // UVs in order to be loaded from a saved asset, we // use the first index of the default UV map created // when we created the target facet mesh aTgtUVIndices = [ 0, 0 ]; // Add the polyline to the target mesh oTgtMesh.addPolyline( aTgtVertexIndices, aTgtUVIndices ); } // Finish editing the target mesh oTgtMesh.finishEdit(); // Set the target mesh for the target shape oTgtFigureShape.setFacetMesh( oTgtMesh ); // Add the target shape to the target object oTgtObject.addShape( oTgtFigureShape ); // Add the target object to the target node oTgtFigure.setObject( oTgtObject ); // Create a "Line Tessellation" modifier var oTgtModifier = new DzLineTessellationModifier(); // Define the wireframe attributes var nSides = 3; var nWidth = 5; // Get the "Viewport Line Tessellation Sides" control var oProperty = oTgtModifier.getViewportSidesControl(); // Set the number of viewport sides oProperty.setValue( nSides ); // Get the "Render Line Tessellation Sides" control oProperty = oTgtModifier.getRenderSidesControl(); // Set the number of render sides oProperty.setValue( nSides ); // Get the "Line Start Width (mm)" control oProperty = oTgtMaterial.getLineStartWidthControl(); // Set the start width oProperty.setValue( nWidth ); // Get the "Line End Width (mm)" control oProperty = oTgtMaterial.getLineEndWidthControl(); // Set the start width oProperty.setValue( nWidth ); // Add the modifier to the target object oTgtObject.addModifier( oTgtModifier ); // Add the target node to the scene Scene.addNode( oTgtFigure ); // Let the user know we are done clearBusyCursor(); // Finalize the function and invoke })();