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 ); } }
/** 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() ); }
/** 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" ); } }