예제 #1
0
		void exportShadingInputs()
		{
			MObject proceduralNode = m_dagPath.node();
			MPlug nullPlug;
			
			MIteratorType filter;
			MIntArray filterTypes;
			filterTypes.append( MFn::kShadingEngine );
			filterTypes.append( MFn::kDisplacementShader );			
			filter.setFilterList( filterTypes );
			
			MItDependencyGraph itDG( proceduralNode, nullPlug, filter, MItDependencyGraph::kUpstream );
			while( !itDG.isDone() )
			{
				MObject node = itDG.currentItem();
				MFnDependencyNode fnNode( node );
				MPlug plug;
				if( fnNode.typeName() == "displacementShader" )
				{
					plug = fnNode.findPlug( "displacement" );
				}
				else
				{
					plug = fnNode.findPlug( "dsm" );
				}
				ExportNode( plug );
				itDG.next();
			}
		}
예제 #2
0
void SGMExporter::ExportObjects(IGameScene *igame_scene, std::ostream &os)
{
	int totalNodeCount = igame_scene ->GetTotalNodeCount();
	SetProgressSteps(totalNodeCount);

	int c_top_nodes = igame_scene ->GetTopLevelNodeCount();

	for (int i = 0; i < c_top_nodes; i++)
		ExportNode(igame_scene ->GetTopLevelNode(i), os);
}
xml::XMLElement* DecisionTree::exportXMLSettings(xml::XMLElement* elem)
{
	xml::XMLElement*e=new xml::XMLElement(mT("DecisionTree"));
	elem->addSubElement(e);
	if(!m_root)
		return e;

	ExportNode(m_root,e);

	return e;
}
예제 #4
0
void SGMExporter::ExportObjects(BinaryWriter *fh)
{
	int totalNodeCount = gScene ->GetTotalNodeCount();
	SetProgressSteps(totalNodeCount);

	int c_top_nodes = gScene ->GetTopLevelNodeCount();
	fh ->Write(c_top_nodes);

	for (int i = 0; i < c_top_nodes; i++)
		ExportNode(gScene ->GetTopLevelNode(i), fh);
}
예제 #5
0
void SGMExporter::ExportNode(IGameNode *gNode, BinaryWriter *bw)
{
	// despite of that we don't need IGameObject, we need to initialize it to
	// gain access to controller data
	IGameObject *gObject = gNode ->GetIGameObject();
	if (gObject == NULL)
	{
		//log ->AddLog(sb() + "unable to get IGameObject for node '" + gNode ->GetName() + "'");
		return;
	}

	gObject ->InitializeData(); // dont need to check suckess of this operation.
								// we dont need mesh data

	bw ->Write(gNode ->GetNodeID());
	bw ->Write(StringUtils::ToNarrow(gNode ->GetName()));

	ExportMatrix(gNode ->GetWorldTM().Inverse(), bw);

	IGameControl *gControl = gNode ->GetIGameControl();
	if (gControl != NULL)
	{
		if (!ExportPositionKeys(gNode, gControl, bw))
			ExportStaticPos(gNode, bw);

		if (!ExportRotationKeys(gNode, gControl, bw))
			ExportStaticRot(gNode, bw);

		if (!ExportScaleKeys(gNode, gControl, bw))
			ExportStaticScale(gNode, bw);
	}
	else
	{
		// no pos, rot, scale keys
		bw ->Write((int)0);
		ExportStaticPos(gNode, bw);

		bw ->Write((int)0);
		ExportStaticRot(gNode, bw);

		bw ->Write((int)0);
		ExportStaticScale(gNode, bw);
	}

	int nodeChildCount = gNode ->GetChildCount();
	bw ->Write(nodeChildCount);

	for (int i = 0; i < nodeChildCount; i++)
		ExportNode(gNode ->GetNodeChild(i), bw);

	gNode ->ReleaseIGameObject();

	StepProgress();
}
                /// Returns the arnold shader assigned to the procedural. This duplicates
                /// code in GeometryTranslator.h, but there's not much can be done about that
                /// since the GeometryTranslator isn't part of the MtoA public API.
                AtNode *arnoldShader(AtNode* node)
                {
                  m_displaced = false;

                  float maximumDisplacementPadding = -AI_BIG;
                  bool enableAutoBump = false;

                  unsigned instNumber = m_dagPath.isInstanced() ? m_dagPath.instanceNumber() : 0;
                  MPlug shadingGroupPlug = GetNodeShadingGroup(m_dagPath.node(), instNumber);

                  //find and export any displacment shaders attached
                  // DISPLACEMENT MATERIAL EXPORT
                  MPlugArray        connections;
                  MFnDependencyNode fnDGShadingGroup(shadingGroupPlug.node());
                  MPlug shaderPlug = fnDGShadingGroup.findPlug("displacementShader");
                  shaderPlug.connectedTo(connections, true, false);

                  // are there any connections to displacementShader?
                  if (connections.length() > 0)
                  {
                     m_displaced = true;
                     MObject dispNode = connections[0].node();
                     GetDisplacement(dispNode, maximumDisplacementPadding, enableAutoBump);
                     m_dispPadding = maximumDisplacementPadding;
                     AtNode* dispImage(ExportNode(connections[0]));

                     m_dispNode = dispImage;
                  }

                  // Only export displacement attributes if a displacement is applied
                  if (m_displaced)
                  {
                      std::cout << "arnoldShader::m_displaced :: " << m_displaced << std::endl;
                     // Note that disp_height has no actual influence on the scale of the displacement if it is vector based
                     // it only influences the computation of the displacement bounds
                    // AiNodeSetFlt(node, "disp_padding", maximumDisplacementPadding);
                  }

                  // return the exported surface shader
                  return ExportNode( shadingGroupPlug );
                }
