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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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);
  }
}