User Tools

Site Tools


Generate Polyline Wireframe

Summary

Below is an example demonstrating the use of the geometry pipeline to generate polylines for edges of a polygonal mesh.

API Areas of Interest

Example

Generate_Polyline_Wireframe.dsa
// 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
})();