void AlembicVisibilityController::GetValueLocalTime(TimeValue t, void *ptr, Interval &valid, GetSetMethod method) { ESS_CPP_EXCEPTION_REPORTING_START ESS_PROFILE_FUNC(); Interval interval = FOREVER; MCHAR const *strPath = NULL; this->pblock->GetValue(AlembicVisibilityController::ID_PATH, t, strPath, interval); MCHAR const *strIdentifier = NULL; this->pblock->GetValue(AlembicVisibilityController::ID_IDENTIFIER, t, strIdentifier, interval); float fTime; this->pblock->GetValue(AlembicVisibilityController::ID_TIME, t, fTime, interval); BOOL bMuted; this->pblock->GetValue(AlembicVisibilityController::ID_MUTED, t, bMuted, interval); if (bMuted || !strPath || !strIdentifier) { return; } std::string szPath = EC_MCHAR_to_UTF8(strPath); std::string szIdentifier = EC_MCHAR_to_UTF8(strIdentifier); AbcG::IObject iObj = getObjectFromArchive(szPath, szIdentifier); if (!iObj.valid()) { return; } alembic_fillvis_options visOptions; visOptions.pIObj = &iObj; visOptions.dTicks = t; visOptions.bOldVisibility = m_bOldVisibility; AlembicImport_FillInVis(visOptions); float fBool = visOptions.bVisibility ? 1.0f : 0.0f; m_bOldVisibility = visOptions.bVisibility; valid = interval; if (method == CTRL_ABSOLUTE) { float *fInVal = (float *)ptr; *fInVal = fBool; } else { // CTRL_RELATIVE float *fInVal = (float *)ptr; *fInVal = fBool * (*fInVal); } ESS_CPP_EXCEPTION_REPORTING_END }
AlembicPoints::AlembicPoints(SceneNodePtr eNode, AlembicWriteJob * in_Job, Abc::OObject oParent) : AlembicObject(eNode, in_Job, oParent) { mNumShapeMeshes = 0; mTotalShapeMeshes = 0; //mTimeSamplesCount = 0; std::string xformName = EC_MCHAR_to_UTF8( mMaxNode->GetName() ); std::string pointsName = xformName + "Shape"; AbcG::OPoints points(GetOParent(), pointsName.c_str(), GetCurrentJob()->GetAnimatedTs()); mPointsSchema = points.getSchema(); Abc::OCompoundProperty argGeomParams = mPointsSchema.getArbGeomParams(); // create all properties mInstanceNamesProperty = Abc::OStringArrayProperty(argGeomParams, ".instancenames", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); // particle attributes mScaleProperty = Abc::OV3fArrayProperty(argGeomParams, ".scale", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); mOrientationProperty = Abc::OQuatfArrayProperty(argGeomParams, ".orientation", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); mAngularVelocityProperty = Abc::OQuatfArrayProperty(argGeomParams, ".angularvelocity", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); mAgeProperty = Abc::OFloatArrayProperty(argGeomParams, ".age", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); mMassProperty = Abc::OFloatArrayProperty(argGeomParams, ".mass", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); mShapeTypeProperty = Abc::OUInt16ArrayProperty(argGeomParams, ".shapetype", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); mShapeTimeProperty = Abc::OFloatArrayProperty(argGeomParams, ".shapetime", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); mShapeInstanceIDProperty = Abc::OUInt16ArrayProperty(argGeomParams, ".shapeinstanceid", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); mColorProperty = Abc::OC4fArrayProperty(argGeomParams, ".color", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); }
void addFloatControllerV2(std::stringstream& evalStream, alembic_importoptions &options, std::string nodeName, const std::string& modkey, std::string propName, const std::string& file, const std::string& identifier, const std::string& category, std::string propertyID) { std::string mkStr; if(!modkey.empty()){ std::stringstream mkStream; mkStream<<".modifiers[\""<<modkey<<"\"]"; mkStr = mkStream.str(); } std::string timeControlName; if(options.pTimeControl){ timeControlName = EC_MCHAR_to_UTF8( options.pTimeControl->GetObjectName() ); } evalStream<<nodeName<<mkStr<<"."<<propName<<".controller = AlembicFloatController()\n"; evalStream<<nodeName<<mkStr<<"."<<propName<<".controller.path = \""<<file<<"\"\n"; evalStream<<nodeName<<mkStr<<"."<<propName<<".controller.identifier = \""<<identifier<<"\"\n"; evalStream<<nodeName<<mkStr<<"."<<propName<<".controller.propCategory = \""<<category<<"\"\n"; evalStream<<nodeName<<mkStr<<"."<<propName<<".controller.property = \""<<propertyID<<"\"\n"; evalStream<<nodeName<<mkStr<<"."<<propName<<".controller.time.controller = float_expression()\n"; if(options.loadTimeControl){ evalStream<<nodeName<<mkStr<<"."<<propName<<".controller.time.controller.AddScalarTarget \"current\" $'"<<timeControlName<<"'.time.controller\n"; evalStream<<nodeName<<mkStr<<"."<<propName<<".controller.time.controller.setExpression \"current\"\n"; } else{ evalStream<<nodeName<<mkStr<<"."<<propName<<".controller.time.controller.setExpression \"S\"\n"; } }
RefResult AlembicFloatController::NotifyRefChanged(Interval iv, RefTargetHandle hTarg, PartID& partID, RefMessage msg) #endif { switch (msg) { case REFMSG_CHANGE: if (hTarg == pblock) { ParamID changing_param = pblock->LastNotifyParamID(); switch (changing_param) { case ID_PATH: { delRefArchive(m_CachedAbcFile); const MCHAR* strPath = NULL; TimeValue t = GetCOREInterface()->GetTime(); Interval v; pblock->GetValue(AlembicFloatController::ID_PATH, t, strPath, v); m_CachedAbcFile = EC_MCHAR_to_UTF8(strPath); addRefArchive(m_CachedAbcFile); } break; default: break; } AlembicFloatControllerParams.InvalidateUI(changing_param); } break; case REFMSG_OBJECT_CACHE_DUMPED: return REF_STOP; break; } return REF_SUCCEED; }
void AlembicImport_ConnectTimeControl( const char* szControllerName, alembic_importoptions &options ) { char szBuffer[10000]; if(options.loadTimeControl && options.pTimeControl){ std::string objectNameName = EC_MCHAR_to_UTF8( options.pTimeControl->GetObjectName() ); sprintf_s( szBuffer, 10000, "%s.controller = float_expression()\n" "%s.controller.AddScalarTarget \"current\" $'%s'.time.controller\n" "%s.controller.setExpression \"current\"\n", szControllerName, szControllerName, objectNameName.c_str(), szControllerName, objectNameName.c_str(), szControllerName, objectNameName.c_str(), szControllerName ); } else{ sprintf_s( szBuffer, 10000, "%s.controller = float_expression()\n" "%s.controller.setExpression \"S\"\n" , szControllerName, szControllerName, szControllerName, szControllerName ); } ExecuteMAXScriptScript( EC_UTF8_to_TCHAR( szBuffer ) ); }
AlembicFloatController* getController(Animatable* pObj, const std::string& identifier, const std::string& camProperty, int i, int j, int k = -1) { if (i >= pObj->NumSubs()) { return NULL; } Animatable* an = pObj->SubAnim(i); if (!an || j >= an->NumSubs()) { return NULL; } an = an->SubAnim(j); if (k != -1) { if (!an || k >= an->NumSubs()) { return NULL; } an = an->SubAnim(k); } Class_ID cid = an->ClassID(); if (!an || an->ClassID() != ALEMBIC_FLOAT_CONTROLLER_CLASSID) { return NULL; } AlembicFloatController* pControl = static_cast<AlembicFloatController*>(an); TimeValue zero(0); std::string contIdentifier = EC_MCHAR_to_UTF8(pControl->GetParamBlockByID(0)->GetStr( GetParamIdByName(pControl, 0, "identifier"), zero)); if (strcmp(contIdentifier.c_str(), identifier.c_str()) != 0) { return NULL; } std::string contCamProperty = EC_MCHAR_to_UTF8(pControl->GetParamBlockByID(0)->GetStr( GetParamIdByName(pControl, 0, "property"), zero)); if (strcmp(contCamProperty.c_str(), camProperty.c_str()) != 0) { return NULL; } return pControl; }
AlembicCamera::AlembicCamera(SceneNodePtr eNode, AlembicWriteJob *in_Job, Abc::OObject oParent) : AlembicObject(eNode, in_Job, oParent) { std::string xformName = EC_MCHAR_to_UTF8(mMaxNode->GetName()); std::string cameraName = xformName + "Shape"; AbcG::OCamera camera(GetOParent(), cameraName.c_str(), GetCurrentJob()->GetAnimatedTs()); mCameraSchema = camera.getSchema(); }
bool AlembicCustomAttributesEx::defineCustomAttributes(INode* node, Abc::OCompoundProperty& compoundProp, const AbcA::MetaData& metadata, unsigned int animatedTs) { Modifier* pMod = FindModifier(node, (char*)this->modName.c_str()); if(!pMod){ return false; } ICustAttribContainer* cont = pMod->GetCustAttribContainer(); if(!cont){ return false; } for(int i=0; i<cont->GetNumCustAttribs(); i++) { CustAttrib* ca = cont->GetCustAttrib(i); std::string name = EC_MCHAR_to_UTF8( ca->GetName() ); pblock = ca->GetParamBlockByID(0); break; } if(!pblock){ return false; } for(int i=0, nNumParams = pblock->NumParams(); i<nNumParams; i++){ ParamID id = pblock->IndextoID(i); MSTR name = pblock->GetLocalName(id, 0); std::stringstream propName; propName<<EC_MSTR_to_UTF8(name); ParamType2 type = pblock->GetParameterType(id); if(type == TYPE_STRING){ customProps[propName.str()] = new Abc::OStringProperty(compoundProp, propName.str().c_str(), metadata, animatedTs ); } else if(type == TYPE_FLOAT){ customProps[propName.str()] = new Abc::OFloatProperty(compoundProp, propName.str().c_str(), metadata, animatedTs ); } else if(type == TYPE_INT){ customProps[propName.str()] = new Abc::OInt32Property(compoundProp, propName.str().c_str(), metadata, animatedTs ); } } return true; }
AlembicCurves::AlembicCurves(SceneNodePtr eNode, AlembicWriteJob * in_Job, Abc::OObject oParent) : AlembicObject(eNode, in_Job, oParent) { std::string xformName = EC_MCHAR_to_UTF8( mMaxNode->GetName() ); std::string curveName = xformName + "Shape"; AbcG::OCurves curves(GetOParent(),curveName,GetCurrentJob()->GetAnimatedTs()); mCurvesSchema = curves.getSchema(); // create all properties //mInTangentProperty = OV3fArrayProperty(mCurvesSchema.getArbGeomParams(), ".inTangent", mCurvesSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); //mOutTangentProperty = OV3fArrayProperty(mCurvesSchema.getArbGeomParams(), ".outTangent", mCurvesSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); //mRadiusProperty = OFloatArrayProperty(mCurvesSchema.getArbGeomParams(), ".radius", mCurvesSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); //mColorProperty = OC4fArrayProperty(mCurvesSchema.getArbGeomParams(), ".color", mCurvesSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() ); }
void addFloatController(std::stringstream& evalStream, alembic_importoptions &options, const std::string& modkey, std::string propName, const std::string& file, const std::string& identifier, std::string propertyID/*, const std::string& propComponent=std::string(""), const std::string& propInterp=std::string("")*/) { //if(propComponent.length() > 0){ // propName += propComponent; // propertyID += "."; // propertyID += propInterp; // propertyID += "."; // propertyID += propComponent; //} std::string mkStr; if(!modkey.empty()){ std::stringstream mkStream; mkStream<<".modifiers[\""<<modkey<<"\"]"; mkStr = mkStream.str(); } std::string timeControlName; if(options.pTimeControl){ timeControlName = EC_MCHAR_to_UTF8( options.pTimeControl->GetObjectName() ); } evalStream<<"$"<<mkStr<<"."<<propName<<".controller = AlembicFloatController()\n"; evalStream<<"$"<<mkStr<<"."<<propName<<".controller.path = \""<<file<<"\"\n"; evalStream<<"$"<<mkStr<<"."<<propName<<".controller.identifier = \""<<identifier<<"\"\n"; evalStream<<"$"<<mkStr<<"."<<propName<<".controller.property = \""<<propertyID<<"\"\n"; evalStream<<"$"<<mkStr<<"."<<propName<<".controller.time.controller = float_expression()\n"; if(options.loadTimeControl){ evalStream<<"$"<<mkStr<<"."<<propName<<".controller.time.controller.AddScalarTarget \"current\" $'"<<timeControlName<<"'.time.controller\n"; evalStream<<"$"<<mkStr<<"."<<propName<<".controller.time.controller.setExpression \"current\"\n"; } else{ evalStream<<"$"<<mkStr<<"."<<propName<<".controller.time.controller.setExpression \"S\"\n"; } }
int importAlembicScene(AbcArchiveCache *pArchiveCache, AbcObjectCache *pRootObjectCache, alembic_importoptions &options, std::string &file, progressUpdate &progress, std::map<std::string, bool> &nodeFullPaths) { std::vector<stackElement> sceneStack; sceneStack.reserve(200); for (size_t j = 0; j < pRootObjectCache->childIdentifiers.size(); j++) { sceneStack.push_back(stackElement( &(pArchiveCache->find(pRootObjectCache->childIdentifiers[j])->second))); } while (!sceneStack.empty()) { stackElement sElement = sceneStack.back(); sceneStack.pop_back(); Abc::IObject &iObj = sElement.pObjectCache->obj; INode *pParentMaxNode = sElement.pParentMaxNode; if (!iObj.valid()) { return alembic_failure; } const std::string fullname = iObj.getFullName(); const std::string pname = (pParentMaxNode) ? EC_MCHAR_to_UTF8(pParentMaxNode->GetName()) : std::string(""); const std::string name = iObj.getName(); ESS_LOG_INFO("Importing " << fullname); bool bCreateDummyNode = false; int mergedGeomNodeIndex = -1; AbcObjectCache *pMergedObjectCache = NULL; getMergeInfo(pArchiveCache, sElement.pObjectCache, bCreateDummyNode, mergedGeomNodeIndex, &pMergedObjectCache); INode *pMaxNode = NULL; // the newly create node, which may be a merged node INode *pExistingNode = NULL; int keepTM = 1; // I don't remember why this needed to be set in some // cases. bool bCreateNode = true; if (!nodeFullPaths.empty()) { if (mergedGeomNodeIndex != -1) { AbcG::IObject mergedGeomChild = pMergedObjectCache->obj; bCreateNode = nodeFullPaths.find(mergedGeomChild.getFullName()) != nodeFullPaths.end(); } else { bCreateNode = nodeFullPaths.find(fullname) != nodeFullPaths.end(); } } if (bCreateNode) { // if we are about to merge a camera with its parent transform, force it // to create a dummy node instead if the camera's // transform also has children. This is done to prevent the camera // correction matrix from being applied to the other children if (!bCreateDummyNode && pMergedObjectCache && sElement.pObjectCache->childIdentifiers.size() > 1 && AbcG::ICamera::matches(pMergedObjectCache->obj.getMetaData())) { bCreateDummyNode = true; mergedGeomNodeIndex = -1; } if (bCreateDummyNode) { std::string importName = removeXfoSuffix(iObj.getName()); pExistingNode = GetChildNodeFromName(importName, pParentMaxNode); if (options.attachToExisting && pExistingNode) { pMaxNode = pExistingNode; // see if a controller already exists, and then delete it int ret = AlembicImport_XForm(pParentMaxNode, pMaxNode, iObj, NULL, file, options); if (ret != 0) { return ret; } } // only create node if either attachToExisting is false or it is true // and the object does not already exist else { int ret = AlembicImport_DummyNode(iObj, options, &pMaxNode, importName); if (ret != 0) { return ret; } ret = AlembicImport_XForm(pParentMaxNode, pMaxNode, iObj, NULL, file, options); if (ret != 0) { return ret; } } } else { if (mergedGeomNodeIndex != -1) { // we are merging, so look at the child geometry node AbcG::IObject mergedGeomChild = pMergedObjectCache->obj; std::string importName = removeXfoSuffix(iObj.getName()); // mergedGeomChild.getName()); pExistingNode = GetChildNodeFromName(importName, pParentMaxNode); if (options.attachToExisting && pExistingNode) { pMaxNode = pExistingNode; } // only create node if either attachToExisting is false or it is // true and the object does not already exist int ret = createAlembicObject(mergedGeomChild, &pMaxNode, options, file); if (ret != 0) { return ret; } if (pMaxNode != NULL) { ret = AlembicImport_XForm(pParentMaxNode, pMaxNode, iObj, &mergedGeomChild, file, options); if (ret != 0) { return ret; } } } else { // geometry node(s) under a dummy node (in pParentMaxNode) pExistingNode = GetChildNodeFromName(iObj.getName(), pParentMaxNode); if (options.attachToExisting && pExistingNode) { pMaxNode = pExistingNode; } // only create node if either attachToExisting is false or it is // true and the object does not already exist int ret = createAlembicObject(iObj, &pMaxNode, options, file); if (ret != 0) { return ret; } // since the transform is the identity, should position relative to // parent keepTM = 0; if (AbcG::ICamera::matches(iObj.getMetaData())) { // apply camera adjustment matrix to the identity Matrix3 rotation(TRUE); rotation.RotateX(HALFPI); TimeValue zero(0); pMaxNode->SetNodeTM(zero, rotation); } // import identity matrix, since more than goemetry node share the // same transform // Should we just list MAX put a default position/scale/rotation // controller on? // int ret = AlembicImport_XForm(pMaxNode, *piParentObj, file, // options); } if (options.failOnUnsupported) { if (!pMaxNode) { return alembic_failure; } } } } if (pMaxNode && pParentMaxNode && !pExistingNode) { pParentMaxNode->AttachChild(pMaxNode, keepTM); } progress.increment(); progress.update(); if (pMaxNode) { for (size_t j = 0; j < sElement.pObjectCache->childIdentifiers.size(); j++) { AbcObjectCache *pChildObjectCache = &(pArchiveCache->find(sElement.pObjectCache->childIdentifiers[j]) ->second); if (NodeCategory::get(pChildObjectCache->obj) == NodeCategory::UNSUPPORTED) { continue; // skip over unsupported types } // I assume that geometry nodes are always leaf nodes. Thus, if we // merged a geometry node will its parent transform, we don't // need to push it to the stack. // A geometry node can't be combined with its transform node, the // transform node has other tranform nodes as children. These // nodes must be pushed. if (mergedGeomNodeIndex != j) { sceneStack.push_back(stackElement(pChildObjectCache, pMaxNode)); } } } } return alembic_success; }
AlembicPoints::meshInfo AlembicPoints::CacheShapeMesh(Mesh* pShapeMesh, BOOL bNeedDelete, Matrix3 meshTM, int nMatId, int particleId, TimeValue ticks, ShapeType &type, Abc::uint16_t &instanceId, float &animationTime) { ESS_PROFILE_FUNC(); type = ShapeType_Instance; //animationTime = 0; //Mesh* pShapeMesh = pExt->GetParticleShapeByIndex(particleId); if(pShapeMesh->getNumFaces() == 0 || pShapeMesh->getNumVerts() == 0){ meshInfo mi; return mi; } meshDigests digests; { ESS_PROFILE_SCOPE("AlembicPoints::CacheShapeMesh - compute hash"); AbcU::MurmurHash3_x64_128( pShapeMesh->verts, pShapeMesh->numVerts * sizeof(Point3), sizeof(Point3), digests.Vertices.words ); AbcU::MurmurHash3_x64_128( pShapeMesh->faces, pShapeMesh->numFaces * sizeof(Face), sizeof(Face), digests.Faces.words ); if(mJob->GetOption("exportMaterialIds")){ std::vector<MtlID> matIds; if(nMatId < 0){ matIds.reserve(pShapeMesh->getNumFaces()); for(int i=0; i<pShapeMesh->getNumFaces(); i++){ matIds.push_back(pShapeMesh->getFaceMtlIndex(i)); } } else{ matIds.push_back(nMatId); } AbcU::MurmurHash3_x64_128( &matIds[0], matIds.size() * sizeof(MtlID), sizeof(MtlID), digests.MatIds.words ); } if(mJob->GetOption("exportUVs")){ //TODO... } } mTotalShapeMeshes++; meshInfo currShapeInfo; faceVertexHashToShapeMap::iterator it = mShapeMeshCache.find(digests); if( it != mShapeMeshCache.end() ){ currShapeInfo = it->second; } else{ meshInfo& mi = mShapeMeshCache[digests]; mi.pMesh = pShapeMesh; mi.bbox = computeBoundingBox(pShapeMesh); mi.nMatId = nMatId; std::stringstream nameStream; nameStream<< EC_MCHAR_to_UTF8( mMaxNode->GetName() ) <<"_"; nameStream<<"InstanceMesh"<<mNumShapeMeshes; mi.name=nameStream.str(); mi.bNeedDelete = bNeedDelete; mi.meshTM = meshTM; mi.nMeshInstanceId = mNumShapeMeshes; currShapeInfo = mi; mNumShapeMeshes++; mMeshesToSaveForCurrentFrame.push_back(&mi); //ESS_LOG_WARNING("ticks: "<<ticks<<" particleId: "<<particleId); //ESS_LOG_WARNING("Adding shape with hash("<<vertexDigest.str()<<", "<<faceDigest.str()<<") \n auto assigned name "<<mi.name <<" efficiency:"<<(double)mNumShapeMeshes/mTotalShapeMeshes); } instanceId = currShapeInfo.nMeshInstanceId; // { // ESS_PROFILE_SCOPE("CacheShapeMesh push_back instance name"); //std::string pathName("/"); //pathName += currShapeInfo.name; //instanceId = FindInstanceName(pathName); //if (instanceId == USHRT_MAX){ // mInstanceNames.push_back(pathName); // instanceId = (Abc::uint16_t)mInstanceNames.size()-1; //} // } return currShapeInfo; }
void AlembicPoints::ReadShapeFromOperator( IParticleGroup *particleGroup, PFSimpleOperator *pSimpleOperator, int particleId, TimeValue ticks, ShapeType &type, Abc::uint16_t &instanceId, float &animationTime) { if(!pSimpleOperator){ return; } if (pSimpleOperator->ClassID() == PFOperatorSimpleShape_Class_ID) { IParamBlock2 *pblock = pSimpleOperator->GetParamBlockByID(0); int nShapeId = pblock->GetInt(PFlow_kSimpleShape_shape, ticks); switch(nShapeId) { case PFlow_kSimpleShape_shape_pyramid: type = ShapeType_Cone; break; case PFlow_kSimpleShape_shape_cube: type = ShapeType_Box; break; case PFlow_kSimpleShape_shape_sphere: type = ShapeType_Sphere; break; case PFlow_kSimpleShape_shape_vertex: type = ShapeType_Point; break; default: type = ShapeType_Point; } } else if (pSimpleOperator->ClassID() == PFOperatorShapeLib_Class_ID) { IParamBlock2 *pblock = pSimpleOperator->GetParamBlockByID(0); int nDimension = pblock->GetInt(PFlow_kShapeLibary_dimensionType, ticks); if(nDimension == PFlow_kShapeLibrary_dimensionType_2D){ int n2DShapeId = pblock->GetInt(PFlow_kShapeLibary_2DType, ticks); if( n2DShapeId == PFlow_kShapeLibrary_dimensionType_2D_square){ type = ShapeType_Rectangle; } else{ ESS_LOG_INFO("Unsupported shape type."); type = ShapeType_Point; } } else if(nDimension == PFlow_kShapeLibrary_dimensionType_3D){ int n3DShapeId = pblock->GetInt(PFlow_kShapeLibary_3DType, ticks); if(n3DShapeId == PFlow_kShapeLibary_3DType_cube){ type = ShapeType_Box; } else if(n3DShapeId == PFlow_kShapeLibary_3DType_Sphere20sides || n3DShapeId == PFlow_kShapeLibary_3DType_Sphere80sides){ type = ShapeType_Sphere; } else{ ESS_LOG_INFO("Unsupported shape type."); type = ShapeType_Point; } //ShapeType_Cylinder unsupported //ShapeType_Cone unsupported //ShapeType_Disc unsupported //ShapeType_NbElements unsupported } else{ ESS_LOG_INFO("Unknown dimension."); type = ShapeType_Point; } //int nNumParams = pblock->NumParams(); //for(int i=0; i<nNumParams; i++){ // ParamID id = pblock->IndextoID(i); // MSTR paramStr = pblock->GetLocalName(id, 0); // int n = 0; // //} } else if (pSimpleOperator->ClassID() == PFOperatorInstanceShape_Class_ID) { // Assign animation time and shape here IParamBlock2 *pblock = pSimpleOperator->GetParamBlockByID(0); INode *pNode = pblock->GetINode(PFlow_kInstanceShape_objectMaxscript, ticks); if (pNode == NULL || pNode->GetName() == NULL) { return; } type = ShapeType_Instance; bool bFlatten = GetCurrentJob()->GetOption("flattenHierarchy"); std::string nodePath = getNodeAlembicPath( EC_MCHAR_to_UTF8( pNode->GetName() ), bFlatten); // Find if the name is alerady registered, otherwise add it to the list // instanceId = FindInstanceName(nodePath); // if (instanceId == USHRT_MAX) // { //mInstanceNames.push_back(nodePath); // instanceId = (Abc::uint16_t)mInstanceNames.size()-1; // } // Determine if we have an animated shape BOOL animatedShape = pblock->GetInt(PFlow_kInstanceShape_animatedShape); BOOL acquireShape = pblock->GetInt(PFlow_kInstanceShape_acquireShape); if (!animatedShape && !acquireShape) { return; } // Get the necesary particle channels to grab the current time values ::IObject *pCont = particleGroup->GetParticleContainer(); if (!pCont) { return; } // Get synch values that we are interested in fromt the param block int syncType = pblock->GetInt(PFlow_kInstanceShape_syncType); BOOL syncRandom = pblock->GetInt(PFlow_kInstanceShape_syncRandom); IParticleChannelPTVR* chTime = GetParticleChannelTimeRInterface(pCont); if (chTime == NULL) { return; // can't find particle times in the container } IChannelContainer* chCont = GetChannelContainerInterface(pCont); if (chCont == NULL) { return; // can't get access to ChannelContainer interface } IParticleChannelPTVR* chBirthTime = NULL; IParticleChannelPTVR* chEventStartR = NULL; bool initEventStart = false; if (syncType == PFlow_kInstanceShape_syncBy_particleAge) { chBirthTime = GetParticleChannelBirthTimeRInterface(pCont); if (chBirthTime == NULL) { return; // can't read particle age } } else if (syncType == PFlow_kInstanceShape_syncBy_eventStart) { chEventStartR = GetParticleChannelEventStartRInterface(pCont); if (chEventStartR == NULL) { return; // can't read event start time } } IParticleChannelIntR* chLocalOffR = NULL; bool initLocalOff = false; // acquire LocalOffset particle channel; if not present then create it. if (syncRandom) { chLocalOffR = (IParticleChannelIntR*)chCont->GetPrivateInterface(PARTICLECHANNELLOCALOFFSETR_INTERFACE, pSimpleOperator); } // get new shape from the source PreciseTimeValue time = chTime->GetValue(particleId); switch(syncType) { case PFlow_kInstanceShape_syncBy_absoluteTime: break; case PFlow_kInstanceShape_syncBy_particleAge: time -= chBirthTime->GetValue(particleId); break; case PFlow_kInstanceShape_syncBy_eventStart: time -= chEventStartR->GetValue(particleId); break; default: break; } if (syncRandom) { if (chLocalOffR != NULL) time += chLocalOffR->GetValue(particleId); } //timeValueMap::iterator it = mTimeValueMap.find(time); //if( it != mTimeValueMap.end() ){ // ESS_LOG_WARNING("sampleTime already seen."); //} //else{ // mTimeValueMap[time] = true; // mTimeSamplesCount++; // ESS_LOG_WARNING("sampleTime: "<<(float)time<<" totalSamples: "<<mTimeSamplesCount); //} TimeValue t = TimeValue(time); animationTime = (float)GetSecondsFromTimeValue(t); } else if (pSimpleOperator->ClassID() == PFOperatorMarkShape_Class_ID) { ESS_LOG_INFO("Shape Mark operator not supported."); } else if (pSimpleOperator->ClassID() == PFOperatorFacingShape_Class_ID) { ESS_LOG_INFO("Shape Facing operator not supported."); } }
void AlembicImport_TimeControl( alembic_importoptions &options ) { if(!options.loadTimeControl){ return; } // check if an Alembic Time Control already exists in the scene. BOOL alreadyExists = ExecuteMAXScriptScript( _T( "select $Alembic_Time_Control" ), TRUE ); if( alreadyExists != 0 ) { if( GetCOREInterface()->GetSelNodeCount() > 0 ) { INode *pSelectedNode = GetCOREInterface()->GetSelNode( 0 ); HelperObject *pSelectedHelper = static_cast<HelperObject*>( pSelectedNode->GetObjectRef() ); options.pTimeControl = pSelectedHelper; return; } } // Create the xform modifier HelperObject *pHelper = static_cast<HelperObject*> (GetCOREInterface()->CreateInstance(HELPER_CLASS_ID, ALEMBIC_TIME_CONTROL_HELPER_CLASSID)); TimeValue zero( 0 ); // Set the alembic id pHelper->GetParamBlockByID( 0 )->SetValue( GetParamIdByName( pHelper, 0, "current" ), zero, 0.0f ); pHelper->GetParamBlockByID( 0 )->SetValue( GetParamIdByName( pHelper, 0, "offset" ), zero, 0.0f ); pHelper->GetParamBlockByID( 0 )->SetValue( GetParamIdByName( pHelper, 0, "factor" ), zero, 1.0f ); // Create the object node INode *node = GET_MAX_INTERFACE()->CreateObjectNode(pHelper, pHelper->GetObjectName() ); // Add the new inode to our current scene list SceneEntry *pEntry = options.sceneEnumProc.Append(node, pHelper, OBTYPE_CURVES, &std::string( EC_MCHAR_to_UTF8( node->GetName() ) ) ); options.currentSceneList.Append(pEntry); //GET_MAX_INTERFACE()->SelectNode( node ); //std::string nodeName = EC_MCHAR_to_UTF8( node->GetName() ); //char szBuffer[10000]; //sprintf_s( szBuffer, 10000, // "$'%s'.current.controller = float_expression()\n" // "$'%s'.current.controller.setExpression \"S\"\n" // "$'%s'.offset.controller = bezier_float()\n" // "$'%s'.factor.controller = bezier_float()\n" // , nodeName.c_str(), nodeName.c_str(), nodeName.c_str(), nodeName.c_str() ); //ExecuteMAXScriptScript( EC_UTF8_to_TCHAR( szBuffer ) ); options.pTimeControl = pHelper; }
void AlembicFloatController::GetValueLocalTime(TimeValue t, void* ptr, Interval& valid, GetSetMethod method) { ESS_CPP_EXCEPTION_REPORTING_START Interval interval = FOREVER; MCHAR const* strPath = NULL; this->pblock->GetValue(AlembicFloatController::ID_PATH, t, strPath, interval); MCHAR const* strIdentifier = NULL; this->pblock->GetValue(AlembicFloatController::ID_IDENTIFIER, t, strIdentifier, interval); MCHAR const* strCategory = NULL; this->pblock->GetValue(AlembicFloatController::ID_CATEGORY, t, strCategory, interval); MCHAR const* strProperty = NULL; this->pblock->GetValue(AlembicFloatController::ID_PROPERTY, t, strProperty, interval); float fTime; this->pblock->GetValue(AlembicFloatController::ID_TIME, t, fTime, interval); BOOL bMuted; this->pblock->GetValue(AlembicFloatController::ID_MUTED, t, bMuted, interval); extern bool g_bVerboseLogging; if (g_bVerboseLogging) { ESS_LOG_WARNING("Param block at tick " << t << "-----------------------"); ESS_LOG_WARNING("PATH: " << strPath); ESS_LOG_WARNING("IDENTIFIER: " << strIdentifier); ESS_LOG_WARNING("PROPERTY: " << strProperty); ESS_LOG_WARNING("TIME: " << fTime); ESS_LOG_WARNING("MUTED: " << bMuted); ESS_LOG_WARNING("Param block end -------------"); } const float fDefaultVal = -1.0; std::string szPath = EC_MCHAR_to_UTF8(strPath); std::string szIdentifier = EC_MCHAR_to_UTF8(strIdentifier); std::string szProperty = EC_MCHAR_to_UTF8(strProperty); std::string szCategory = EC_MCHAR_to_UTF8(strCategory); if (szCategory.empty()) { // default to standard properties for backwards // compatibility szCategory = std::string("standardProperties"); } if (!strProperty || !strPath || !strIdentifier /*|| !strCategory*/) { return setController("1", szProperty, valid, interval, method, ptr, fDefaultVal); } if (bMuted) { return setController("2", szProperty, valid, interval, method, ptr, fDefaultVal); } // if( szCategory.size() == 0 ) { // ESS_LOG_ERROR( "No category specified." ); // return setController("3a", szProperty, valid, interval, method, ptr, // fDefaultVal); //} if (szProperty.size() == 0) { ESS_LOG_ERROR("No property specified."); return setController("3b", szProperty, valid, interval, method, ptr, fDefaultVal); } AbcG::IObject iObj = getObjectFromArchive(szPath, szIdentifier); if (!iObj.valid()) { return setController("4", szProperty, valid, interval, method, ptr, fDefaultVal); } TimeValue dTicks = GetTimeValueFromSeconds(fTime); double sampleTime = GetSecondsFromTimeValue(dTicks); float fSampleVal = fDefaultVal; if (boost::iequals(szCategory, "standardProperties")) { if (Alembic::AbcGeom::ICamera::matches( iObj.getMetaData())) { // standard camera properties Alembic::AbcGeom::ICamera objCamera = Alembic::AbcGeom::ICamera(iObj, Alembic::Abc::kWrapExisting); SampleInfo sampleInfo = getSampleInfo(sampleTime, objCamera.getSchema().getTimeSampling(), objCamera.getSchema().getNumSamples()); Alembic::AbcGeom::CameraSample sample; objCamera.getSchema().get(sample, sampleInfo.floorIndex); double sampleVal; if (!getCameraSampleVal(objCamera, sampleInfo, sample, szProperty, sampleVal)) { return setController("5", szProperty, valid, interval, method, ptr, fDefaultVal); } // Blend the camera values, if necessary if (sampleInfo.alpha != 0.0) { objCamera.getSchema().get(sample, sampleInfo.ceilIndex); double sampleVal2 = 0.0; if (getCameraSampleVal(objCamera, sampleInfo, sample, szProperty, sampleVal2)) { sampleVal = (1.0 - sampleInfo.alpha) * sampleVal + sampleInfo.alpha * sampleVal2; } } fSampleVal = (float)sampleVal; } else if (Alembic::AbcGeom::ILight::matches( iObj.getMetaData())) { // ILight material properties ESS_PROFILE_SCOPE( "AlembicFloatController::GetValueLocalTime - read ILight shader " "parameter"); Alembic::AbcGeom::ILight objLight = Alembic::AbcGeom::ILight(iObj, Alembic::Abc::kWrapExisting); SampleInfo sampleInfo = getSampleInfo(sampleTime, objLight.getSchema().getTimeSampling(), objLight.getSchema().getNumSamples()); AbcM::IMaterialSchema matSchema = getMatSchema(objLight); std::string strProp = szProperty; std::vector<std::string> parts; boost::split(parts, strProp, boost::is_any_of(".")); if (parts.size() == 3) { const std::string& target = parts[0]; const std::string& type = parts[1]; const std::string& prop = parts[2]; Abc::IFloatProperty fProp = readShaderScalerProp<Abc::IFloatProperty>( matSchema, target, type, prop); if (fProp.valid()) { fProp.get(fSampleVal, sampleInfo.floorIndex); } else { ESS_LOG_WARNING("Float Controller Error: could find shader parameter " << strProp); } } else if (parts.size() == 5) { const std::string& target = parts[0]; const std::string& type = parts[1]; const std::string& prop = parts[2]; const std::string& propInterp = parts[3]; const std::string& propComp = parts[4]; // ESS_LOG_WARNING("propInterp: "<<propInterp); if (propInterp == "rgb") { Abc::IC3fProperty fProp = readShaderScalerProp<Abc::IC3fProperty>( matSchema, target, type, prop); if (fProp.valid()) { Abc::C3f v3f; fProp.get(v3f, sampleInfo.floorIndex); if (propComp == "x") { fSampleVal = v3f.x; } else if (propComp == "y") { fSampleVal = v3f.y; } else if (propComp == "z") { fSampleVal = v3f.z; } else { ESS_LOG_WARNING( "Float Controller Error: invalid component: " << propComp); } } else { ESS_LOG_WARNING( "Float Controller Error: could find shader parameter " << strProp); } } else { ESS_LOG_WARNING( "Float Controller Error: unrecognized parameter interpretation: " << propInterp); } } else { ESS_LOG_WARNING( "Float Controller Error: could not parse property field: " << strProperty); } } } else if (boost::iequals(szCategory, "userProperties")) { // AbcA::TimeSamplingPtr timeSampling = obj.getSchema().getTimeSampling(); // int nSamples = (int)obj.getSchema().getNumSamples(); AbcA::TimeSamplingPtr timeSampling; int nSamples = 0; Abc::ICompoundProperty propk = AbcNodeUtils::getUserProperties(iObj, timeSampling, nSamples); if (propk.valid()) { SampleInfo sampleInfo = getSampleInfo(sampleTime, timeSampling, nSamples); std::vector<std::string> parts; boost::split(parts, szProperty, boost::is_any_of(".")); if (parts.size() == 1) { Abc::IFloatProperty fProp = readScalarProperty<Abc::IFloatProperty>(propk, szProperty); if (fProp.valid()) { fProp.get(fSampleVal, sampleInfo.floorIndex); } else { Abc::IInt32Property intProp = readScalarProperty<Abc::IInt32Property>(propk, szProperty); if (intProp.valid()) { int intVal; intProp.get(intVal, sampleInfo.floorIndex); fSampleVal = (float)intVal; } else { ESS_LOG_WARNING( "Float Controller Error: could not read user property " << szProperty); } } } else if (parts.size() == 3) { const std::string& prop = parts[0]; const std::string& propInterp = parts[1]; const std::string& propComp = parts[2]; // ESS_LOG_WARNING("interpretation: "<<propInterp); if (propInterp == "rgb") { fSampleVal = readScalarPropertyExt3<Abc::IC3fProperty, Abc::C3f>( propk, sampleInfo, prop, propComp); } else if (propInterp == "vector") { fSampleVal = readScalarPropertyExt3<Abc::IV3fProperty, Abc::V3f>( propk, sampleInfo, prop, propComp); } else { ESS_LOG_WARNING( "Float Controller Error: unrecognized parameter interpretation: " << propInterp); } } } } // else if( boost::iequals(szCategory, "arbGeomParams") ){ //} return setController("6", szProperty, valid, interval, method, ptr, fSampleVal); ESS_CPP_EXCEPTION_REPORTING_END }
void SaveMetaData(INode* node, AlembicObject* object) { if (object == NULL) { return; } if (object->GetNumSamples() > 0) { return; } Modifier* pMod = FindModifier(node, Class_ID(0xd81fc3e, 0x1e4eacf5)); bool bReadCustAttribs = false; if (!pMod) { pMod = FindModifier(node, "Metadata"); bReadCustAttribs = true; } if (!pMod) { return; } std::vector<std::string> metaData; if (bReadCustAttribs) { ICustAttribContainer* cont = pMod->GetCustAttribContainer(); if (!cont) { return; } for (int i = 0; i < cont->GetNumCustAttribs(); i++) { CustAttrib* ca = cont->GetCustAttrib(i); std::string name = EC_MCHAR_to_UTF8(ca->GetName()); IParamBlock2* pblock = ca->GetParamBlockByID(0); if (pblock) { int nNumParams = pblock->NumParams(); for (int i = 0; i < nNumParams; i++) { ParamID id = pblock->IndextoID(i); // MSTR name = pblock->GetLocalName(id, 0); MSTR value = pblock->GetStr(id, 0); metaData.push_back(EC_MSTR_to_UTF8(value)); } } } } else { IParamBlock2* pblock = pMod->GetParamBlockByID(0); if (pblock && pblock->NumParams() == 1) { ParamID id = pblock->IndextoID(0); MSTR name = pblock->GetLocalName(id, 0); int nSize = pblock->Count(id); for (int i = 0; i < nSize; i++) { MSTR value = pblock->GetStr(id, 0, i); metaData.push_back(EC_MSTR_to_UTF8(value)); } } } if (metaData.size() > 0) { Abc::OStringArrayProperty metaDataProperty = Abc::OStringArrayProperty( object->GetCompound(), ".metadata", object->GetCompound().getMetaData(), object->GetCurrentJob()->GetAnimatedTs()); Abc::StringArraySample metaDataSample(&metaData.front(), metaData.size()); metaDataProperty.set(metaDataSample); } }