bool  FlatColorNodeVisitor::regist(MFnPlugin &plugin)
	{
		//CM_TRACE_FUNC("FlatColorNodeVisitor::regist()");

		MStatus status;

		status = plugin.registerNode( 
			elvishray::FlatColorNode::getTypeName(), 
			elvishray::FlatColorNode::getTypeId(), 
			elvishray::FlatColorNode::creator, elvishray::FlatColorNode::initialize, MPxNode::kDependNode,
			&elvishray::surface_classification);
		IfMErrorMsgReturnIt( status, "Can't register "+elvishray::FlatColorNode::getTypeName()+" node" );
		status.clear();
		status = MSwatchRenderRegister::registerSwatchRender( elvishray::FlatColorNode::getTypeName()+"Swatch", liqNodeSwatch::creator );
		IfMErrorMsgReturnIt( status, "Can't register "+elvishray::FlatColorNode::getTypeName()+"Swatch" );
		
		RNodeVisitorMgr::getInstancePtr()->regist(
			FlatColorNode::getTypeName().asChar(),
			FlatColorNodeVisitor::getInstancePtr()
			);
		return true;
	}
	bool  PhysicalsunNodeVisitor::regist(MFnPlugin &plugin)
	{
		//CM_TRACE_FUNC("PhysicalsunNodeVisitor::regist()");

		MStatus status;

		status = plugin.registerNode( 
			renderman::PhysicalsunNode::getTypeName(), 
			renderman::PhysicalsunNode::getTypeId(), 
			renderman::PhysicalsunNode::creator, renderman::PhysicalsunNode::initialize, MPxNode::kDependNode,
			&renderman::light_classification);
		IfMErrorMsgReturnIt( status, "Can't register "+renderman::PhysicalsunNode::getTypeName()+" node" );
		status.clear();
		status = MSwatchRenderRegister::registerSwatchRender( renderman::PhysicalsunNode::getTypeName()+"Swatch", liqNodeSwatch::creator );
		IfMErrorMsgReturnIt( status, "Can't register "+renderman::PhysicalsunNode::getTypeName()+"Swatch" );

		RNodeVisitorMgr::getInstancePtr()->regist(
			PhysicalsunNode::getTypeName().asChar(),
			PhysicalsunNodeVisitor::getInstancePtr()
			);
		return true;
	}
	int Renderer::preview( const std::string& fileName, const liqPreviewShaderOptions& options )
	{
		CM_TRACE_FUNC("Renderer::preview("<<fileName<<","<<options.shaderNodeName<<")");

		  std::string shaderFileName;
  liqShader currentShader;
  MObject	shaderObj;
  MString shader_type_TempForRefactoring;//  [2/14/2012 yaoyansi]

  if ( options.fullShaderPath ) 
  {
	  // a full shader path was specified
	  //cout <<"[liquid] got full path for preview !"<<endl;
	  //shaderFileName = const_cast<char*>(options.shaderNodeName);

	  std::string tmp( options.shaderNodeName );
	  currentShader.setShaderFileName(tmp.substr( 0, tmp.length() -  4 ) );

	  if ( options.type == "surface" ){
		  assert(0&&"we should use currentShader.shader_type_ex = \"surface\"");
		  //currentShader.shader_type = SHADER_TYPE_SURFACE;//  [2/14/2012 yaoyansi]
		  shader_type_TempForRefactoring = "surface";
	  }else if ( options.type == "displacement" ){
		  assert(0&&"we should use currentShader.shader_type_ex = \"displacement\"");
		  //currentShader.shader_type = SHADER_TYPE_DISPLACEMENT;//  [2/14/2012 yaoyansi]
		  shader_type_TempForRefactoring = "displacement";
	  }
	  //cout <<"[liquid]   options.shaderNodeName = " << options.shaderNodeName << endl;
	  //cout <<"[liquid]   options.type = "<<options.type<<endl;
  } 
  else 
  {
	  // a shader node was specified
	  MSelectionList shaderNameList;
	  shaderNameList.add( options.shaderNodeName.c_str() );
	  shaderNameList.getDependNode( 0, shaderObj );
	  if( shaderObj == MObject::kNullObj )
	  {
		  MGlobal::displayError( std::string( "Can't find node for " + options.shaderNodeName ).c_str() );
		  RiEnd();
		  return 0;
	  }
	  currentShader = liqShader( shaderObj );
	  shader_type_TempForRefactoring = currentShader.shader_type_ex;
	  shaderFileName = currentShader.getShaderFileName();
  }
  MFnDependencyNode assignedShader( shaderObj );


  // Get the Pathes in globals node
  MObject globalObjNode;
  MString liquidShaderPath = "",liquidTexturePath = "",liquidProceduralPath = "";
  MStatus status;
  MSelectionList globalList;
	
	// get the current project directory
  MString MELCommand = "workspace -q -rd";
  MString MELReturn;
  MGlobal::executeCommand( MELCommand, MELReturn );
  MString liquidProjectDir = MELReturn;
	
  status = globalList.add( "liquidGlobals" );
  if ( globalList.length() > 0 ) 
	{
    status.clear();
    status = globalList.getDependNode( 0, globalObjNode );
    MFnDependencyNode globalNode( globalObjNode );
		liquidGetPlugValue( globalNode, "shaderPath", liquidShaderPath, status);
    liquidGetPlugValue( globalNode, "texturePath", liquidTexturePath, status);
    liquidGetPlugValue( globalNode, "proceduralPath", liquidProceduralPath, status);
  }
  if( fileName.empty() ) 
	{
    RiBegin_liq( NULL );
#ifdef DELIGHT
    //RtPointer callBack( progressCallBack );
    //RiOption( "statistics", "progresscallback", &callBack, RI_NULL );
#endif
  } 
	else {
	liquidMessage2(messageInfo,"preview rib file: [%s]", fileName.c_str());
    RiBegin_liq( (RtToken)fileName.c_str() );
  }

  std::string liquidHomeDir = liquidSanitizeSearchPath( getEnvironment( "LIQUIDHOME" ) );
  std::string shaderPath( "&:@:.:~:" + liquidHomeDir + "/lib/shaders" );
  std::string texturePath( "&:@:.:~:" + liquidHomeDir + "/lib/textures" );
  std::string proceduralPath( "&:@:.:~:" + liquidHomeDir + "/lib/shaders" );

  std::string projectDir = std::string( liquidSanitizeSearchPath( liquidProjectDir ).asChar() );
  if ( liquidProjectDir != "")
  {
    shaderPath += ":" + projectDir;	
    texturePath += ":" + projectDir;
    proceduralPath += ":" + projectDir;
  }
  if ( liquidShaderPath != "" )
		shaderPath += ":" + std::string( liquidSanitizeSearchPath( parseString( liquidShaderPath, false ) ).asChar());	
  if ( liquidTexturePath != "" )
		texturePath += ":" + std::string( liquidSanitizeSearchPath( parseString( liquidTexturePath, false) ).asChar());	
  if ( liquidProceduralPath != "" )
		proceduralPath += ":" + std::string( liquidSanitizeSearchPath( parseString( liquidProceduralPath, false) ).asChar());	
	
  RtString list( const_cast< RtString >( shaderPath.c_str() ) );
  RiOption( "searchpath", "shader", &list, RI_NULL );
	
  RtString texPath( const_cast< RtString >( texturePath.c_str() ) );
  if( texPath[ 0 ] )
    RiOption( "searchpath","texture", &texPath, RI_NULL );
	
  RtString procPath( const_cast< RtString >( proceduralPath.c_str() ) );
  
  if( procPath[ 0 ] )
    RiOption( "searchpath","procedural", &procPath, RI_NULL );

  RiShadingRate( ( RtFloat )options.shadingRate );
  RiPixelSamples( options.pixelSamples, options.pixelSamples );

#ifdef PRMAN
  if ( MString( "PRMan" ) == liqglo.liquidRenderer.renderName )
	RiPixelFilter( RiCatmullRomFilter, 4., 4. );
#elif defined( DELIGHT )
  if ( MString( "3Delight" ) == liqglo.liquidRenderer.renderName )
    RiPixelFilter( RiSeparableCatmullRomFilter, 4., 4. );
//    RiPixelFilter( RiMitchellFilter, 4., 4.);
#else
  RiPixelFilter( RiCatmullRomFilter, 4., 4. );
#endif

  RiFormat( ( RtInt )options.displaySize, ( RtInt )options.displaySize, 1.0 );
  if( options.backPlane ) 
	{
    RiDisplay( const_cast< RtString >( options.displayName.c_str() ),
               const_cast< RtString >( options.displayDriver.c_str() ), RI_RGB, RI_NULL );
  } 
	else 
	{ // Alpha might be useful
    RiDisplay( const_cast< RtString >( options.displayName.c_str() ),
               const_cast< RtString >( options.displayDriver.c_str() ), RI_RGBA, RI_NULL );
  }
  RtFloat fov( 22.5 );
  RiProjection( "perspective", "fov", &fov, RI_NULL );
  RiTranslate( 0, 0, 2.75 );
  RiExposure(1, currentShader.m_previewGamma);
  
  RtInt visible = 1;
  RtString transmission = "transparent";

  RiAttribute( "visibility", ( RtToken ) "camera", &visible, RI_NULL );
  RiAttribute( "visibility",  ( RtToken ) "trace", &visible, RI_NULL );
  // RiAttribute( "visibility", ( RtToken ) "transmission", ( RtPointer ) &transmission, RI_NULL );
  
  RiWorldBegin();
  RiReverseOrientation();
  RiTransformBegin();
  RiRotate( -90., 1., 0., 0. );
  RiCoordinateSystem( "_environment" );
  RiTransformEnd();
  RtLightHandle ambientLightH, directionalLightH;
  RtFloat intensity;
  intensity = 0.05 * (RtFloat)options.previewIntensity;
  ambientLightH = RiLightSource( "ambientlight", "intensity", &intensity, RI_NULL );
  intensity = 0.9 * (RtFloat)options.previewIntensity;
  RtPoint from;
  RtPoint to;
  from[0] = -1.; from[1] = 1.5; from[2] = -1.;
  to[0] = 0.; to[1] = 0.; to[2] = 0.;
  RiTransformBegin();
    RiRotate( 55.,  1, 0, 0 );
    RiRotate( 30.,  0, 1, 0 );
    directionalLightH = RiLightSource( "liquiddistant", "intensity", &intensity, RI_NULL );
  RiTransformEnd();
  intensity = 0.2f * (RtFloat)options.previewIntensity;
  from[0] = 1.3f; from[1] = -1.2f; from[2] = -1.;
  RiTransformBegin();
    RiRotate( -50.,  1, 0, 0 );
    RiRotate( -40.,  0, 1, 0 );
    directionalLightH = RiLightSource( "liquiddistant", "intensity", &intensity, RI_NULL );
  RiTransformEnd();

  RiAttributeBegin();


  //ymesh omit this section, because liqShader::writeRibAttributes() do this work in that branch
  //I don't use liqShader::writeRibAttributes(), so I use this section. -yayansi
  float displacementBounds = 0.;
	liquidGetPlugValue( assignedShader, "displacementBound", displacementBounds, status);
  
  if ( displacementBounds > 0. ) 
	{
    RtString coordsys = "shader";
	RiArchiveRecord( RI_COMMENT, "ymesh omit this section, because liqShader::writeRibAttributes do this work in that branch" );
    RiAttribute( "displacementbound", "coordinatesystem", &coordsys, RI_NULL );	
    RiAttribute( "displacementbound", "sphere", &displacementBounds, "coordinatesystem", &coordsys, RI_NULL );
  }

  //LIQ_GET_SHADER_FILE_NAME( shaderFileName, options.shortShaderName, currentShader );

	// output shader space
  MString shadingSpace;
	liquidGetPlugValue( assignedShader, "shaderSpace", shadingSpace, status);
  
  if ( shadingSpace != "" ) 
	{
    RiTransformBegin();
    RiCoordSysTransform( (char*) shadingSpace.asChar() );
  }

  RiTransformBegin();
  // Rotate shader space to make the preview more interesting
  RiRotate( 60., 1., 0., 0. );
  RiRotate( 60., 0., 1., 0. );
  RtFloat scale( 1.f / ( RtFloat )options.objectScale );
  RiScale( scale, scale, scale );

  if ( shader_type_TempForRefactoring=="surface" || shader_type_TempForRefactoring=="shader"/*currentShader.shader_type == SHADER_TYPE_SURFACE || currentShader.shader_type == SHADER_TYPE_SHADER */ ) //  [2/14/2012 yaoyansi]
	{
		RiColor( currentShader.rmColor );
		RiOpacity( currentShader.rmOpacity );
		//cout << "Shader: " << shaderFileName << endl;
		if ( options.fullShaderPath ) 
				RiSurface( (RtToken)shaderFileName.c_str(), RI_NULL );
		else
		{
			liqShader liqAssignedShader( shaderObj );
			liqAssignedShader.forceAs = SHADER_TYPE_SURFACE;
			liqAssignedShader.write();
		}
  } 
	else if ( shader_type_TempForRefactoring=="displacement"/*currentShader.shader_type == SHADER_TYPE_DISPLACEMENT*/ ) //  [2/14/2012 yaoyansi]
	{
		RtToken Kd( "Kd" );
		RtFloat KdValue( 1. );
#ifdef GENERIC_RIBLIB    
    // !!! current ribLib has wrong interpretation of RiSurface parameters 
    RiSurface( "plastic", Kd, &KdValue, RI_NULL );
#else
		RiSurface( "plastic", &Kd, &KdValue, RI_NULL );
#endif    
		if ( options.fullShaderPath ) 
			RiDisplacement( (RtToken)shaderFileName.c_str(), RI_NULL );
		else 
		{
			liqShader liqAssignedShader( shaderObj );
			liqAssignedShader.forceAs = SHADER_TYPE_DISPLACEMENT;
			liqAssignedShader.write();
		}
  }
  RiTransformEnd();
  if ( shadingSpace != "" ) 
		RiTransformEnd();

 switch( options.primitiveType ) 
 {
    case CYLINDER: 
		{
      RiReverseOrientation();
      RiScale( 0.95, 0.95, 0.95 );
      RiRotate( 60., 1., 0., 0. );
      RiTranslate( 0., 0., -0.05 );
      RiCylinder( 0.5, -0.3, 0.3, 360., RI_NULL );
      RiTranslate( 0., 0., 0.3f );
      RiTorus( 0.485, 0.015, 0., 90., 360., RI_NULL );
      RiDisk( 0.015, 0.485, 360., RI_NULL );
      RiTranslate( 0., 0., -0.6 );
      RiTorus( 0.485, 0.015, 270., 360., 360., RI_NULL );
      RiReverseOrientation();
      RiDisk( -0.015, 0.485, 360., RI_NULL );
      break;
    }
    case TORUS: 
		{
      RiRotate( 45., 1., 0., 0. );
      RiTranslate( 0., 0., -0.05 );
      RiReverseOrientation();
      RiTorus( 0.3f, 0.2f, 0., 360., 360., RI_NULL );
      break;
    }
    case PLANE: 
		{
      RiScale( 0.5, 0.5, 0.5 );
      RiReverseOrientation();
      static RtPoint plane[4] = {
        { -1.,  1.,  0. },
        {  1.,  1.,  0. },
        { -1., -1.,  0. },
        {  1., -1.,  0. }
      };
      RiPatch( RI_BILINEAR, RI_P, (RtPointer) plane, RI_NULL );
      break;
    }
    case TEAPOT: 
		{
      RiTranslate( 0.06f, -0.18f, 0. );
      RiRotate( -120., 1., 0., 0. );
      RiRotate( 130., 0., 0., 1. );
      RiScale( 0.2f, 0.2f, 0.2f );
			RiArchiveRecord( RI_VERBATIM, "Geometry \"teapot\"" );
      break;
    }
    case CUBE: 
		{
      /* Lovely cube with rounded corners and edges */
      RiScale( 0.35f, 0.35f, 0.35f );
      RiRotate( 60., 1., 0., 0. );
      RiRotate( 60., 0., 0., 1. );

      RiTranslate( 0.11f, 0., -0.08f );

      RiReverseOrientation();

      static RtPoint top[ 4 ] = { { -0.95, 0.95, -1. }, { 0.95, 0.95, -1. }, { -0.95, -0.95, -1. },  { 0.95, -0.95, -1. } };
      RiPatch( RI_BILINEAR, RI_P, ( RtPointer ) top, RI_NULL );

      static RtPoint bottom[ 4 ] = { { 0.95, 0.95, 1. }, { -0.95, 0.95, 1. }, { 0.95, -0.95, 1. }, { -0.95, -0.95, 1. } };
      RiPatch( RI_BILINEAR, RI_P, ( RtPointer ) bottom, RI_NULL );

      static RtPoint right[ 4 ] = { { -0.95, -1., -0.95 }, { 0.95, -1., -0.95 }, { -0.95, -1., 0.95 }, { 0.95, -1., 0.95 } };
      RiPatch( RI_BILINEAR, RI_P, ( RtPointer ) right, RI_NULL );

      static RtPoint left[ 4 ] = { { 0.95, 1., -0.95 }, { -0.95, 1., -0.95 }, { 0.95, 1., 0.95 }, { -0.95, 1., 0.95 } };
      RiPatch( RI_BILINEAR, RI_P, ( RtPointer ) left, RI_NULL );

      static RtPoint front[ 4 ] = { {-1., 0.95, -0.95 }, { -1., -0.95, -0.95 }, { -1., 0.95, 0.95 }, { -1., -0.95, 0.95 } };
      RiPatch( RI_BILINEAR, RI_P, ( RtPointer ) front, RI_NULL );

      static RtPoint back[ 4 ] = { { 1., -0.95, -0.95 }, { 1., 0.95, -0.95 }, { 1., -0.95, 0.95 }, { 1., 0.95, 0.95 } };
      RiPatch( RI_BILINEAR, RI_P, ( RtPointer ) back, RI_NULL );

      RiTransformBegin();
      RiTranslate( 0.95, 0.95, 0. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( 0.95, -0.95, 0. );
      RiRotate( -90., 0., 0., 1. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( -0.95, 0.95, 0. );
      RiRotate( 90., 0., 0., 1. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( -0.95, -0.95, 0. );
      RiRotate( 180., 0., 0., 1. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( 0., 0., 0.95 );

      RiTransformBegin();

      RiTransformBegin();
      RiTranslate( 0.95, 0.95, 0. );
      RiSphere( 0.05, 0., 0.05, 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( 0.95, -0.95, 0. );
      RiRotate( -90., 0., 0., 1. );
      RiSphere( 0.05, 0., 0.05, 90., RI_NULL );
      RiTransformEnd();

      RiRotate( 180., 0., 0., 1. );

      RiTransformBegin();
      RiTranslate( 0.95, 0.95, 0. );
      RiSphere( 0.05, 0., 0.05, 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( 0.95, -0.95, 0. );
      RiRotate( -90., 0., 0., 1. );
      RiSphere( 0.05, 0., 0.05, 90., RI_NULL );
      RiTransformEnd();

      RiTransformEnd();

      RiRotate( 90., 1., 0., 0. );

      RiTransformBegin();
      RiTranslate( 0.95, 0., 0. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( -0.95, 0., 0. );
      RiRotate( 90., 0., 0., 1. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiRotate( 90., 0., 1., 0. );

      RiTransformBegin();
      RiTranslate( 0.95, 0.,  0. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( -0.95, 0., 0. );
      RiRotate( 90., 0., 0., 1. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( 0., 0., -0.95 );

      RiTransformBegin();

      RiTransformBegin();
      RiTranslate( 0.95, 0.95, 0. );
      RiSphere( 0.05, -0.05, 0., 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( 0.95, -0.95, 0. );
      RiRotate( -90., 0., 0., 1. );
      RiSphere( 0.05, -0.05, 0., 90., RI_NULL );
      RiTransformEnd();

      RiRotate( 180., 0., 0., 1. );

      RiTransformBegin();
      RiTranslate( 0.95, 0.95, 0. );
      RiSphere( 0.05, -0.05, 0., 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( 0.95, -0.95, 0. );
      RiRotate( -90., 0., 0., 1. );
      RiSphere( 0.05, -0.05, 0., 90., RI_NULL );
      RiTransformEnd();

      RiTransformEnd();

      RiRotate( 90., 1., 0., 0. );

      RiTransformBegin();
      RiTranslate( -0.95, 0.,  0. );
      RiRotate( 180., 0., 0., 1. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( 0.95, 0.,  0. );
      RiRotate( -90., 0., 0., 1. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiRotate( 90., 0., 1., 0. );

      RiTransformBegin();
      RiTranslate( 0.95, 0.,  0. );
      RiRotate( -90., 0., 0., 1. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiTransformBegin();
      RiTranslate( -0.95, 0.,  0. );
      RiRotate( 180., 0., 0., 1. );
      RiCylinder( 0.05, -0.95, 0.95, 90., RI_NULL );
      RiTransformEnd();

      RiTransformEnd();

      break;
    }
    case CUSTOM: 
		{
      //cout <<"custom : "<<options.customRibFile<<endl;
      if ( fileExists( options.customRibFile.c_str() ) ) 
			{
        RiReadArchive( const_cast< RtToken >( options.customRibFile.c_str() ), NULL, RI_NULL );
      }
      break;
    }
    case SPHERE:
    default: 
		{
      RiRotate( 60., 1., 0., 0. );
      RiReverseOrientation();
      RiSphere( 0.5, -0.5, 0.5, 360., RI_NULL );
      break;
    }
  }

  RiAttributeEnd();
  /*
   * Backplane
   */
  if( options.backPlane ) 
	{
    if ( options.customBackplane.empty() ) 
		{
      RiAttributeBegin();
      RiScale( 0.91, 0.91, 0.91 );
      if( MString("displacement")==shader_type_TempForRefactoring/*SHADER_TYPE_DISPLACEMENT == currentShader.shader_type*/ ) //  [2/14/2012 yaoyansi]
			{
        RtColor bg = { 0.698, 0.698, 0. };
        RiColor( bg );
      } else 
        RiSurface( const_cast< RtToken >( options.backPlaneShader.c_str() ), RI_NULL );




      static RtPoint backplane[4] = {
        { -1.,  1.,  2. },
        {  1.,  1.,  2. },
        { -1., -1.,  2. },
        {  1., -1.,  2. }
      };
      RiPatch( RI_BILINEAR, RI_P, (RtPointer) backplane, RI_NULL );
      RiAttributeEnd();
    } 
		else 
		{
      if ( fileExists( options.customBackplane.c_str() ) ) 
			{
        RiAttributeBegin();
          RiScale( 1., 1., -1. );
          RiReadArchive( const_cast< RtString >( options.customBackplane.c_str() ), NULL, RI_NULL );
        RiAttributeEnd();
      }
    }
  }

  RiWorldEnd();

/* this caused maya to hang up under windoof - Alf
#ifdef _WIN32
//	Wait until the renderer is done
	while( !fileFullyAccessible( options.displayName.c_str() ) );
#endif
*/
  RiEnd();
  if(liqglo.m_logMsgFlush)
  {
	fflush( NULL );
  }
	}
Exemple #4
0
/** Create a RIB representation of the given node in the DAG as a ribgen.
 */
liqRibObj::liqRibObj( const MDagPath &path, ObjectType objType )
:
  written( 0 ),
  instanceMatrices(),
  objectHandle( NULL ),
  referenceCount( 0 ),
  data()
{
  LIQDEBUGPRINTF( "-> creating dag node handle rep\n");

  MStatus status;
  MObject obj( path.node() );
  MObject skip;

  //lightSources = NULL;
  MFnDagNode nodeFn( obj );

  // Store the matrices for all instances of this node at this time
  // so that they can be used to determine if this node's transformation
  // is animated.  This information is used for doing motion blur.
  MDagPathArray instanceArray;
  nodeFn.getAllPaths( instanceArray );
  unsigned last( instanceArray.length() );
  instanceMatrices.resize( last );
  for ( unsigned i( 0 ); i < last; i++ ) instanceMatrices[ i ] = instanceArray[ i ].inclusiveMatrix();

  LIQDEBUGPRINTF( "-> checking handles display status\n");

  ignore = !areObjectAndParentsVisible( path );
  if ( !ignore ) ignore = !areObjectAndParentsTemplated( path );
  if ( !ignore ) ignore = !isObjectPrimaryVisible( path );

  // check that the shape's transform does not a have a liqIgnoreShapes attribute.
  ignoreShapes = false;
  MDagPath searchPath( path );
  while ( searchPath.apiType() != ( MFn::kTransform ) && searchPath.length() > 1 ) searchPath.pop();
  
  MFnDagNode transformDN( searchPath );
  status.clear();
  MPlug ignorePlug = transformDN.findPlug( "liqIgnoreShapes", &status );
  if ( status == MS::kSuccess ) ignorePlug.getValue( ignoreShapes );

  ignoreShadow = !isObjectCastsShadows( path );
  if ( !ignoreShadow ) ignoreShadow = !areObjectAndParentsVisible( path );
  if ( !ignoreShadow ) ignoreShadow = !areObjectAndParentsTemplated( path );
  
  receiveShadow = isObjectReceivesShadows( path );

  // don't bother storing it if it's not going to be visible!
  LIQDEBUGPRINTF( "-> about to create rep\n");

  if ( !ignore || !ignoreShadow ) 
  {
    if ( objType == MRT_RibGen ) 
    {
      type = MRT_RibGen;
      data = liqRibDataPtr( new liqRibGenData( obj, path ) );
    } 
    else 
    {
      // check to see if object's class is derived from liqCustomNode
      liqCustomNode *customNode( NULL );
      MFnDependencyNode mfnDepNode( obj, &status );
      if ( status ) 
      {
        MPxNode *mpxNode( mfnDepNode.userNode() );
        if ( mpxNode ) 
          customNode = dynamic_cast< liqCustomNode* >( mpxNode ); // will be NULL if cast is not invalid
      }
      // Store the geometry/light/shader data for this object in RIB format
      if ( customNode ) 
      {
        type = MRT_Custom;
        data = liqRibDataPtr( new liqRibCustomNode( (( !ignoreShapes )? obj : skip ), customNode ) );
      } 
      else if ( obj.hasFn(MFn::kNurbsSurface) ) 
      {
        type = MRT_Nurbs;
        data = liqRibDataPtr( new liqRibSurfaceData( ( !ignoreShapes )? obj : skip ) );
      } 
      else if ( obj.hasFn(MFn::kSubdiv) ) 
      {
        type = MRT_Subdivision;
        data = liqRibDataPtr( new liqRibMayaSubdivisionData( ( !ignoreShapes )? obj : skip ) );
      } 
      else if ( obj.hasFn(MFn::kNurbsCurve) ) 
      {
        type = MRT_NuCurve;
        data = liqRibDataPtr( new liqRibNuCurveData( ( !ignoreShapes )? obj : skip ) );
      } 
      else if ( obj.hasFn(MFn::kPfxGeometry) ) 
      {
	      type = objType;
        data = liqRibDataPtr( new liqRibPfxData( (( !ignoreShapes )? obj : skip), objType ) );
      } 
      else if ( obj.hasFn( MFn::kPfxToon ) ) 
      {
        type = MRT_PfxToon;
        data = liqRibDataPtr( new liqRibPfxToonData( ( !ignoreShapes )? obj : skip ) );
      } 
      else if ( obj.hasFn( MFn::kPfxHair ) ) 
      {
        type = MRT_PfxHair;
        //LIQDEBUGPRINTF( "--> new liqRibPfxHairData\n");
        data = liqRibDataPtr( new liqRibPfxHairData( ( !ignoreShapes )? obj : skip ) );
      } 
      else if ( obj.hasFn( MFn::kParticle ) || obj.hasFn( MFn::kNParticle ) ) 
      {
        type = MRT_Particles;
        data = liqRibDataPtr( new liqRibParticleData( ( !ignoreShapes )? obj : skip ) );
      } 
      // if you want to use plugin shapes as placeholders for example
			// i.e. you want to use shave & haircut and attach a custom shader to it
			else if ( obj.hasFn( MFn::kPluginShape ) )
			{
				type = MRT_Weirdo; // lets use this at least once :)
				data = liqRibDataPtr( new liqRibSurfaceData( skip ) ); // you could use any here
			}
      else if ( obj.hasFn( MFn::kMesh ) ) 
      {
        float   	areaIntensity;
        // may be explicit "areaLight" attribute would be better ...
        liquidGetPlugValue( nodeFn, "areaIntensity", areaIntensity, status );
        if ( status == MS::kSuccess )
        {
          // it should be AreaLight ( until better solution...)
          type = MRT_Light;
          data = liqRibDataPtr( new liqAreaLightData( ( !ignoreShapes )? obj : skip ) );
        }
        else
        { 
          // we know we are dealing with a mesh here, now we check to see if it
          // needs to be handled as a subdivision surface
          bool usingSubdiv ( false );
          liquidGetPlugValue( nodeFn, "liqSubdiv", usingSubdiv, status );

          bool usingSubdivOld ( false );
          liquidGetPlugValue( nodeFn, "subDMesh", usingSubdivOld, status );
 
          // make Liquid understand MTOR subdiv attribute
          bool usingSubdivMtor ( false );
          if ( liqglo_useMtorSubdiv ) 
            liquidGetPlugValue( nodeFn, "mtorSubdiv", usingSubdivMtor, status );

          usingSubdiv |= usingSubdivMtor | usingSubdivOld;
          if ( usingSubdiv ) 
          {
            // we've got a subdivision surface
            bool useHierarchicalSubdiv ( false );
            liquidGetPlugValue( nodeFn, "liqHierarchicalSubdiv", useHierarchicalSubdiv, status );
            
            type = MRT_Subdivision;
					  if ( useHierarchicalSubdiv )
						  data = liqRibDataPtr( new liqRibHierarchicalSubdivisionData( ( !ignoreShapes )? obj : skip ) );
					  else
						  data = liqRibDataPtr( new liqRibSubdivisionData( ( !ignoreShapes )? obj : skip ) );
          } 
          else 
          {
            // it's a regular mesh
            type = MRT_Mesh;
            data = liqRibDataPtr( new liqRibMeshData( ( !ignoreShapes )? obj : skip ) );
          }
        }
      } 
      else if ( obj.hasFn( MFn::kLight ) ) 
      {
        type = MRT_Light;
        data = liqRibDataPtr( new liqRibLightData( path ) );
      } 
      else if ( obj.hasFn( MFn::kLocator ) ) 
      {
        if ( mfnDepNode.typeName() == "liquidCoordSys" ) 
        {
          MStatus status;
          int coordSysType = 0;
          MPlug typePlug( mfnDepNode.findPlug( "type", &status ) );
          if ( MS::kSuccess == status ) typePlug.getValue( coordSysType );
          if ( coordSysType == 5 ) 
          {
            type = MRT_ClipPlane;
            data = liqRibDataPtr( new liqRibClipPlaneData( obj ) );
          } 
          else 
          {
            type = MRT_Coord;
            data = liqRibDataPtr( new liqRibCoordData( obj ) );
          }
        } 
        else
        {
          bool isCurveGroup( false );
				  if ( mfnDepNode.typeName() == "liqBoundingBoxLocator" )
				  {
            liquidGetPlugValue( mfnDepNode, "liquidCurveGroup", isCurveGroup, status );
					  if ( isCurveGroup )
					  {
						  type = MRT_Curves;
						  //if ( liqglo_renderAllCurves ) data = liqRibDataPtr( new liqRibCurvesData( obj ) );
						  //else                          data = liqRibDataPtr( new liqRibCurvesData( skip ) );
              data = liqRibDataPtr( new liqRibCurvesData( obj ) );
					  }
				  }
				  if ( !isCurveGroup )
				  {
					  type = MRT_Locator;
					  data = liqRibDataPtr( new liqRibLocatorData( obj ) );
				  }
        }
      } 
      else if ( obj.hasFn( MFn::kImplicitSphere ) ) 
      {
        type = MRT_ImplicitSphere;
        if ( !ignoreShapes ) data = liqRibDataPtr( new liqRibImplicitSphereData( obj ) );
        else                 data = liqRibDataPtr( new liqRibImplicitSphereData( skip ) );
      }
    }

    data->objDagPath = path;
  } 
  LIQDEBUGPRINTF( "==> done creating rep %s\n", path.fullPathName().asChar() );
}
Exemple #5
0
/** Create a RIB representation of the given node in the DAG as a ribgen.
 */
liqRibObj::liqRibObj( const MDagPath &path, ObjectType objType )
    :
    written( 0 ),
    instanceMatrices(),
    objectHandle( NULL ),
    referenceCount( 0 ),
    data()
{
    CM_TRACE_FUNC("liqRibObj::liqRibObj("<<path.fullPathName()<<","<<objType<<")");

    LIQDEBUGPRINTF( "-> creating dag node handle rep\n");
    MString pathName(path.fullPathName()); //debug
    MStatus status;
    MObject obj( path.node() );
    MObject skip;

    //lightSources = NULL;
    MFnDagNode nodeFn( obj );

    // Store the matrices for all instances of this node at this time
    // so that they can be used to determine if this node's transformation
    // is animated.  This information is used for doing motion blur.
    MDagPathArray instanceArray;
    nodeFn.getAllPaths( instanceArray );
    unsigned last( instanceArray.length() );
    instanceMatrices.resize( last );
    for( unsigned i( 0 ); i < last; i++ )
        instanceMatrices[ i ] = instanceArray[ i ].inclusiveMatrix();

    LIQDEBUGPRINTF( "-> checking handles display status\n");

    ignore = !areObjectAndParentsVisible( path );
    if( !ignore )
        ignore = !areObjectAndParentsTemplated( path );

    if( !ignore )
        ignore = !isObjectPrimaryVisible( path );

    // check that the shape's transform does not a have a liqIgnoreShapes attribute.
    ignoreShapes = false;
    MDagPath searchPath( path );
    while ( searchPath.apiType() != ( MFn::kTransform ) && searchPath.length() > 1 )
        searchPath.pop();

    MFnDagNode transformDN( searchPath );
    status.clear();
    MPlug ignorePlug = transformDN.findPlug( "liqIgnoreShapes", &status );
    if( status == MS::kSuccess )
        ignorePlug.getValue( ignoreShapes );

    ignoreShadow = !isObjectCastsShadows( path );
    if( !ignoreShadow )
        ignoreShadow = !areObjectAndParentsVisible( path );

    if( !ignoreShadow )
        ignoreShadow = !areObjectAndParentsTemplated( path );


    // don't bother storing it if it's not going to be visible!
    LIQDEBUGPRINTF( "-> about to create rep\n");

    if( !ignore || !ignoreShadow )
    {
        if( objType == MRT_RibGen )
        {
            type = MRT_RibGen;
            data = liqRibDataPtr( new liqRibGenData( obj, path ) );
        }
        else
        {

            // check to see if object's class is derived from liqCustomNode
            liqCustomNode *customNode( NULL );
            MFnDependencyNode mfnDepNode( obj, &status );
            if( status )
            {
                MPxNode *mpxNode( mfnDepNode.userNode() );
                if(mpxNode)
                    customNode = dynamic_cast< liqCustomNode* >( mpxNode ); // will be NULL if cast is not invalid
            }

            // Store the geometry/light/shader data for this object in RIB format
            if(customNode)
            {
                type = MRT_Custom;
                if( !ignoreShapes )
                    data = liqRibDataPtr( new liqRibCustomNode( obj, customNode ) );
                else
                    data = liqRibDataPtr( new liqRibCustomNode( skip, customNode ) );
            }
            else if( obj.hasFn(MFn::kNurbsSurface) )
            {
                type = MRT_Nurbs;
                if( !ignoreShapes )
                    data = liqRibDataPtr( new liqRibSurfaceData( obj ) );
                else
                    data = liqRibDataPtr( new liqRibSurfaceData( skip ) );
            }
            else if( obj.hasFn(MFn::kSubdiv) )
            {
                type = MRT_Subdivision;
                if( !ignoreShapes )
                    data = liqRibDataPtr( new liqRibMayaSubdivisionData( obj ) );
                else
                    data = liqRibDataPtr( new liqRibMayaSubdivisionData( skip ) );
            }
            else if( obj.hasFn(MFn::kNurbsCurve) )
            {
                type = MRT_NuCurve;
                if( !ignoreShapes )
                    data = liqRibDataPtr( new liqRibNuCurveData( obj ) );
                else
                    data = liqRibDataPtr( new liqRibNuCurveData( skip ) );
            }
            else if( obj.hasFn(MFn::kPfxGeometry) )
            {
                type = objType;
                liquidMessage2(messageInfo, "liqRibObj(MFn kPfxGeometry) type = %d\n", (int)objType);
                if( !ignoreShapes )
                    data = liqRibDataPtr( new liqRibPfxData( obj, objType ) );
                else
                    data = liqRibDataPtr( new liqRibPfxData( skip, objType ) );
            }
            else if( obj.hasFn( MFn::kPfxToon ) )
            {
                type = MRT_PfxToon;
                if( !ignoreShapes )
                    data = liqRibDataPtr( new liqRibPfxToonData( obj ) );
                else
                    data = liqRibDataPtr( new liqRibPfxToonData( skip ) );
            }
            else if( obj.hasFn( MFn::kPfxHair ) )
            {
                type = MRT_PfxHair;
                //LIQDEBUGPRINTF( "--> new liqRibPfxHairData\n");
                if( !ignoreShapes )
                    data = liqRibDataPtr( new liqRibPfxHairData( obj ) );
                else
                    data = liqRibDataPtr( new liqRibPfxHairData( skip ) );
            }
            else if( obj.hasFn( MFn::kParticle ) )
            {
                type = MRT_Particles;
                if( !ignoreShapes )
                    data = liqRibDataPtr( new liqRibParticleData( obj ) );
                else
                    data = liqRibDataPtr( new liqRibParticleData( skip ) );
            }
            // if you want to use plugin shapes as placeholders for example
            // i.e. you want to use shave & haircut and attach a custom shader to it
            else if( obj.hasFn( MFn::kPluginShape ) )
            {
                MString nodeType;
                MGlobal::executeCommand(("nodeType "+pathName), nodeType);
                liquidMessage2(messageInfo, "liqRibObj(MFn::kPluginShape) %s, type=%s\n", pathName.asChar(), nodeType.asChar());

                if(nodeType=="shaveHair")
                {
#if _USE_SHAVE_
                    type = MRT_Shave;
                    data = liqRibDataPtr( new liqRibShaveData( ignoreShapes? skip : obj ) );
#else
                    assert(0 &&"_USE_SHAVE_ is 0 (in liqConfig.h)");
#endif
                } else {
                    type = MRT_Weirdo; // lets use this at least once :)
                    data = liqRibDataPtr( new liqRibSurfaceData( skip ) ); // you could use any here
                }
            }
            else if( obj.hasFn( MFn::kMesh ) )
            {
                // we know we are dealing with a mesh here, now we check to see if it
                // needs to be handled as a subdivision surface
                bool usingSubdiv = false;
                MPlug subdivPlug = nodeFn.findPlug( "liqSubdiv", &status );
                if( status == MS::kSuccess )
                    subdivPlug.getValue( usingSubdiv );

                bool usingSubdivOld( false );
                MPlug oldSubdivPlug( nodeFn.findPlug( "subDMesh", &status ) );
                if( status == MS::kSuccess )
                    oldSubdivPlug.getValue( usingSubdivOld );

                // make Liquid understand MTOR subdiv attribute
                bool usingSubdivMtor( false );
                if( liqglo.liqglo_useMtorSubdiv )
                {
                    MPlug mtorSubdivPlug( nodeFn.findPlug( "mtorSubdiv", &status ) );
                    if( status == MS::kSuccess )
                        mtorSubdivPlug.getValue( usingSubdivMtor );
                }

                usingSubdiv |= usingSubdivMtor | usingSubdivOld;

                if( usingSubdiv )
                {
                    // we've got a subdivision surface
                    type = MRT_Subdivision;
                    if( !ignoreShapes )
                        data = liqRibDataPtr( new liqRibSubdivisionData( obj ) );
                    else
                        data = liqRibDataPtr( new liqRibSubdivisionData( skip ) );
                    type = data->type();
                }
                else
                {
                    // it's a regular mesh
                    type = MRT_Mesh;
                    if( !ignoreShapes )
                        data = liqRibDataPtr( new liqRibMeshData( obj ) );
                    else
                        data = liqRibDataPtr( new liqRibMeshData( skip ) );
                    type = data->type();
                }
            }
            else if( obj.hasFn(MFn::kLight))
            {
                type = MRT_Light;
                data = liqRibDataPtr( new liqRibLightData( path ) );
            }
            else if( mfnDepNode.typeName() == "liquidCoordSys" )
            {
                MStatus status;
                int coordSysType = 0;
                MPlug typePlug( mfnDepNode.findPlug( "type", &status ) );
                if( MS::kSuccess == status )
                    typePlug.getValue( coordSysType );
                if( coordSysType == 5 )
                {
                    type = MRT_ClipPlane;
                    data = liqRibDataPtr( new liqRibClipPlaneData( obj ) );
                }
                else
                {
                    type = MRT_Coord;
                    data = liqRibDataPtr( new liqRibCoordData( obj ) );
                }
            }
            else if( obj.hasFn(MFn::kLocator) && mfnDepNode.typeName() != "liquidCoordSys" )
            {
                bool isCurveGroup( false );
                if( mfnDepNode.typeName() == "liquidBoundingBox" )
                {
                    MPlug curveGroupPlug( mfnDepNode.findPlug( "liquidCurveGroup", &status ) );
                    if( status == MS::kSuccess )
                        curveGroupPlug.getValue( isCurveGroup );
                    if( isCurveGroup )
                    {
                        type = MRT_Curves;
                        if( liqglo.liqglo_renderAllCurves )
                            data = liqRibDataPtr( new liqRibCurvesData( obj ) );
                        else
                            data = liqRibDataPtr( new liqRibCurvesData( skip ) );
                    }
                }
                if( !isCurveGroup )
                {
                    type = MRT_Locator;
                    data = liqRibDataPtr( new liqRibLocatorData( obj ) );
                }
            }
            else if( obj.hasFn( MFn::kImplicitSphere ) )
            {
                type = MRT_ImplicitSphere;
                if( !ignoreShapes )
                    data = liqRibDataPtr( new liqRibImplicitSphereData( obj ) );
                else
                    data = liqRibDataPtr( new liqRibImplicitSphereData( skip ) );
            }
        }
        data->objDagPath = path;
    }
    LIQDEBUGPRINTF( "==> done creating rep %s\n", path.fullPathName().asChar() );
    if ( debugMode )
    {
        if ( ignore ) LIQDEBUGPRINTF( "\t ignoring...\n" );
        if ( ignoreShadow ) LIQDEBUGPRINTF( "\t ignoring in shadow...\n" );
    }
}