예제 #7
0
bool ExporterProject::ExportToStream(StreamFormatted& stream)
{
    // write out file format sentinel
    stream.write(kExporterFormatMagicNumber);

    // write out the version
    stream.write(kVersion);

    Node* rootNode = MySceneEditor::instance()->GetRootNode();
    NodeItem* rootItem = MainWindow::instance()->GetNodeItemFromNode(rootNode);

    return ExportNode(stream, rootItem);
}
예제 #8
0
bool ExporterProject::ExportNode(StreamFormatted& stream, NodeItem* item)
{
    Node* node = item->GetNode();

    // write out the node class id
    stream.write(node->classId());

    // write out the node name
    std::string name(item->SceneItem()->text(0).toUtf8());
    ExportProperty(stream, &name);

    // write out the count of items
    stream.write(uint32_t(item->Drivers().size()));

    // export each node driver
    const NodeItem::tNodeDrivers& drivers = item->Drivers();
    NodeItem::tNodeDrivers::const_iterator it(drivers.begin()), itEnd(drivers.end());
    for (; it != itEnd; ++it)
    {
        INodeDriver* driver = *it;

        // write out id of driver
        stream.write(driver->Id());

        // write out driver data
        driver->Update();
        driver->Export(stream, this);
    }

    // export children
    Array* children = node->getChildren();

    // write child count
    stream.write(uint32_t(children ? children->count() : 0));

    Object* object;
    CCARRAY_FOREACH(children, object)
    {
        Node* child = (Node*)object;
        NodeItem* childItem = MainWindow::instance()->GetNodeItemFromNode(child);
        if (childItem)
        {
            if (!ExportNode(stream, childItem))
            {
                // insert logging
                return false;
            }
        }
    }
void Unreal3DExport::ExportNode( IGameNode * child )
{
    DebugPrint( _T("ExportNode: %s\n"), child->GetName() );
    CheckCancel();

    ProgressMsg.printf(GetString(IDS_INFO_ENUM_OBJ),NodeIdx,NodeCount,TSTR(child->GetName()));
    pInt->ProgressUpdate(Progress+((float)NodeIdx/NodeCount*U3D_PROGRESS_ENUM), FALSE, ProgressMsg.data());
    ++NodeIdx;
    
    if( child->IsGroupOwner() )
    {
        // do nothing
    }
    else
    {
        IGameObject * obj = child->GetIGameObject();

        switch(obj->GetIGameType())
        {
            case IGameObject::IGAME_MESH:
            { 
                if( !bIgnoreHidden || !child->IsNodeHidden() )
                {
                    Nodes.Append(1,&child);
                }
                break;
            }
			case IGameObject::IGAME_HELPER:
            {
                if( !bIgnoreHidden || !child->IsNodeHidden() )
                {
                    TrackedNodes.Append(1,&child);
                }
            }
            break;
        }

        child->ReleaseIGameObject();
    }   
    
    for( int i=0; i<child->GetChildCount(); ++i )
    {
        IGameNode * n = child->GetNodeChild(i);
        ExportNode(n);
    }
}
예제 #10
0
void SGMExporter::ExportNode(IGameNode *igame_node, std::ostream &os)
{
	INode *node = igame_node ->GetMaxNode();
	Object *object = node ->GetObjectRef();

	if (object != NULL)
	{
		if (object ->ClassID() == Class_ID(SPOT_LIGHT_CLASS_ID, 0))
			ExportLight((LightObject*)object, node, os);
	}

	int node_childs_count = igame_node ->GetChildCount();
	for (int i = 0; i < node_childs_count; i++)
		ExportNode(igame_node ->GetNodeChild(i), os);

	StepProgress();
}
void Unreal3DExport::Init()
{
    // Init
    CheckCancel();
    pScene = GetIGameInterface();
    GetConversionManager()->SetUserCoordSystem(UnrealCoords);
    if( bExportSelected )
    {
        Tab<INode*> selnodes;;
        for( int i=0; i<pInt->GetSelNodeCount(); ++i )
        {
            INode* n = pInt->GetSelNode(i);
            selnodes.Append(1,&n);
        }
        if( !pScene->InitialiseIGame(selnodes,false)  )
            throw MAXException(GetString(IDS_ERR_IGAME));
    }
    else
    {
        if( !pScene->InitialiseIGame() )
            throw MAXException(GetString(IDS_ERR_IGAME));
    }


    // Enumerate scene
    NodeCount = pScene->GetTotalNodeCount();
    for( int i=0; i<pScene->GetTopLevelNodeCount(); ++i )
    {
        IGameNode * n = pScene->GetTopLevelNode(i);
        ExportNode(n);
    }
    Progress += U3D_PROGRESS_ENUM;


    // Get animation info
    FrameStart = pScene->GetSceneStartTime() / pScene->GetSceneTicks();
    FrameEnd = pScene->GetSceneEndTime() / pScene->GetSceneTicks();
    FrameCount = FrameEnd - FrameStart+1;
    if( FrameCount <= 0 || FrameEnd < FrameStart ) 
    {
        ProgressMsg.printf(GetString(IDS_ERR_FRAMERANGE),FrameStart,FrameEnd);
        throw MAXException(ProgressMsg.data());
    }
    pScene->SetStaticFrame(FrameStart);
}
예제 #12
0
		/// Returns the arnold shader to assign to the procedural.
		AtNode *arnoldShader()
		{	
			bool overrideShaders = false;
			MPlug plug = FindMayaObjectPlug( "overrideProceduralShaders" );
			if( !plug.isNull() )
			{
				// if we've been told explicitly not to override the shaders
				// in the procedurals, then early out.
				overrideShaders = plug.asBool();
				if( !overrideShaders )
				{
					return 0;
				}
			}
			
			unsigned instNumber = m_dagPath.isInstanced() ? m_dagPath.instanceNumber() : 0;
			MPlug shadingGroupPlug = GetNodeShadingGroup(m_dagPath.node(), instNumber);
			
			if( !overrideShaders )
			{
				// if we weren't explicitly told to override the shaders, then
				// decide whether to or not based on whether a non-default
				// shader has been applied to the shape by the user.
				MObject shadingGroupNode = shadingGroupPlug.node();
				MFnDependencyNode fnShadingGroupNode( shadingGroupNode );
				if( fnShadingGroupNode.name() != "initialShadingGroup" )
				{
					overrideShaders = true;
				}
			}
			
			if( overrideShaders )
			{
				return ExportNode( shadingGroupPlug );
			}
			else
			{
				return 0;
			}
		}
void DecisionTree::ExportNode(DecisionTreeNode*node,xml::XMLElement* elem)
{
	xml::XMLElement*e=new xml::XMLElement(mT("Node"));
	elem->addSubElement(e);
	IDecisionAttribute*attr= m_scheme->GetAttribute(node->attributeID);
	IDecisionAttribute*tAttr= m_scheme->GetAttribute(m_targetAttr);
	e->addAttribute(mT("Name"),attr->GetName());
	for (int i=0;i<node->values.size();++i)
	{
		xml::XMLElement*e1=new xml::XMLElement(mT("Value"));
		e->addSubElement(e1);
		core::string v=attr->GetValueString(i);
		e1->addAttribute(mT("value"),v);
		if(node->values[i].classificationVal)
		{
			core::string v=tAttr->GetValueString(node->values[i].assignedBucket);
			e1->addAttribute(tAttr->GetName(),v);
		}else
		{
			ExportNode(node->values[i].subNode,e1);
		}
	}
}
void CScriptedShapeTranslator::RunScripts(AtNode *atNode, unsigned int step, bool update)
{
   std::map<std::string, CScriptedTranslator>::iterator translatorIt;
   MFnDependencyNode fnNode(GetMayaObject());
   
   translatorIt = gTranslators.find(fnNode.typeName().asChar());
   if (translatorIt == gTranslators.end())
   {
      AiMsgError("[mtoa.scriptedTranslators] No command to export node \"%s\" of type %s.", fnNode.name().asChar(), fnNode.typeName().asChar());
      return;
   }
   
   MString exportCmd = translatorIt->second.exportCmd;
   MString cleanupCmd = translatorIt->second.cleanupCmd;
   
   MFnDagNode node(m_dagPath.node());
   
   bool isMasterDag = false;
   bool transformBlur = IsMotionBlurEnabled(MTOA_MBLUR_OBJECT) && IsLocalMotionBlurEnabled();
   bool deformBlur = IsMotionBlurEnabled(MTOA_MBLUR_DEFORM) && IsLocalMotionBlurEnabled();
   
   char buffer[64];
   
   MString command = exportCmd;
   command += "(";
   
   sprintf(buffer, "%f", GetExportFrame());
   command += buffer;
   command += ", ";
   
   sprintf(buffer, "%d", step);
   command += buffer;
   command += ", ";
   
   // current sample frame
   sprintf(buffer, "%f", GetSampleFrame(m_session, step));
   command += buffer;
   command += ", ";
   
   // List of arnold attributes the custom shape export command has overriden
   MStringArray attrs;
   
   if (!m_masterNode)
   {
      command += "(\"" + m_dagPath.partialPathName() + "\", \"";
      command += AiNodeGetName(atNode);
      command += "\"), None)";
      isMasterDag = true;
   }
   else
   {
      command += "(\"" + m_dagPath.partialPathName() + "\", \"";
      command += AiNodeGetName(atNode);
      command += "\"), (\"" + GetMasterInstance().partialPathName() + "\", \"";
      command += AiNodeGetName(m_masterNode);
      command += "\"))";
   }
   
   MStatus status = MGlobal::executePythonCommand(command, attrs);
   if (!status)
   {
      AiMsgError("[mtoa.scriptedTranslators] Failed to export node \"%s\".", node.name().asChar());
      return;
   }
   
   // Build set of attributes already processed
   std::set<std::string> attrsSet;
   for (unsigned int i=0; i<attrs.length(); ++i)
   {
      attrsSet.insert(attrs[i].asChar());
   }
   std::set<std::string>::iterator attrsEnd = attrsSet.end();
   
   // Should be getting displacement shader from master instance only
   //   as arnold do not support displacement shader overrides for ginstance
   MFnDependencyNode masterShadingEngine;
   MFnDependencyNode shadingEngine;
   float dispPadding = -AI_BIG;
   float dispHeight = 1.0f;
   float dispZeroValue = 0.0f;
   bool dispAutobump = false;
   bool outputDispPadding = false;
   bool outputDispHeight = false;
   bool outputDispZeroValue = false;
   bool outputDispAutobump = false;
   
   const AtNodeEntry *anodeEntry = AiNodeGetNodeEntry(atNode);
   
   GetShapeInstanceShader(m_dagPath, shadingEngine);
   if (!IsMasterInstance())
   {
      GetShapeInstanceShader(GetMasterInstance(), masterShadingEngine);
   }
   else
   {
      masterShadingEngine.setObject(shadingEngine.object());
   }
   
   AtMatrix matrix;
   MMatrix mmatrix = m_dagPath.inclusiveMatrix();
   ConvertMatrix(matrix, mmatrix);
   
   // Set transformation matrix
   if (attrsSet.find("matrix") == attrsEnd)
   {
      if (HasParameter(anodeEntry, "matrix"))
      {
         if (transformBlur)
         {
            if (step == 0)
            {
               AtArray* matrices = AiArrayAllocate(1, GetNumMotionSteps(), AI_TYPE_MATRIX);
               AiArraySetMtx(matrices, step, matrix);
               AiNodeSetArray(atNode, "matrix", matrices);
            }
            else
            {
               AtArray* matrices = AiNodeGetArray(atNode, "matrix");
               AiArraySetMtx(matrices, step, matrix);
            }
         }
         else
         {
            AiNodeSetMatrix(atNode, "matrix", matrix);
         }
      }
   }
   
   // Set bounding box
   if (attrsSet.find("min") == attrsEnd && attrsSet.find("max") == attrsEnd)
   {
      // Now check if min and max parameters are valid parameter names on arnold node
      if (HasParameter(anodeEntry, "min") != 0 && HasParameter(anodeEntry, "max") != 0)
      {
         if (step == 0)
         {
            MBoundingBox bbox = node.boundingBox();
            
            MPoint bmin = bbox.min();
            MPoint bmax = bbox.max();
            
            AiNodeSetPnt(atNode, "min", static_cast<float>(bmin.x), static_cast<float>(bmin.y), static_cast<float>(bmin.z));
            AiNodeSetPnt(atNode, "max", static_cast<float>(bmax.x), static_cast<float>(bmax.y), static_cast<float>(bmax.z));
         }
         else
         {
            if (transformBlur || deformBlur)
            {
               AtPoint cmin = AiNodeGetPnt(atNode, "min");
               AtPoint cmax = AiNodeGetPnt(atNode, "max");
               
               MBoundingBox bbox = node.boundingBox();
               
               MPoint bmin = bbox.min();
               MPoint bmax = bbox.max();
               
               if (bmin.x < cmin.x)
                  cmin.x = static_cast<float>(bmin.x);
               if (bmin.y < cmin.y)
                  cmin.y = static_cast<float>(bmin.y);
               if (bmin.z < cmin.z)
                  cmin.z = static_cast<float>(bmin.z);
               if (bmax.x > cmax.x)
                  cmax.x = static_cast<float>(bmax.x);
               if (bmax.y > cmax.y)
                  cmax.y = static_cast<float>(bmax.y);
               if (bmax.z > cmax.z)
                  cmax.z = static_cast<float>(bmax.z);
               
               AiNodeSetPnt(atNode, "min", cmin.x, cmin.y, cmin.z);
               AiNodeSetPnt(atNode, "max", cmax.x, cmax.y, cmax.z);
            }
         }
      }
   }
   
   if (step == 0)
   {
      // Set common attributes
      MPlug plug;
      
      if (AiNodeIs(atNode, "procedural"))
      {
         // Note: it is up to the procedural to properly forward (or not) those parameters to the node
         //       it creates
         
         if (attrsSet.find("subdiv_type") == attrsEnd)
         {
            plug = FindMayaPlug("subdiv_type");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiSubdivType");
            }
            if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_type", atNode, "constant INT"))
            {
               AiNodeSetInt(atNode, "subdiv_type", plug.asInt());
            }
         }
         
         if (attrsSet.find("subdiv_iterations") == attrsEnd)
         {
            plug = FindMayaPlug("subdiv_iterations");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiSubdivIterations");
            }
            if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_iterations", atNode, "constant BYTE"))
            {
               AiNodeSetByte(atNode, "subdiv_iterations", plug.asInt());
            }
         }
         
         if (attrsSet.find("subdiv_adaptive_metric") == attrsEnd)
         {
            plug = FindMayaPlug("subdiv_adaptive_metric");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiSubdivAdaptiveMetric");
            }
            if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_adaptive_metric", atNode, "constant INT"))
            {
               AiNodeSetInt(atNode, "subdiv_adaptive_metric", plug.asInt());
            }
         }
         
         if (attrsSet.find("subdiv_pixel_error") == attrsEnd)
         {
            plug = FindMayaPlug("subdiv_pixel_error");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiSubdivPixelError");
            }
            if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_pixel_error", atNode, "constant FLOAT"))
            {
               AiNodeSetFlt(atNode, "subdiv_pixel_error", plug.asFloat());
            }
         }
         
         if (attrsSet.find("subdiv_dicing_camera") == attrsEnd)
         {
            plug = FindMayaPlug("subdiv_dicing_camera");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiSubdivDicingCamera");
            }
            if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_dicing_camera", atNode, "constant NODE"))
            {
               AtNode *cameraNode = NULL;
               
               MPlugArray plugs;
               plug.connectedTo(plugs, true, false);
               
               if (plugs.length() == 1)
               {
                  MFnDagNode camDag(plugs[0].node());
                  MDagPath camPath;
                  
                  if (camDag.getPath(camPath) == MS::kSuccess)
                  {
                     cameraNode = ExportDagPath(camPath);
                  }
               }
               
               AiNodeSetPtr(atNode, "subdiv_dicing_camera", cameraNode);
            }
         }
         
         if (attrsSet.find("subdiv_uv_smoothing") == attrsEnd)
         {
            plug = FindMayaPlug("subdiv_uv_smoothing");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiSubdivUvSmoothing");
            }
            if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_uv_smoothing", atNode, "constant INT"))
            {
               AiNodeSetInt(atNode, "subdiv_uv_smoothing", plug.asInt());
            }
         }
         
         if (attrsSet.find("subdiv_smooth_derivs") == attrsEnd)
         {
            plug = FindMayaPlug("aiSubdivSmoothDerivs");
            if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_smooth_derivs", atNode, "constant BOOL"))
            {
               AiNodeSetBool(atNode, "subdiv_smooth_derivs", plug.asBool());
            }
         }
         
         if (attrsSet.find("smoothing") == attrsEnd)
         {
            // Use maya shape built-in attribute
            plug = FindMayaPlug("smoothShading");
            if (!plug.isNull() && HasParameter(anodeEntry, "smoothing", atNode, "constant BOOL"))
            {
               AiNodeSetBool(atNode, "smoothing", plug.asBool());
            }
         }
         
         if (attrsSet.find("disp_height") == attrsEnd)
         {
            plug = FindMayaPlug("aiDispHeight");
            if (!plug.isNull())
            {
               outputDispHeight = true;
               dispHeight = plug.asFloat();
            }
         }
         
         if (attrsSet.find("disp_zero_value") == attrsEnd)
         {
            plug = FindMayaPlug("aiDispZeroValue");
            if (!plug.isNull())
            {
               outputDispZeroValue = true;
               dispZeroValue = plug.asFloat();
            }
         }
         
         if (attrsSet.find("disp_autobump") == attrsEnd)
         {
            plug = FindMayaPlug("aiDispAutobump");
            if (!plug.isNull())
            {
               outputDispAutobump = true;
               dispAutobump = plug.asBool();
            }
         }
         
         if (attrsSet.find("disp_padding") == attrsEnd)
         {
            plug = FindMayaPlug("aiDispPadding");
            if (!plug.isNull())
            {
               outputDispPadding = true;
               dispPadding = MAX(dispPadding, plug.asFloat());
            }
         }
         
         // Set diplacement shader
         if (attrsSet.find("disp_map") == attrsEnd)
         {
            if (masterShadingEngine.object() != MObject::kNullObj)
            {
               MPlugArray shaderConns;
               
               MPlug shaderPlug = masterShadingEngine.findPlug("displacementShader");
               
               shaderPlug.connectedTo(shaderConns, true, false);
               
               if (shaderConns.length() > 0)
               {
                  MFnDependencyNode dispNode(shaderConns[0].node());
                  
                  plug = dispNode.findPlug("aiDisplacementPadding");
                  if (!plug.isNull())
                  {
                     outputDispPadding = true;
                     dispPadding = MAX(dispPadding, plug.asFloat());
                  }
                  
                  plug = dispNode.findPlug("aiDisplacementAutoBump");
                  if (!plug.isNull())
                  {
                     outputDispAutobump = true;
                     dispAutobump = dispAutobump || plug.asBool();
                  }
                  
                  if (HasParameter(anodeEntry, "disp_map", atNode, "constant ARRAY NODE"))
                  {
                     AtNode *dispImage = ExportNode(shaderConns[0]);
                     AiNodeSetArray(atNode, "disp_map", AiArrayConvert(1, 1, AI_TYPE_NODE, &dispImage));
                  }
               }
            }
         }
         
         if (outputDispHeight && HasParameter(anodeEntry, "disp_height", atNode, "constant FLOAT"))
         {
            AiNodeSetFlt(atNode, "disp_height", dispHeight);
         }
         if (outputDispZeroValue && HasParameter(anodeEntry, "disp_zero_value", atNode, "constant FLOAT"))
         {
            AiNodeSetFlt(atNode, "disp_zero_value", dispZeroValue);
         }
         if (outputDispPadding && HasParameter(anodeEntry, "disp_padding", atNode, "constant FLOAT"))
         {
            AiNodeSetFlt(atNode, "disp_padding", dispPadding);
         }
         if (outputDispAutobump && HasParameter(anodeEntry, "disp_autobump", atNode, "constant BOOL"))
         {
            AiNodeSetBool(atNode, "disp_autobump", dispAutobump);
         }
         
         // Old point based SSS parameter
         if (attrsSet.find("sss_sample_distribution") == attrsEnd)
         {
            plug = FindMayaPlug("sss_sample_distribution");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiSssSampleDistribution");
            }
            if (!plug.isNull() && HasParameter(anodeEntry, "sss_sample_distribution", atNode, "constant INT"))
            {
               AiNodeSetInt(atNode, "sss_sample_distribution", plug.asInt());
            }
         }
         
         // Old point based SSS parameter
         if (attrsSet.find("sss_sample_spacing") == attrsEnd)
         {
            plug = FindMayaPlug("sss_sample_spacing");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiSssSampleSpacing");
            }
            if (!plug.isNull() && HasParameter(anodeEntry, "sss_sample_spacing", atNode, "constant FLOAT"))
            {
               AiNodeSetFlt(atNode, "sss_sample_spacing", plug.asFloat());
            }
         }
         
         if (attrsSet.find("min_pixel_width") == attrsEnd)
         {
            plug = FindMayaPlug("aiMinPixelWidth");
            if (!plug.isNull() && HasParameter(anodeEntry, "min_pixel_width", atNode, "constant FLOAT"))
            {
               AiNodeSetFlt(atNode, "min_pixel_width", plug.asFloat());
            }
         }
         
         if (attrsSet.find("mode") == attrsEnd)
         {
            plug = FindMayaPlug("aiMode");
            if (!plug.isNull() && HasParameter(anodeEntry, "mode", atNode, "constant INT"))
            {
               AiNodeSetInt(atNode, "mode", plug.asShort());
            }
         }
         
         if (attrsSet.find("basis") == attrsEnd)
         {
            plug = FindMayaPlug("aiBasis");
            if (!plug.isNull() && HasParameter(anodeEntry, "basis", atNode, "constant INT"))
            {
               AiNodeSetInt(atNode, "basis", plug.asShort());
            }
         }
      }
      
      if (AiNodeIs(atNode, "ginstance"))
      {
         if (attrsSet.find("node") == attrsEnd)
         {
            AiNodeSetPtr(atNode, "node", m_masterNode);
         }
         
         if (attrsSet.find("inherit_xform") == attrsEnd)
         {
            AiNodeSetBool(atNode, "inherit_xform", false);
         }
      }
      else
      {
         // box or procedural
         if (attrsSet.find("step_size") == attrsEnd)
         {
            plug = FindMayaPlug("step_size");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiStepSize");
            }
            if (!plug.isNull() && HasParameter(anodeEntry, "step_size", atNode, "constant FLOAT"))
            {
               AiNodeSetFlt(atNode, "step_size", plug.asFloat());
            }
         }
      }
      
      if (attrsSet.find("sidedness") == attrsEnd)
      {
         // Use maya shape built-in attribute
         plug = FindMayaPlug("doubleSided");
         if (!plug.isNull() && HasParameter(anodeEntry, "sidedness", atNode, "constant BYTE"))
         {
            AiNodeSetByte(atNode, "sidedness", plug.asBool() ? AI_RAY_ALL : 0);
            
            // Only set invert_normals if doubleSided attribute could be found
            if (!plug.asBool() && attrsSet.find("invert_normals") == attrsEnd)
            {
               // Use maya shape built-in attribute
               plug = FindMayaPlug("opposite");
               if (!plug.isNull() && HasParameter(anodeEntry, "invert_normals", atNode, "constant BOOL"))
               {
                  AiNodeSetBool(atNode, "invert_normals", plug.asBool());
               }
            }
         }
      }
      
      if (attrsSet.find("receive_shadows") == attrsEnd)
      {
         // Use maya shape built-in attribute
         plug = FindMayaPlug("receiveShadows");
         if (!plug.isNull() && HasParameter(anodeEntry, "receive_shadows", atNode, "constant BOOL"))
         {
            AiNodeSetBool(atNode, "receive_shadows", plug.asBool());
         }
      }
      
      if (attrsSet.find("self_shadows") == attrsEnd)
      {
         plug = FindMayaPlug("self_shadows");
         if (plug.isNull())
         {
            plug = FindMayaPlug("aiSelfShadows");
         }
         if (!plug.isNull() && HasParameter(anodeEntry, "self_shadows", atNode, "constant BOOL"))
         {
            AiNodeSetBool(atNode, "self_shadows", plug.asBool());
         }
      }
      
      if (attrsSet.find("opaque") == attrsEnd)
      {
         plug = FindMayaPlug("opaque");
         if (plug.isNull())
         {
            plug = FindMayaPlug("aiOpaque");
         }
         if (!plug.isNull() && HasParameter(anodeEntry, "opaque", atNode, "constant BOOL"))
         {
            AiNodeSetBool(atNode, "opaque", plug.asBool());
         }
      }
      
      if (attrsSet.find("visibility") == attrsEnd)
      {
         if (HasParameter(anodeEntry, "visibility", atNode, "constant BYTE"))
         {
            int visibility = AI_RAY_ALL;
            
            // Use maya shape built-in attribute
            plug = FindMayaPlug("castsShadows");
            if (!plug.isNull() && !plug.asBool())
            {
               visibility &= ~AI_RAY_SHADOW;
            }
            
            // Use maya shape built-in attribute
            plug = FindMayaPlug("primaryVisibility");
            if (!plug.isNull() && !plug.asBool())
            {
               visibility &= ~AI_RAY_CAMERA;
            }
            
            // Use maya shape built-in attribute
            plug = FindMayaPlug("visibleInReflections");
            if (!plug.isNull() && !plug.asBool())
            {
               visibility &= ~AI_RAY_REFLECTED;
            }
            
            // Use maya shape built-in attribute
            plug = FindMayaPlug("visibleInRefractions");
            if (!plug.isNull() && !plug.asBool())
            {
               visibility &= ~AI_RAY_REFRACTED;
            }
            
            plug = FindMayaPlug("diffuse_visibility");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiVisibleInDiffuse");
            }
            if (!plug.isNull() && !plug.asBool())
            {
               visibility &= ~AI_RAY_DIFFUSE;
            }
            
            plug = FindMayaPlug("glossy_visibility");
            if (plug.isNull())
            {
               plug = FindMayaPlug("aiVisibleInGlossy");
            }
            if (!plug.isNull() && !plug.asBool())
            {
               visibility &= ~AI_RAY_GLOSSY;
            }
            
            AiNodeSetByte(atNode, "visibility", visibility & 0xFF);
         }
      }
      
      if (attrsSet.find("sss_setname") == attrsEnd)
      {
         plug = FindMayaPlug("aiSssSetname");
         if (!plug.isNull() && plug.asString().length() > 0)
         {
            if (HasParameter(anodeEntry, "sss_setname", atNode, "constant STRING"))
            {
               AiNodeSetStr(atNode, "sss_setname", plug.asString().asChar());
            }
         }
      }
      
      // Set surface shader
      if (HasParameter(anodeEntry, "shader", atNode, "constant NODE"))
      {
         if (attrsSet.find("shader") == attrsEnd)
         {
            if (shadingEngine.object() != MObject::kNullObj)
            {
               AtNode *shader = ExportNode(shadingEngine.findPlug("message"));
               if (shader != NULL)
               {
                  const AtNodeEntry *entry = AiNodeGetNodeEntry(shader);
                  
                  if (AiNodeEntryGetType(entry) != AI_NODE_SHADER)
                  {
                     MGlobal::displayWarning("[mtoaScriptedTranslators] Node generated from \"" + shadingEngine.name() +
                                             "\" of type " + shadingEngine.typeName() + " for shader is not a shader but a " +
                                             MString(AiNodeEntryGetTypeName(entry)));
                  }
                  else
                  {
                     AiNodeSetPtr(atNode, "shader", shader);
                     
                     if (AiNodeLookUpUserParameter(atNode, "mtoa_shading_groups") == 0)
                     {
                        AiNodeDeclare(atNode, "mtoa_shading_groups", "constant ARRAY NODE");
                        AiNodeSetArray(atNode, "mtoa_shading_groups", AiArrayConvert(1, 1, AI_TYPE_NODE, &shader));
                     }
                  }
               }
            }
         }
      }
   }
   
   ExportLightLinking(atNode);
   
   MPlug plug = FindMayaPlug("aiTraceSets");
   if (!plug.isNull())
   {
      ExportTraceSets(atNode, plug);
   }
   
   // Call cleanup command on last export step
   
   if (!IsMotionBlurEnabled() || !IsLocalMotionBlurEnabled() || int(step) >= (int(GetNumMotionSteps()) - 1))
   {
      if (HasParameter(anodeEntry, "disp_padding", atNode))
      {
         float padding = AiNodeGetFlt(atNode, "disp_padding");
         
         AtPoint cmin = AiNodeGetPnt(atNode, "min");
         AtPoint cmax = AiNodeGetPnt(atNode, "max");
         
         cmin.x -= padding;
         cmin.y -= padding;
         cmin.z -= padding;
         cmax.x += padding;
         cmax.y += padding;
         cmax.z += padding;
         
         AiNodeSetPnt(atNode, "min", cmin.x, cmin.y, cmin.z);
         AiNodeSetPnt(atNode, "max", cmax.x, cmax.y, cmax.z);
      }
      
      if (cleanupCmd != "")
      {
         command = cleanupCmd += "((\"" + m_dagPath.partialPathName() + "\", \"";
         command += AiNodeGetName(atNode);
         command += "\"), ";
         
         if (!m_masterNode)
         {
            command += "None)";
         }
         else
         {
            command += "(\"" + GetMasterInstance().partialPathName() + "\", \"";
            command += AiNodeGetName(m_masterNode);
            command += "\"))";
         }
         
         status = MGlobal::executePythonCommand(command);
         
         if (!status)
         {
            AiMsgError("[mtoa.scriptedTranslators] Failed to cleanup node \"%s\".", node.name().asChar());
         }
      }
   }
}