/** Create a RIB compatible representation of a Maya pfxToon node as RiCurves. */ liqRibPfxToonData::liqRibPfxToonData( MObject pfxToon ) : nverts(), CVs(), curveWidth(), cvColor(), cvOpacity() { LIQDEBUGPRINTF( "-> creating pfxToon curves\n" ); MStatus status( MS::kSuccess ); // Update the pfxToon node with the renderCamera's position // otherwise the resulting outline might be incorrect MDagPath cameraPath; MSelectionList camList; camList.add( liqglo_renderCamera ); camList.getDagPath( 0, cameraPath ); MMatrix cam_mat( cameraPath.inclusiveMatrix() ); MFnDependencyNode pfxToonNode( pfxToon ); pfxToonNode.findPlug( "cameraPointX" ).setValue( cam_mat( 3, 0 ) ); pfxToonNode.findPlug( "cameraPointY" ).setValue( cam_mat( 3, 1 ) ); pfxToonNode.findPlug( "cameraPointZ" ).setValue( cam_mat( 3, 2 ) ); MFnPfxGeometry pfxtoon( pfxToon, &status ); if ( status == MS::kSuccess ) { MRenderLineArray profileArray; MRenderLineArray creaseArray; MRenderLineArray intersectionArray; bool doLines = true; bool doTwist = false; bool doWidth = true; bool doFlatness = false; bool doParameter = false; bool doColor = true; bool doIncandescence = false; bool doTransparency = true; bool doWorldSpace = false; status = pfxtoon.getLineData( profileArray, creaseArray, intersectionArray, doLines, doTwist, doWidth, doFlatness, doParameter, doColor, doIncandescence, doTransparency, doWorldSpace ); if ( status == MS::kSuccess ) { // Het the lines and fill the arrays. ncurves = profileArray.length(); { MFnDependencyNode pfxNode( pfxToon ); MString info( "[liquid] pfxToon node " ); info += pfxNode.name() + " : " + ncurves + " curves."; cout << info << endl << flush; } unsigned totalNumberOfVertices( 0 ); if ( ncurves > 0 ) { nverts = shared_array< RtInt >( new RtInt[ ncurves ] ); // Calculate storage requirments. // This is a lot more efficient than all those reallocs() // (or resize()s if we used a vector) that were done before // in the main loop below. for ( unsigned i( 0 ); i < ncurves; i++ ) { MRenderLine theLine( profileArray.renderLine( i, &status ) ); if ( MS::kSuccess == status ) { MVectorArray vertices( theLine.getLine() ); totalNumberOfVertices += vertices.length(); } } // Allocate memory CVs = shared_array< RtFloat >( new RtFloat[ totalNumberOfVertices * 3 ] ); if ( !CVs ) { MString err( "liqRibPfxToonData failed to allocate CV memory!" ); cout << err << endl << flush; throw( err ); return; } curveWidth = shared_array< RtFloat >( new RtFloat[ totalNumberOfVertices ] ); if ( !curveWidth ) { MString err( "liqRibPfxToonData failed to allocate per vertex width memory!" ); cout << err << endl << flush; throw( err ); return; } cvColor = shared_array< RtFloat >( new RtFloat[ totalNumberOfVertices * 3 ] ); if ( !cvColor ) { MString err( "liqRibPfxToonData failed to allocate CV color memory!" ); cout << err << endl << flush; throw(err); return; } cvOpacity = shared_array< RtFloat >( new RtFloat[ totalNumberOfVertices * 3 ] ); if ( !cvOpacity ) { MString err("liqRibPfxToonData failed to allocate CV opacity memory !"); cout << err << endl << flush; throw( err ); return; } RtFloat* cvPtr; RtFloat* widthPtr; RtFloat* colorPtr; RtFloat* opacityPtr; totalNumberOfVertices = 0; for ( unsigned i( 0 ); i < ncurves; i++ ) { MRenderLine theLine( profileArray.renderLine( i, &status ) ); if ( MS::kSuccess == status ) { const MVectorArray& vertices( theLine.getLine() ); const MDoubleArray& width( theLine.getWidth() ); const MVectorArray& vertexColor( theLine.getColor() ); const MVectorArray& vertexTransparency( theLine.getTransparency() ); //cout <<"line "<<i<<" contains "<<vertices.length()<<" vertices."<<endl; //cout <<vertexColor<<endl; nverts[i] = vertices.length(); totalNumberOfVertices += vertices.length(); cvPtr = CVs.get() + ( totalNumberOfVertices * 3 - nverts[ i ] * 3 ) ; widthPtr = curveWidth.get() + ( totalNumberOfVertices - nverts[ i ] ) ; colorPtr = cvColor.get() + ( totalNumberOfVertices * 3 - nverts[ i ] * 3 ) ; opacityPtr = cvOpacity.get() + ( totalNumberOfVertices * 3 - nverts[ i ] * 3 ) ; for ( unsigned vertIndex( 0 ); vertIndex < vertices.length(); vertIndex++ ) { *cvPtr++ = ( RtFloat ) vertices[ vertIndex ].x; *cvPtr++ = ( RtFloat ) vertices[ vertIndex ].y; *cvPtr++ = ( RtFloat ) vertices[ vertIndex ].z; *widthPtr++ = ( RtFloat )width[ vertIndex ]; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex ].x ; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex ].y ; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex ].z ; *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex ].x ) ; *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex ].y ) ; *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex ].z ) ; } } } // Store for output liqTokenPointer points_pointerPair; if ( !points_pointerPair.set( "P", rPoint, true, false, totalNumberOfVertices ) ) { MString err( "liqRibPfxToonData: liqTokenPointer failed to allocate CV memory !" ); cout << err << endl; throw(err); return; } points_pointerPair.setDetailType( rVertex ); points_pointerPair.setTokenFloats( CVs ); tokenPointerArray.push_back( points_pointerPair ); // Store width params liqTokenPointer width_pointerPair; if ( !width_pointerPair.set( "width", rFloat, true, false, totalNumberOfVertices ) ) { MString err("liqRibPfxToonData: liqTokenPointer failed to allocate width memory !"); cout <<err<<endl; throw(err); return; } width_pointerPair.setDetailType( rVarying ); width_pointerPair.setTokenFloats( curveWidth ); tokenPointerArray.push_back( width_pointerPair ); // Store color params liqTokenPointer color_pointerPair; if ( !color_pointerPair.set( "pfxToon_vtxColor", rColor, true, false, totalNumberOfVertices ) ) { MString err("liqRibPfxToonData: liqTokenPointer failed to allocate color memory !"); cout <<err<<endl; throw(err); return; } color_pointerPair.setDetailType( rVertex ); color_pointerPair.setTokenFloats( cvColor ); tokenPointerArray.push_back( color_pointerPair ); // Store opacity params liqTokenPointer opacity_pointerPair; if ( !opacity_pointerPair.set( "pfxToon_vtxOpacity", rColor, true, false, totalNumberOfVertices ) ) { MString err("liqRibPfxToonData: liqTokenPointer failed to allocate opacity memory !"); cout <<err<<endl<<flush; throw(err); return; } opacity_pointerPair.setDetailType( rVertex ); opacity_pointerPair.setTokenFloats( cvOpacity ); tokenPointerArray.push_back( opacity_pointerPair ); addAdditionalSurfaceParameters( pfxToon ); } } } }
/** Create a RIB compatible representation of a Maya pfxHair node as RiCurves. */ liqRibPfxHairData::liqRibPfxHairData( MObject pfxHair ) : nverts(), CVs(), normals(), curveWidth(), cvColor(), cvOpacity() { CM_TRACE_FUNC("liqRibPfxHairData::liqRibPfxHairData("<<MFnDagNode(pfxHair).fullPathName()<<")"); LIQDEBUGPRINTF( "-> creating pfxHair curve\n" ); MStatus status( MS::kSuccess ); MFnPfxGeometry pfxhair( pfxHair, &status ); if ( MS::kSuccess == status ) { MRenderLineArray profileArray; MRenderLineArray creaseArray; MRenderLineArray intersectionArray; MRenderLineArray copy; bool doLines = true; bool doTwist = true; bool doWidth = true; bool doFlatness = false; bool doParameter = false; bool doColor = true; bool doIncandescence = false; bool doTransparency = true; bool doWorldSpace = false; status = pfxhair.getLineData( profileArray, creaseArray, intersectionArray, doLines, doTwist, doWidth, doFlatness, doParameter, doColor, doIncandescence, doTransparency, doWorldSpace ); if ( status == MS::kSuccess ) { ncurves = profileArray.length(); { MFnDependencyNode pfxNode( pfxHair ); MString info( "[liquid] pfxHair node " ); info += pfxNode.name() + " : " + ncurves + " curves."; printf("%s\n", info.asChar() ); } unsigned totalNumberOfVertices( 0 ), totalNumberOfSpans( 0 ); if( ncurves > 0 ) { nverts = shared_array< RtInt >( new RtInt[ ncurves ] ); // Calculate storage requirments. // This is a lot more efficient than all those reallocs() // (or resize()s if we used a vector) that were done before // in the main loop below. for( unsigned i( 0 ); i < ncurves; i++ ) { MRenderLine theLine( profileArray.renderLine( i, &status ) ); if ( MS::kSuccess == status ) { const MVectorArray& vertex( theLine.getLine() ); totalNumberOfVertices += vertex.length() + 2; } } // Allocate memory CVs = shared_array< RtFloat >( new RtFloat[ totalNumberOfVertices ] ); if ( !CVs ) { //MString err( "liqRibPfxHairData failed to allocate CV memory!" ); //cout << err << endl << flush; //throw( err ); liquidMessage2(messageError, "liqRibPfxHairData failed to allocate CV memory!\n" ); return; } normals = shared_array< RtFloat >( new RtFloat[ totalNumberOfVertices * 3 ] ); if( !normals ) { //MString err( "liqRibPfxHairData failed to allocate normal memory!" ); //cout << err << endl << flush; //throw( err ); liquidMessage2(messageError, "[error] liqRibPfxHairData failed to allocate normal memory!\n" ); return; } curveWidth = shared_array< RtFloat >( new RtFloat[ totalNumberOfSpans ] ); if( !curveWidth ) { //MString err( "liqRibPfxHairData failed to allocate per vertex width memory!" ); //cout << err << endl << flush; //throw( err ); liquidMessage2(messageError, "[error] liqRibPfxHairData failed to allocate per vertex width memory!\n" ); return; } cvColor = shared_array< RtFloat >( new RtFloat[ totalNumberOfVertices * 3 ] ); if( !cvColor ) { //MString err( "liqRibPfxHairData failed to allocate CV color memory!" ); //cout << err << endl << flush; //throw( err ); liquidMessage2(messageError, "[error] liqRibPfxHairData failed to allocate CV color memory!\n" ); return; } cvOpacity = shared_array< RtFloat >( new RtFloat[ totalNumberOfVertices * 3 ] ); if( !cvOpacity ) { //MString err( "liqRibPfxHairData failed to allocate CV opacity memory !" ); //cout << err << endl << flush; //throw( err ); liquidMessage2(messageError, "[error] liqRibPfxHairData failed to allocate CV opacity memory!\n" ); return; } RtFloat* cvPtr; RtFloat* normalPtr; RtFloat* widthPtr; RtFloat* colorPtr; RtFloat* opacityPtr; totalNumberOfVertices = 0; for( unsigned i( 0 ); i < ncurves; i++ ) { MRenderLine theLine( profileArray.renderLine( i, &status ) ); if ( MS::kSuccess == status ) { const MVectorArray& vertex( theLine.getLine() ); const MVectorArray& twist( theLine.getTwist() ); const MDoubleArray& width( theLine.getWidth() ); const MVectorArray& vertexColor( theLine.getColor() ); const MVectorArray& vertexTransparency( theLine.getTransparency() ); nverts[ i ] = vertex.length() + 2; totalNumberOfVertices += nverts[ i ]; totalNumberOfSpans += vertex.length(); unsigned int vertIndex = 0; cvPtr = CVs.get() + ( totalNumberOfVertices * 3 - nverts[ i ] * 3 ); normalPtr = normals.get() + ( totalNumberOfVertices * 3 - nverts[ i ] * 3 ); widthPtr = curveWidth.get() + ( totalNumberOfSpans - vertex.length() ); colorPtr = cvColor.get() + ( totalNumberOfVertices * 3 - nverts[ i ] * 3 ); opacityPtr = cvOpacity.get() + ( totalNumberOfVertices * 3 - nverts[ i ] * 3 ); *cvPtr++ = ( RtFloat )vertex[ vertIndex ].x; *cvPtr++ = ( RtFloat )vertex[ vertIndex ].y; *cvPtr++ = ( RtFloat )vertex[ vertIndex ].z; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex ].x; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex ].y; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex ].z; *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex ].x ); *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex ].y ); *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex ].z ); for ( ; vertIndex < vertex.length(); vertIndex++ ) { *cvPtr++ = ( RtFloat )vertex[ vertIndex ].x; *cvPtr++ = ( RtFloat )vertex[ vertIndex ].y; *cvPtr++ = ( RtFloat )vertex[ vertIndex ].z; *normalPtr++ = ( RtFloat )twist[ vertIndex ].x; *normalPtr++ = ( RtFloat )twist[ vertIndex ].y; *normalPtr++ = ( RtFloat )twist[ vertIndex ].z; *widthPtr++ = ( RtFloat )width[ vertIndex ]; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex ].x; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex ].y; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex ].z; *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex ].x ); *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex ].y ); *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex ].z ); } *cvPtr++ = ( float )vertex[ vertIndex - 1 ].x; *cvPtr++ = ( float )vertex[ vertIndex - 1 ].y; *cvPtr++ = ( float )vertex[ vertIndex - 1 ].z; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex - 1 ].x; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex - 1 ].y; *colorPtr++ = ( RtFloat )vertexColor[ vertIndex - 1 ].z; *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex-1 ].x ); *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex-1 ].y ); *opacityPtr++ = ( RtFloat )( 1.0f - vertexTransparency[ vertIndex-1 ].z ); } } // Store for CVs liqTokenPointer points_pointerPair; points_pointerPair.set( "P", rPoint, true, false, totalNumberOfVertices ); points_pointerPair.setDetailType( rVertex ); points_pointerPair.setTokenFloats( CVs ); tokenPointerArray.push_back( points_pointerPair ); // Store normals liqTokenPointer normals_pointerPair; normals_pointerPair.set( "N", rNormal, true, false, totalNumberOfVertices ); points_pointerPair.setDetailType( rVertex ); points_pointerPair.setTokenFloats( normals ); tokenPointerArray.push_back( normals_pointerPair ); // Store width params liqTokenPointer width_pointerPair; width_pointerPair.set( "width", rFloat, true, false, totalNumberOfSpans ); width_pointerPair.setDetailType( rVarying ); width_pointerPair.setTokenFloats( curveWidth ); tokenPointerArray.push_back( width_pointerPair ); // Store color params liqTokenPointer color_pointerPair; color_pointerPair.set( "Cs", rColor, true, false, totalNumberOfVertices ); color_pointerPair.setDetailType( rVertex ); color_pointerPair.setTokenFloats( cvColor ); tokenPointerArray.push_back( color_pointerPair ); // Store opacity params liqTokenPointer opacity_pointerPair; opacity_pointerPair.set( "Os", rColor, true, false, totalNumberOfVertices ); opacity_pointerPair.setDetailType( rVertex ); opacity_pointerPair.setTokenFloats( cvOpacity ); tokenPointerArray.push_back( opacity_pointerPair ); // Additional RMan* params addAdditionalSurfaceParameters( pfxHair ); } } } }