Exemplo n.º 1
0
/** 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 );
      }
    }
  }
}