AtNode *convert( const IECore::ExternalProcedural *procedural ) { std::string nodeType = "procedural"; // Allow a parameter "ai:nodeType" == "volume" to create a volume shape rather // than a procedural shape. Volume shapes provide "dso", "min" and "max" parameters // just as procedural shapes do, so the mapping is a fairly natural one. const CompoundDataMap ¶meters = procedural->parameters()->readable(); CompoundDataMap::const_iterator nodeTypeIt = parameters.find( "ai:nodeType" ); if( nodeTypeIt != parameters.end() && nodeTypeIt->second->isInstanceOf( StringData::staticTypeId() ) ) { nodeType = static_cast<const StringData *>( nodeTypeIt->second.get() )->readable(); } AtNode *node = AiNode( nodeType.c_str() ); AiNodeSetStr( node, "dso", procedural->getFileName().c_str() ); ParameterAlgo::setParameters( node, parameters ); const Box3f bound = procedural->bound(); if( bound != Renderer::Procedural::noBound ) { AiNodeSetPnt( node, "min", bound.min.x, bound.min.y, bound.min.z ); AiNodeSetPnt( node, "max", bound.max.x, bound.max.y, bound.max.z ); } else { // No bound available - expand procedural immediately. AiNodeSetBool( node, "load_at_init", true ); } return node; }
virtual AtNode* ExportInstance(AtNode *instance, const MDagPath& masterInstance) { AtNode* masterNode = AiNodeLookUpByName(masterInstance.partialPathName().asChar()); int instanceNum = m_dagPath.instanceNumber(); if ( instanceNum > 0 ) { AiNodeSetStr(instance, "name", m_dagPath.partialPathName().asChar()); ExportMatrix(instance, 0); AiNodeSetPtr(instance, "node", masterNode); AiNodeSetBool(instance, "inherit_xform", false); int visibility = AiNodeGetInt(masterNode, "visibility"); AiNodeSetInt(instance, "visibility", visibility); AtNode *shader = arnoldShader(); if( shader ) { AiNodeSetPtr( instance, "shader", shader ); } // Export light linking per instance ExportLightLinking(instance); } return instance; }
void ApplyOverrides(std::string name, AtNode* node, std::vector<std::string> tags, ProcArgs & args) { bool foundInPath = false; for(std::vector<std::string>::iterator it=args.overrides.begin(); it!=args.overrides.end(); ++it) { Json::Value overrides; if(it->find("/") != std::string::npos) // Based on path { if(name.find(*it) != std::string::npos) { overrides = args.overrideRoot[*it]; foundInPath = true; } } else if(matchPattern(name,*it)) // based on wildcard expression { overrides = args.overrideRoot[*it]; foundInPath = true; } else if(foundInPath == false) { if (std::find(tags.begin(), tags.end(), *it) != tags.end()) { overrides = args.overrideRoot[*it]; } } if(overrides.size() > 0) { for( Json::ValueIterator itr = overrides.begin() ; itr != overrides.end() ; itr++ ) { std::string attribute = itr.key().asString(); const AtNodeEntry* nodeEntry = AiNodeGetNodeEntry(node); const AtParamEntry* paramEntry = AiNodeEntryLookUpParameter(nodeEntry, attribute.c_str()); if ( paramEntry != NULL && attribute!="invert_normals" || attribute == "matte") { Json::Value val = args.overrideRoot[*it][itr.key().asString()]; if( val.isString() ) AiNodeSetStr(node, attribute.c_str(), val.asCString()); else if( val.isBool() ) { if(attribute == "matte") { AiMsgDebug("[ABC] adding enable_matte to %s", AiNodeGetName(node)); AddUserGeomParams(node,"enable_matte",AI_TYPE_BOOLEAN); AiNodeSetBool(node,"enable_matte", val.asBool()); } else { AiNodeSetBool(node, attribute.c_str(), val.asBool()); } } else if( val.isInt() ) { //make the difference between Byte & int! int typeEntry = AiParamGetType(paramEntry); if(typeEntry == AI_TYPE_BYTE) { if(attribute=="visibility") { AtByte attrViz = val.asInt(); // special case, we must determine it against the general viz. AtByte procViz = AiNodeGetByte( args.proceduralNode, "visibility" ); AtByte compViz = AI_RAY_ALL; { compViz &= ~AI_RAY_GLOSSY; if(procViz > compViz) procViz &= ~AI_RAY_GLOSSY; else attrViz &= ~AI_RAY_GLOSSY; compViz &= ~AI_RAY_DIFFUSE; if(procViz > compViz) procViz &= ~AI_RAY_DIFFUSE; else attrViz &= ~AI_RAY_DIFFUSE; compViz &= ~AI_RAY_REFRACTED; if(procViz > compViz) procViz &= ~AI_RAY_REFRACTED; else attrViz &= ~AI_RAY_REFRACTED; compViz &= ~AI_RAY_REFLECTED; if(procViz > compViz) procViz &= ~AI_RAY_REFLECTED; else attrViz &= ~AI_RAY_REFLECTED; compViz &= ~AI_RAY_SHADOW; if(procViz > compViz) procViz &= ~AI_RAY_SHADOW; else attrViz &= ~AI_RAY_SHADOW; compViz &= ~AI_RAY_CAMERA; if(procViz > compViz) procViz &= ~AI_RAY_CAMERA; else attrViz &= ~AI_RAY_CAMERA; } AiNodeSetByte(node, attribute.c_str(), attrViz); } else AiNodeSetByte(node, attribute.c_str(), val.asInt()); } else AiNodeSetInt(node, attribute.c_str(), val.asInt()); } else if( val.isUInt() ) AiNodeSetUInt(node, attribute.c_str(), val.asUInt()); else if( val.isDouble() ) AiNodeSetFlt(node, attribute.c_str(), val.asDouble()); } } } } }
void ApplyUserAttributes(std::string name, AtNode* node,std::vector<std::string> tags,ProcArgs & args) { bool foundInPath = false; for(std::vector<std::string>::iterator it=args.userAttributes.begin(); it!=args.userAttributes.end(); ++it) { Json::Value userAttributes; if(it->find("/") != std::string::npos) // Based on path { if(name.find(*it) != std::string::npos) { userAttributes = args.userAttributesRoot[*it]; foundInPath = true; } } else if(matchPattern(name,*it)) // based on wildcard expression { userAttributes = args.userAttributesRoot[*it]; foundInPath = true; } else if(foundInPath == false) { if (std::find(tags.begin(), tags.end(), *it) != tags.end()) { userAttributes = args.userAttributesRoot[*it]; } } if(userAttributes.size() > 0) { for( Json::ValueIterator itr = userAttributes.begin() ; itr != userAttributes.end() ; itr++ ) { std::string attribute = itr.key().asString(); if( AiNodeLookUpUserParameter(node,attribute.c_str())) continue; const AtNodeEntry* nodeEntry = AiNodeGetNodeEntry(node); Json::Value val = args.userAttributesRoot[*it][attribute]; if( val.isString() ) { AddUserGeomParams(node,attribute.c_str(),AI_TYPE_STRING); AiNodeSetStr(node, attribute.c_str(), val.asCString()); } else if( val.isBool() ) { AddUserGeomParams(node,attribute.c_str(),AI_TYPE_BOOLEAN); AiNodeSetBool(node, attribute.c_str(), val.asBool()); } else if( val.isInt() ) { AddUserGeomParams(node,attribute.c_str(),AI_TYPE_INT); AiNodeSetInt(node, attribute.c_str(), val.asInt()); } else if( val.isUInt() ) { AddUserGeomParams(node,attribute.c_str(),AI_TYPE_UINT); AiNodeSetUInt(node, attribute.c_str(), val.asUInt()); } else if(val.isDouble()) { AddUserGeomParams(node,attribute.c_str(),AI_TYPE_FLOAT); AiNodeSetFlt(node, attribute.c_str(), val.asDouble()); } else if(val.isArray()) { // in the future we will convert to an arnold array type for now lets just // write out a json string AddUserGeomParams(node,attribute.c_str(),AI_TYPE_STRING); Json::FastWriter writer; AiNodeSetStr(node, attribute.c_str(), writer.write(val).c_str()); // AddUserGeomParams(node,attribute.c_str(),AI_TYPE_ARRAY ); // // get the type of the first entry, this will be our key as to // // what type of data is in this array // Json::Value firstValue = val[0]; // if (firstValue.isString()) // { // AtArray* arrayValues = AiArrayAllocate( val.size() , 1, AI_TYPE_STRING); // for( uint idx = 0 ; idx != val.size() ; idx++ ) // { // AiMsgInfo("[ABC] adding string %s to user array attribute '%s'",val[idx].asCString(),attribute.c_str()); // AiArraySetStr(arrayValues,idx,val[idx].asCString()); // } // AiNodeSetArray(node, attribute.c_str(), arrayValues); // } } // TODO color, matrix, vector } } } }
AtNode *createInstanceNode(nodeData &nodata, userData * ud, int i) { Alembic::AbcGeom::IPoints typedObject(ud->gIObjects[i].abc, Alembic::Abc::kWrapExisting); instanceCloudInfo * info = ud->gIObjects[i].instanceCloud; // check that we have the masternode size_t id = (size_t)ud->gIObjects[i].ID; size_t instanceID = (size_t)ud->gIObjects[i].instanceID; if(instanceID >= info->groupInfos.size()) { AiMsgError("[ExocortexAlembicArnold] Instance '%s.%d' has an invalid instanceID . Aborting.",ud->gIObjects[i].abc.getFullName().c_str(),(int)id); return NULL; } size_t groupID = (size_t)ud->gIObjects[i].instanceGroupID; if(groupID >= info->groupInfos[instanceID].identifiers.size()) { AiMsgError("[ExocortexAlembicArnold] Instance '%s.%d' has an invalid instanceGroupID. Aborting.",ud->gIObjects[i].abc.getFullName().c_str(),(int)id); return NULL; } instanceGroupInfo * group = &info->groupInfos[instanceID]; // get the right centroidTime float centroidTime = ud->gCentroidTime; if(info->time.size() > 0) { centroidTime = info->time[0]->get()[id < info->time[0]->size() ? id : info->time[0]->size() - 1]; if(info->time.size() > 1) centroidTime = (1.0f - info->timeAlpha) * centroidTime + info->timeAlpha * info->time[1]->get()[id < info->time[1]->size() ? id : info->time[1]->size() - 1]; centroidTime = roundCentroid(centroidTime); } std::map<float,AtNode*>::iterator it = group->nodes[groupID].find(centroidTime); if(it == group->nodes[groupID].end()) { AiMsgError("[ExocortexAlembicArnold] Cannot find masterNode '%s' for centroidTime '%f'. Aborting.",group->identifiers[groupID].c_str(),centroidTime); return NULL; } AtNode *usedMasterNode = it->second; AtNode *shapeNode = AiNode("ginstance"); // setup name, id and the master node AiNodeSetStr(shapeNode, "name", getNameFromIdentifier(ud->gIObjects[i].abc.getFullName(),ud->gIObjects[i].ID,(long)groupID).c_str()); AiNodeSetInt(shapeNode, "id", ud->gIObjects[i].instanceID); AiNodeSetPtr(shapeNode, "node", usedMasterNode); // declare color on the ginstance if(info->color.size() > 0 && AiNodeDeclare(shapeNode, "Color", "constant RGBA")) { Alembic::Abc::C4f color = info->color[0]->get()[id < info->color[0]->size() ? id : info->color[0]->size() - 1]; AiNodeSetRGBA(shapeNode, "Color", color.r, color.g, color.b, color.a); } // now let's take care of the transform AtArray * matrices = AiArrayAllocate(1,(AtInt)ud->gMbKeys.size(),AI_TYPE_MATRIX); for(size_t j=0;j<ud->gMbKeys.size(); ++j) { SampleInfo sampleInfo = getSampleInfo( ud->gMbKeys[j], typedObject.getSchema().getTimeSampling(), typedObject.getSchema().getNumSamples() ); Alembic::Abc::M44f matrixAbc; matrixAbc.makeIdentity(); const size_t floorIndex = j << 1; const size_t ceilIndex = floorIndex + 1; // apply translation if(info->pos[floorIndex]->size() == info->pos[ceilIndex]->size()) { matrixAbc.setTranslation(float(1.0 - sampleInfo.alpha) * info->pos[floorIndex]->get()[id < info->pos[floorIndex]->size() ? id : info->pos[floorIndex]->size() - 1] + float(sampleInfo.alpha) * info->pos[ceilIndex]->get()[id < info->pos[ceilIndex]->size() ? id : info->pos[ceilIndex]->size() - 1]); } else { const float timeAlpha = getTimeOffsetFromObject( typedObject, sampleInfo ); matrixAbc.setTranslation(info->pos[floorIndex]->get()[id < info->pos[floorIndex]->size() ? id : info->pos[floorIndex]->size() - 1] + info->vel[floorIndex]->get()[id < info->vel[floorIndex]->size() ? id : info->vel[floorIndex]->size() - 1] * timeAlpha); } // now take care of rotation if(info->rot.size() == ud->gMbKeys.size()) { Alembic::Abc::Quatf rotAbc = info->rot[j]->get()[id < info->rot[j]->size() ? id : info->rot[j]->size() - 1]; if(info->ang.size() == ud->gMbKeys.size() && sampleInfo.alpha > 0.0) { Alembic::Abc::Quatf angAbc = info->ang[j]->get()[id < info->ang[j]->size() ? id : info->ang[j]->size() -1] * (float)sampleInfo.alpha; if(angAbc.axis().length2() != 0.0f && angAbc.r != 0.0f) { rotAbc = angAbc * rotAbc; rotAbc.normalize(); } } Alembic::Abc::M44f matrixAbcRot; matrixAbcRot.setAxisAngle(rotAbc.axis(),rotAbc.angle()); matrixAbc = matrixAbcRot * matrixAbc; } // and finally scaling if(info->scale.size() == ud->gMbKeys.size() * 2) { const Alembic::Abc::V3f scalingAbc = info->scale[floorIndex]->get()[id < info->scale[floorIndex]->size() ? id : info->scale[floorIndex]->size() - 1] * info->width[floorIndex]->get()[id < info->width[floorIndex]->size() ? id : info->width[floorIndex]->size() - 1] * float(1.0 - sampleInfo.alpha) + info->scale[ceilIndex]->get()[id < info->scale[ceilIndex]->size() ? id : info->scale[ceilIndex]->size() - 1] * info->width[ceilIndex]->get()[id < info->width[ceilIndex]->size() ? id : info->width[ceilIndex]->size() - 1] * float(sampleInfo.alpha); matrixAbc.scale(scalingAbc); } else { const float width = info->width[floorIndex]->get()[id < info->width[floorIndex]->size() ? id : info->width[floorIndex]->size() - 1] * float(1.0 - sampleInfo.alpha) + info->width[ceilIndex]->get()[id < info->width[ceilIndex]->size() ? id : info->width[ceilIndex]->size() - 1] * float(sampleInfo.alpha); matrixAbc.scale(Alembic::Abc::V3f(width,width,width)); } // if we have offset matrices if(group->parents.size() > groupID && group->matrices.size() > groupID) { if(group->objects[groupID].valid() && group->parents[groupID].valid()) { // we have a matrix map and a parent. // now we need to check if we already exported the matrices std::map<float,std::vector<Alembic::Abc::M44f> >::iterator it; std::vector<Alembic::Abc::M44f> offsets; it = group->matrices[groupID].find(centroidTime); if(it == group->matrices[groupID].end()) { std::vector<float> samples(ud->gMbKeys.size()); offsets.resize(ud->gMbKeys.size()); for(AtInt sampleIndex=0;sampleIndex<(AtInt)ud->gMbKeys.size(); ++sampleIndex) { offsets[sampleIndex].makeIdentity(); // centralize the time once more samples[sampleIndex] = centroidTime + ud->gMbKeys[sampleIndex] - ud->gCentroidTime; } // if the transform differs, we need to compute the offset matrices // get the parent, which should be a transform Alembic::Abc::IObject parent = group->parents[groupID]; Alembic::Abc::IObject xform = group->objects[groupID].getParent(); while(Alembic::AbcGeom::IXform::matches(xform.getMetaData()) && xform.getFullName() != parent.getFullName()) { // cast to a xform Alembic::AbcGeom::IXform parentXform(xform,Alembic::Abc::kWrapExisting); if(parentXform.getSchema().getNumSamples() == 0) break; // loop over all samples for(size_t sampleIndex=0;sampleIndex<ud->gMbKeys.size(); ++sampleIndex) { SampleInfo sampleInfo = getSampleInfo( samples[sampleIndex], parentXform.getSchema().getTimeSampling(), parentXform.getSchema().getNumSamples() ); // get the data and blend it if necessary Alembic::AbcGeom::XformSample sample; parentXform.getSchema().get(sample,sampleInfo.floorIndex); Alembic::Abc::M44f abcMatrix; Alembic::Abc::M44d abcMatrixd = sample.getMatrix(); for(int x=0;x<4;x++) for(int y=0;y<4;y++) abcMatrix[x][y] = (float)abcMatrixd[x][y]; if(sampleInfo.alpha >= sampleTolerance) { parentXform.getSchema().get(sample,sampleInfo.ceilIndex); Alembic::Abc::M44d ceilAbcMatrixd = sample.getMatrix(); Alembic::Abc::M44f ceilAbcMatrix; for(int x=0;x<4;x++) for(int y=0;y<4;y++) ceilAbcMatrix[x][y] = (float)ceilAbcMatrixd[x][y]; abcMatrix = float(1.0 - sampleInfo.alpha) * abcMatrix + float(sampleInfo.alpha) * ceilAbcMatrix; } offsets[sampleIndex] = abcMatrix * offsets[sampleIndex]; } // go upwards xform = xform.getParent(); } group->matrices[groupID].insert(std::pair<float,std::vector<Alembic::Abc::M44f> >(centroidTime,offsets)); } else offsets = it->second; // this means we have the right amount of matrices to blend against if(offsets.size() > j) matrixAbc = offsets[j] * matrixAbc; } } // store it to the array AiArraySetMtx(matrices,(AtULong)j,matrixAbc.x); } AiNodeSetArray(shapeNode,"matrix",matrices); AiNodeSetBool(shapeNode, "inherit_xform", FALSE); return shapeNode; }
virtual void ExportProcedural( AtNode *node ) { // do basic node export ExportMatrix( node, 0 ); AtNode *shader = arnoldShader(); if( shader ) { AiNodeSetPtr( node, "shader", shader ); } AiNodeSetInt( node, "visibility", ComputeVisibility() ); MPlug plug = FindMayaObjectPlug( "receiveShadows" ); if( !plug.isNull() ) { AiNodeSetBool( node, "receive_shadows", plug.asBool() ); } plug = FindMayaObjectPlug( "aiSelfShadows" ); if( !plug.isNull() ) { AiNodeSetBool( node, "self_shadows", plug.asBool() ); } plug = FindMayaObjectPlug( "aiOpaque" ); if( !plug.isNull() ) { AiNodeSetBool( node, "opaque", plug.asBool() ); } // export any shading groups or displacement shaders which look like they // may be connected to procedural parameters. this ensures that maya shaders // the procedural will expect to find at rendertime will be exported to the // ass file (they otherwise might not be if they're not assigned to any objects). exportShadingInputs(); // now set the procedural-specific parameters MFnDagNode fnDagNode( m_dagPath ); MBoundingBox bound = fnDagNode.boundingBox(); AiNodeSetPnt( node, "min", bound.min().x, bound.min().y, bound.min().z ); AiNodeSetPnt( node, "max", bound.max().x, bound.max().y, bound.max().z ); const char *dsoPath = getenv( "IECOREARNOLD_PROCEDURAL_PATH" ); AiNodeSetStr( node, "dso", dsoPath ? dsoPath : "ieProcedural.so" ); AiNodeDeclare( node, "className", "constant STRING" ); AiNodeDeclare( node, "classVersion", "constant INT" ); AiNodeDeclare( node, "parameterValues", "constant ARRAY STRING" ); // cast should be ok as we're registered to only work on procedural holders IECoreMaya::ProceduralHolder *pHolder = static_cast<IECoreMaya::ProceduralHolder *>( fnDagNode.userNode() ); std::string className; int classVersion; IECore::ParameterisedProceduralPtr procedural = pHolder->getProcedural( &className, &classVersion ); AiNodeSetStr( node, "className", className.c_str() ); AiNodeSetInt( node, "classVersion", classVersion ); IECorePython::ScopedGILLock gilLock; try { boost::python::object parser = IECoreMaya::PythonCmd::globalContext()["IECore"].attr( "ParameterParser" )(); boost::python::object serialised = parser.attr( "serialise" )( procedural->parameters() ); size_t numStrings = IECorePython::len( serialised ); AtArray *stringArray = AiArrayAllocate( numStrings, 1, AI_TYPE_STRING ); for( size_t i=0; i<numStrings; i++ ) { std::string s = boost::python::extract<std::string>( serialised[i] ); // hack to workaround ass parsing errors /// \todo Remove when we get the Arnold version that fixes this for( size_t c = 0; c<s.size(); c++ ) { if( s[c] == '#' ) { s[c] = '@'; } } AiArraySetStr( stringArray, i, s.c_str() ); } AiNodeSetArray( node, "parameterValues", stringArray ); } catch( boost::python::error_already_set ) { PyErr_Print(); } }
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()); } } } }
virtual void ExportUserAttrs( AtNode *node ) { // Get the optional attributes and export them as user vars MPlug plug = FindMayaObjectPlug( "shaderAssignation" ); if( !plug.isNull() ) { AiNodeDeclare( node, "shaderAssignation", "constant STRING" ); AiNodeSetStr( node, "shaderAssignation", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "displacementAssignation" ); if( !plug.isNull() ) { AiNodeDeclare( node, "displacementAssignation", "constant STRING" ); AiNodeSetStr( node, "displacementAssignation", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "shaderAssignmentfile" ); if( !plug.isNull() ) { AiNodeDeclare( node, "shaderAssignmentfile", "constant STRING" ); AiNodeSetStr( node, "shaderAssignmentfile", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "overrides" ); if( !plug.isNull() ) { AiNodeDeclare( node, "overrides", "constant STRING" ); AiNodeSetStr( node, "overrides", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "overridefile" ); if( !plug.isNull() ) { AiNodeDeclare( node, "overridefile", "constant STRING" ); AiNodeSetStr( node, "overridefile", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "userAttributes" ); if( !plug.isNull() ) { AiNodeDeclare( node, "userAttributes", "constant STRING" ); AiNodeSetStr( node, "userAttributes", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "userAttributesfile" ); if( !plug.isNull() ) { AiNodeDeclare( node, "userAttributesfile", "constant STRING" ); AiNodeSetStr( node, "userAttributesfile", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "skipJson" ); if( !plug.isNull() ) { AiNodeDeclare( node, "skipJson", "constant BOOL" ); AiNodeSetBool( node, "skipJson", plug.asBool() ); } plug = FindMayaObjectPlug( "skipShaders" ); if( !plug.isNull() ) { AiNodeDeclare( node, "skipShaders", "constant BOOL" ); AiNodeSetBool( node, "skipShaders", plug.asBool() ); } plug = FindMayaObjectPlug( "skipOverrides" ); if( !plug.isNull() ) { AiNodeDeclare( node, "skipOverrides", "constant BOOL" ); AiNodeSetBool( node, "skipOverrides", plug.asBool() ); } plug = FindMayaObjectPlug( "skipUserAttributes" ); if( !plug.isNull() ) { AiNodeDeclare( node, "skipUserAttributes", "constant BOOL" ); AiNodeSetBool( node, "skipUserAttributes", plug.asBool() ); } plug = FindMayaObjectPlug( "skipDisplacements" ); if( !plug.isNull() ) { AiNodeDeclare( node, "skipDisplacements", "constant BOOL" ); AiNodeSetBool( node, "skipDisplacements", plug.asBool() ); } plug = FindMayaObjectPlug( "objectPattern" ); if( !plug.isNull() ) { AiNodeDeclare( node, "objectPattern", "constant STRING" ); AiNodeSetStr( node, "objectPattern", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "assShaders" ); if( !plug.isNull() ) { AiNodeDeclare( node, "assShaders", "constant STRING" ); AiNodeSetStr( node, "assShaders", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "radiusPoint" ); if( !plug.isNull() ) { AiNodeDeclare( node, "radiusPoint", "constant FLOAT" ); AiNodeSetFlt( node, "radiusPoint", plug.asFloat() ); } plug = FindMayaObjectPlug( "radiusCurve" ); if( !plug.isNull() ) { AiNodeDeclare( node, "radiusCurve", "constant FLOAT" ); AiNodeSetFlt( node, "radiusCurve", plug.asFloat() ); } plug = FindMayaObjectPlug( "modeCurve" ); if( !plug.isNull() ) { AiNodeDeclare( node, "modeCurve", "constant STRING" ); int modeCurveInt = plug.asInt(); if (modeCurveInt == 1) AiNodeSetStr(node, "modeCurve", "thick"); else if (modeCurveInt == 2) AiNodeSetStr(node, "modeCurve", "oriented"); else AiNodeSetStr(node, "modeCurve", "ribbon"); } plug = FindMayaObjectPlug( "scaleVelocity" ); if( !plug.isNull() ) { AiNodeDeclare( node, "scaleVelocity", "constant FLOAT" ); AiNodeSetFlt( node, "scaleVelocity", plug.asFloat() ); } }
virtual void ExportProcedural( AtNode *node ) { // do basic node export ExportMatrix( node, 0 ); // AiNodeSetPtr( node, "shader", arnoldShader(node) ); AiNodeSetInt( node, "visibility", ComputeVisibility() ); MPlug plug = FindMayaObjectPlug( "receiveShadows" ); if( !plug.isNull() ) { AiNodeSetBool( node, "receive_shadows", plug.asBool() ); } plug = FindMayaObjectPlug( "aiSelfShadows" ); if( !plug.isNull() ) { AiNodeSetBool( node, "self_shadows", plug.asBool() ); } plug = FindMayaObjectPlug( "aiOpaque" ); if( !plug.isNull() ) { AiNodeSetBool( node, "opaque", plug.asBool() ); } // now set the procedural-specific parameters AiNodeSetBool( node, "load_at_init", true ); // just for now so that it can load the shaders at the right time MFnDagNode fnDagNode( m_dagPath ); MBoundingBox bound = fnDagNode.boundingBox(); AiNodeSetPnt( node, "min", bound.min().x-m_dispPadding, bound.min().y-m_dispPadding, bound.min().z-m_dispPadding ); AiNodeSetPnt( node, "max", bound.max().x+m_dispPadding, bound.max().y, bound.max().z+m_dispPadding ); const char *dsoPath = getenv( "ALEMBIC_ARNOLD_PROCEDURAL_PATH" ); AiNodeSetStr( node, "dso", dsoPath ? dsoPath : "bb_AlembicArnoldProcedural.so" ); // Set the parameters for the procedural //abcFile path MString abcFile = fnDagNode.findPlug("cacheFileName").asString().expandEnvironmentVariablesAndTilde(); //object path MString objectPath = fnDagNode.findPlug("cacheGeomPath").asString(); //object pattern MString objectPattern = "*"; plug = FindMayaObjectPlug( "objectPattern" ); if (!plug.isNull() ) { if (plug.asString() != "") { objectPattern = plug.asString(); } } //object pattern MString excludePattern = ""; plug = FindMayaObjectPlug( "excludePattern" ); if (!plug.isNull() ) { if (plug.asString() != "") { excludePattern = plug.asString(); } } float shutterOpen = 0.0; plug = FindMayaObjectPlug( "shutterOpen" ); if (!plug.isNull() ) { shutterOpen = plug.asFloat(); } float shutterClose = 0.0; plug = FindMayaObjectPlug( "shutterClose" ); if (!plug.isNull() ) { shutterClose = plug.asFloat(); } float timeOffset = 0.0; plug = FindMayaObjectPlug( "timeOffset" ); if (!plug.isNull() ) { timeOffset = plug.asFloat(); } int subDIterations = 0; plug = FindMayaObjectPlug( "ai_subDIterations" ); if (!plug.isNull() ) { subDIterations = plug.asInt(); } MString nameprefix = ""; plug = FindMayaObjectPlug( "namePrefix" ); if (!plug.isNull() ) { nameprefix = plug.asString(); } // bool exportFaceIds = fnDagNode.findPlug("exportFaceIds").asBool(); bool makeInstance = true; // always on for now plug = FindMayaObjectPlug( "makeInstance" ); if (!plug.isNull() ) { makeInstance = plug.asBool(); } bool flipv = false; plug = FindMayaObjectPlug( "flipv" ); if (!plug.isNull() ) { flipv = plug.asBool(); } bool invertNormals = false; plug = FindMayaObjectPlug( "invertNormals" ); if (!plug.isNull() ) { invertNormals = plug.asBool(); } short i_subDUVSmoothing = 1; plug = FindMayaObjectPlug( "ai_subDUVSmoothing" ); if (!plug.isNull() ) { i_subDUVSmoothing = plug.asShort(); } MString subDUVSmoothing; switch (i_subDUVSmoothing) { case 0: subDUVSmoothing = "pin_corners"; break; case 1: subDUVSmoothing = "pin_borders"; break; case 2: subDUVSmoothing = "linear"; break; case 3: subDUVSmoothing = "smooth"; break; default : subDUVSmoothing = "pin_corners"; break; } MTime curTime = MAnimControl::currentTime(); // fnDagNode.findPlug("time").getValue( frame ); // MTime frameOffset; // fnDagNode.findPlug("timeOffset").getValue( frameOffset ); float time = curTime.as(MTime::kFilm)+timeOffset; MString argsString; if (objectPath != "|"){ argsString += "-objectpath "; // convert "|" to "/" argsString += MString(replace_all(objectPath,"|","/").c_str()); } if (objectPattern != "*"){ argsString += "-pattern "; argsString += objectPattern; } if (excludePattern != ""){ argsString += "-excludepattern "; argsString += excludePattern; } if (shutterOpen != 0.0){ argsString += " -shutteropen "; argsString += shutterOpen; } if (shutterClose != 0.0){ argsString += " -shutterclose "; argsString += shutterClose; } if (subDIterations != 0){ argsString += " -subditerations "; argsString += subDIterations; argsString += " -subduvsmoothing "; argsString += subDUVSmoothing; } if (makeInstance){ argsString += " -makeinstance "; } if (nameprefix != ""){ argsString += " -nameprefix "; argsString += nameprefix; } if (flipv){ argsString += " -flipv "; } if (invertNormals){ argsString += " -invertNormals "; } argsString += " -filename "; argsString += abcFile; argsString += " -frame "; argsString += time; if (m_displaced){ argsString += " -disp_map "; argsString += AiNodeGetName(m_dispNode); } AiNodeSetStr(node, "data", argsString.asChar()); ExportUserAttrs(node); // Export light linking per instance ExportLightLinking(node); }
static AtNode *MyGetNode(void *user_ptr, int i){ cout << "BEGIN GET NODE" << endl; const McdMiddleData* params = static_cast<McdMiddleData*>(user_ptr); const char* g_assetsPath = params->m_assetsPath; int g_agentID = params->m_agentID; int g_ppID = params->m_ppID; int g_geoID = params->m_geoID; int g_poly0_subd1 = params->m_poly0_subd1; int g_motionBlur = params->m_motionBlur; float g_motionShutter = params->m_motionShutter; const char* g_poseData = params->m_poseData; string agentFolder; string agentPath2,geoPath2,weightPath2; string currentLine; //long counter1; //long counter2; #ifdef WIN32 EnterCriticalSection(&g_cs1); #else pthread_mutex_lock( &cs_mutex ); #endif if (!have_Data) initAssets(params); #ifdef WIN32 LeaveCriticalSection(&g_cs1); #else pthread_mutex_unlock( &cs_mutex ); #endif #ifdef MiarmyDebug ofstream logFile("e:/logFile.txt"); #endif // agent file: // ///////////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////// bool motionBlurDef = false; float motionShutter = 0.0f; if (g_motionBlur == 1) { motionBlurDef = true; motionShutter = g_motionShutter; } vector<float> poseDataRaw; vector<float> poseDataRawNext; McdUtils utils; utils.getPoseRawData(poseDataRaw,poseDataRawNext, motionBlurDef, g_poseData); #ifdef MiarmyDebug logFile<<"pose data raw"<<endl; for (uint i = 0; i < poseDataRaw.size(); i++){ logFile<<poseDataRaw[i]<<" "; } #endif char tempBuf[10]; string ppIdStr, agentTypeIdStr, geoTypeIdStr; string assetsFolder(g_assetsPath); sprintf(tempBuf, "%d", g_ppID); ppIdStr = tempBuf; sprintf(tempBuf, "%d", g_agentID); agentTypeIdStr = tempBuf; sprintf(tempBuf, "%d", g_geoID); geoTypeIdStr = tempBuf; string geomStr = "geom"; geomStr = geomStr + ppIdStr; agentFolder = agentFolderPre + agentTypeIdStr; // d:/pp / McdAgentType0 / McdAgentMain.txt agentPath2= assetsFolder + slash + agentFolder + slash + agentFile2; // d:/pp / McdAgentType0 / McdGeoFiles / McdGeo 0 geoPath2= assetsFolder + slash + agentFolder + slash + geoFolder + slash + geoFilePre + geoTypeIdStr; // d:/pp / McdAgentType0 / McdGeoFiles / McdWeight 0 weightPath2= assetsFolder + slash + agentFolder + slash + geoFolder + slash + weightFilePre + geoTypeIdStr; // we already have agentPath2, geoPath2, and weightPath2, let's extract data: // get bone number and org pose vector<McdMatrix> orgPoseMatrixList; vector<McdMatrix> currentPoseMatrixList; vector<McdMatrix> nextPoseMatrixList; int nbBone = (int)(agentFiles_Data[g_agentID][0] + .1f); utils.getPoseMatrices( orgPoseMatrixList, currentPoseMatrixList, nextPoseMatrixList, agentFiles_Data, poseDataRaw, poseDataRawNext, nbBone, g_agentID, motionBlurDef); // now get the weights McdPointWeight weightList; int nbPoints = utils.getWeightsFromFile( weightList, weightPath2, weightFiles_Data, g_agentID, g_geoID ); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // session 3: get the data from geo file ////////////////////////////////////////////////////////////////////// //bool startCollect = false; McdGeo geo; vector<float> currentPoints, nextPoints; // modified from points; vector<float> currentNormals, nextNormals; // modified from normals; utils.getGeoFromFile( geo, geoFiles_Data, currentNormals, nextNormals, g_geoID, g_agentID, motionBlurDef); // statistic final information: int nbNormalFromRib = geo.nidxs.size(); if (geo.points.size() / 3 != nbPoints) return 0; #ifdef MiarmyDebug logFile << "-----------> points number from pp exportor: >>>>" <<nbPoints<<endl; logFile << "-----------> normals number from rib: >>>>" <<nbNormalFromRib<<endl; #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // session 4: modify the data in vector /////////////////////////////////////////////////////////////////////// // modify points by skinning info #ifdef MiarmyDebug logFile << "*************start to deal with points********************************************"<<endl; #endif McdPoint currentPoint; McdPoint nextPoint; int nbWeights; int boneID; float weight; for (int i = 0; i < nbPoints; i++) { currentPoint.x = geo.points[i*3]; currentPoint.y = geo.points[i*3 + 1]; currentPoint.z = geo.points[i*3 + 2]; if (motionBlurDef) { nextPoint = currentPoint; } nbWeights = weightList.nbWeights[i]; #ifdef MiarmyDebug logFile<<"-------------------------------"<<endl; logFile << "point pre info: "<<currentPoint.x<<" "<<currentPoint.y<<" "<<currentPoint.z<<" "<<endl; #endif McdMatrix deformMat; deformMat = deformMat * 0.0f; // zero out McdMatrix deformMatNext; deformMatNext = deformMatNext * 0.0f; // zero out for (int j = 0; j < nbWeights; j++) { boneID = weightList.pointIdList[i][j]; weight = weightList.pointWeights[i][j]; #ifdef MiarmyDebug logFile <<"pointid: "<<i<<" boneId: "<<boneID<<" weight: "<<weight<<endl; #endif deformMat = deformMat + (orgPoseMatrixList[boneID] * currentPoseMatrixList[boneID]) * weight; if (motionBlurDef) { deformMatNext = deformMatNext + (orgPoseMatrixList[boneID] * nextPoseMatrixList[boneID]) * weight; } } currentPoint = currentPoint * deformMat; if (motionBlurDef) { nextPoint = nextPoint * deformMatNext; } // put result to points: currentPoints.push_back(currentPoint.x); currentPoints.push_back(currentPoint.y); currentPoints.push_back(currentPoint.z); if (motionBlurDef) { nextPoints.push_back(nextPoint.x); nextPoints.push_back(nextPoint.y); nextPoints.push_back(nextPoint.z); } #ifdef MiarmyDebug logFile << "result point info: "<<currentPoints[i*3]<<" "<<currentPoints[i*3+1]<<" "<<currentPoints[i*3+2]<<" "<<endl; if (motionBlurDef) logFile << "next point info: "<<nextPoints[i*3]<<" "<<nextPoints[i*3+1]<<" "<<nextPoints[i*3+2]<<" "<<endl; #endif } // modify normal by skinning info McdVector currentNormal, nextNormal; int normalPointID, normalID; for (int i = 0; i < nbNormalFromRib; i++){ normalID = geo.nidxs[i]; currentNormal.x = geo.normals[normalID*3]; currentNormal.y = geo.normals[normalID*3+1]; currentNormal.z = geo.normals[normalID*3+2]; if (motionBlurDef){ nextNormal.x = geo.normals[normalID*3]; nextNormal.y = geo.normals[normalID*3+1]; nextNormal.z = geo.normals[normalID*3+2]; } normalPointID = geo.vidxs[i]; nbWeights = weightList.nbWeights[normalPointID]; #ifdef MiarmyDebug logFile << "point normal info: "<<currentNormal.x<<" "<<currentNormal.y<<" "<<currentNormal.z<<" "<<endl; if (motionBlurDef){ logFile << "next point normal info: "<<nextNormal.x<<" "<<nextNormal.y<<" "<<nextNormal.z<<" "<<endl; } #endif McdMatrix deformMat; deformMat = deformMat * 0.0f; // zero out McdMatrix deformMatNext; deformMatNext = deformMatNext * 0.0f; // zero out for (int j = 0; j < nbWeights; j++){ boneID = weightList.pointIdList[normalPointID][j]; weight = weightList.pointWeights[normalPointID][j]; deformMat = deformMat + (orgPoseMatrixList[boneID] * currentPoseMatrixList[boneID]) * weight; if (motionBlurDef){ deformMat = deformMat + (orgPoseMatrixList[boneID] * nextPoseMatrixList[boneID]) * weight; } } currentNormal = currentNormal * deformMat; currentNormal.normalize(); if (motionBlurDef){ nextNormal = nextNormal * deformMatNext; nextNormal.normalize(); } // put result to normals: currentNormals[normalID*3] = currentNormal.x; currentNormals[normalID*3+1] = currentNormal.y; currentNormals[normalID*3+2] = currentNormal.z; if (motionBlurDef){ nextNormals[normalID*3] = nextNormal.x; nextNormals[normalID*3+1] = nextNormal.y; nextNormals[normalID*3+2] = nextNormal.z; } #ifdef MiarmyDebug logFile << "result normal info: "<<currentNormals[normalID*3]<<" "<<currentNormals[normalID*3+1]<<" "<<currentNormals[normalID*3+2]<<" "<<endl; if (motionBlurDef) logFile << "result next normal info: "<<nextNormals[normalID*3]<<" "<<nextNormals[normalID*3+1]<<" "<<nextNormals[normalID*3+2]<<" "<<endl; #endif } #ifdef MiarmyDebug logFile <<endl<< "----------------------- END -----------------------: "; logFile.close(); #endif AtArray *nsidesArray; AtArray *vidxsArray; AtArray *nidxsArray; AtArray *uvidxsArray; AtArray *vlistArray; AtArray *nlistArray; AtArray *uvlistArray; // proc geo: if (!motionBlurDef){ nsidesArray = AiArrayAllocate(geo.nsides.size(), 1, AI_TYPE_UINT); vidxsArray = AiArrayAllocate(geo.vidxs.size(), 1, AI_TYPE_UINT); nidxsArray = AiArrayAllocate(geo.nidxs.size(), 1, AI_TYPE_UINT); uvidxsArray = AiArrayAllocate(geo.uvidxs.size(), 1, AI_TYPE_UINT); vlistArray = AiArrayAllocate(geo.points.size() / 3, 1, AI_TYPE_POINT); nlistArray = AiArrayAllocate(geo.normals.size() / 3, 1, AI_TYPE_VECTOR); uvlistArray = AiArrayAllocate(geo.uvlist.size() / 2, 1, AI_TYPE_POINT2); uint i; AtPoint tempPoint; AtVector tempNormal; AtPoint2 tempPoint2; uint nbPnts = currentPoints.size() / 3; uint nbNormals = currentNormals.size() / 3; uint nbUVs = geo.uvlist.size() / 2; for (i = 0; i < geo.nsides.size(); i++) AiArraySetUInt(nsidesArray, i, geo.nsides[i]); for (i = 0; i < geo.vidxs.size(); i++) AiArraySetUInt(vidxsArray, i, geo.vidxs[i]); for (i = 0; i < geo.nidxs.size(); i++) AiArraySetUInt(nidxsArray, i, geo.nidxs[i]); for (i = 0; i < geo.uvidxs.size(); i++) AiArraySetUInt(uvidxsArray, i, geo.uvidxs[i]); for (i = 0; i < nbPnts; i++){ tempPoint.x = currentPoints[i*3]; tempPoint.y = currentPoints[i*3+1]; tempPoint.z = currentPoints[i*3+2]; AiArraySetPnt(vlistArray, i, tempPoint); } for (i = 0; i < nbNormals; i++){ tempNormal.x = currentNormals[i*3]; tempNormal.y = currentNormals[i*3+1]; tempNormal.z = currentNormals[i*3+2]; AiArraySetPnt(nlistArray, i, tempNormal); } for (i = 0; i < nbUVs; i++){ tempPoint2.x = geo.uvlist[i*2]; tempPoint2.y = geo.uvlist[i*2+1]; AiArraySetPnt2(uvlistArray, i, tempPoint2); } } else { nsidesArray = AiArrayAllocate(geo.nsides.size(), 1, AI_TYPE_UINT); vidxsArray = AiArrayAllocate(geo.vidxs.size(), 1, AI_TYPE_UINT); nidxsArray = AiArrayAllocate(geo.nidxs.size(), 1, AI_TYPE_UINT); uvidxsArray = AiArrayAllocate(geo.uvidxs.size(), 1, AI_TYPE_UINT); vlistArray = AiArrayAllocate(geo.points.size() / 3, 2, AI_TYPE_POINT); nlistArray = AiArrayAllocate(geo.normals.size() / 3, 2, AI_TYPE_VECTOR); uvlistArray = AiArrayAllocate(geo.uvlist.size() / 2, 1, AI_TYPE_POINT2); uint i; AtPoint tempPoint; AtVector tempNormal; AtPoint2 tempPoint2; uint nbPnts = currentPoints.size() / 3; uint nbNormals = currentNormals.size() / 3; uint nbUVs = geo.uvlist.size() / 2; for (i = 0; i < geo.nsides.size(); i++) AiArraySetUInt(nsidesArray, i, geo.nsides[i]); for (i = 0; i < geo.vidxs.size(); i++) AiArraySetUInt(vidxsArray, i, geo.vidxs[i]); for (i = 0; i < geo.nidxs.size(); i++) AiArraySetUInt(nidxsArray, i, geo.nidxs[i]); for (i = 0; i < geo.uvidxs.size(); i++) AiArraySetUInt(uvidxsArray, i, geo.uvidxs[i]); for (i = 0; i < nbPnts; i++){ tempPoint.x = currentPoints[i*3]; tempPoint.y = currentPoints[i*3+1]; tempPoint.z = currentPoints[i*3+2]; AiArraySetPnt(vlistArray, i, tempPoint); } for (i = 0; i < nbNormals; i++){ tempNormal.x = currentNormals[i*3]; tempNormal.y = currentNormals[i*3+1]; tempNormal.z = currentNormals[i*3+2]; AiArraySetPnt(nlistArray, i, tempNormal); } for (i = 0; i < nbPnts; i++){ tempPoint.x = nextPoints[i*3]; tempPoint.y = nextPoints[i*3+1]; tempPoint.z = nextPoints[i*3+2]; AiArraySetPnt(vlistArray, i+nbPnts, tempPoint); } for (i = 0; i < nbNormals; i++){ tempNormal.x = nextNormals[i*3]; tempNormal.y = nextNormals[i*3+1]; tempNormal.z = nextNormals[i*3+2]; AiArraySetPnt(nlistArray, i+nbNormals, tempNormal); } for (i = 0; i < nbUVs; i++){ tempPoint2.x = geo.uvlist[i*2]; tempPoint2.y = geo.uvlist[i*2+1]; AiArraySetPnt2(uvlistArray, i, tempPoint2); } } AtNode *meshNode = AiNode("polymesh"); AiNodeSetStr(meshNode, "name", geomStr.c_str()); AiNodeSetArray(meshNode, "nsides", nsidesArray); AiNodeSetArray(meshNode, "vidxs", vidxsArray); if (g_poly0_subd1 != 1) AiNodeSetArray(meshNode, "nidxs", nidxsArray); AiNodeSetArray(meshNode, "uvidxs", uvidxsArray); AiNodeSetArray(meshNode, "vlist", vlistArray); if (g_poly0_subd1 != 1) AiNodeSetArray(meshNode, "nlist", nlistArray); AiNodeSetArray(meshNode, "uvlist", uvlistArray); AiNodeSetBool(meshNode, "smoothing", true); if (g_poly0_subd1 == 1) AiNodeSetStr(meshNode, "subdiv_type", "catclark"); lockup = false; cout << "END GET NODE" << endl; return meshNode; }