コード例 #1
0
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() );
}
コード例 #2
0
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();
}
コード例 #3
0
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() );
}
コード例 #4
0
bool AlembicPoints::Save(double time, bool bLastFrame)
{
   ESS_PROFILE_FUNC();

    // Note: Particles are always considered to be animated even though
    //       the node does not have the IsAnimated() flag.

    // Extract our particle emitter at the given time
    TimeValue ticks = GetTimeValueFromFrame(time);
    Object *obj = mMaxNode->EvalWorldState(ticks).obj;

	SaveMetaData(mMaxNode, this);

	SimpleParticle* pSimpleParticle = (SimpleParticle*)obj->GetInterface(I_SIMPLEPARTICLEOBJ);
	IPFSystem* ipfSystem = GetPFSystemInterface(obj);
	IParticleObjectExt* particlesExt = GetParticleObjectExtInterface(obj);
	
#ifdef THINKING_PARTICLES
	ParticleMat* pThinkingParticleMat = NULL;
	TP_MasterSystemInterface* pTPMasterSystemInt = NULL;
	if(obj->CanConvertToType(MATTERWAVES_CLASS_ID))
	{
		pThinkingParticleMat = reinterpret_cast<ParticleMat*>(obj->ConvertToType(ticks, MATTERWAVES_CLASS_ID));
		pTPMasterSystemInt = reinterpret_cast<TP_MasterSystemInterface*>(obj->GetInterface(IID_TP_MASTERSYSTEM));     

	}
#endif

	const bool bAutomaticInstancing = GetCurrentJob()->GetOption("automaticInstancing");

	if( 
#ifdef THINKING_PARTICLES
		!pThinkingParticleMat && 
#endif
		!particlesExt && !pSimpleParticle){
		return false;
	}


	//We have to put the particle system into the renders state so that PFOperatorMaterialFrequency::Proceed will set the materialID channel
	//Note: settting the render state to true breaks the shape node instancing export
	bool bRenderStateForced = false;
	if(bAutomaticInstancing && ipfSystem && !ipfSystem->IsRenderState()){
		ipfSystem->SetRenderState(true);
		bRenderStateForced = true;
	}

	int numParticles = 0;
#ifdef THINKING_PARTICLES
	if(pThinkingParticleMat){
		numParticles = pThinkingParticleMat->NumParticles();	
	}
	else 
#endif
	if(particlesExt){
		particlesExt->UpdateParticles(mMaxNode, ticks);
		numParticles = particlesExt->NumParticles();
	}
	else if(pSimpleParticle){
		pSimpleParticle->Update(ticks, mMaxNode);
		numParticles = pSimpleParticle->parts.points.Count();
	}


    // Store positions, velocity, width/size, scale, id, bounding box
    std::vector<Abc::V3f> positionVec;
    std::vector<Abc::V3f> velocityVec;
    std::vector<Abc::V3f> scaleVec;
    std::vector<float> widthVec;
    std::vector<float> ageVec;
    std::vector<float> massVec;
    std::vector<float> shapeTimeVec;
    std::vector<Abc::uint64_t> idVec;
    std::vector<Abc::uint16_t> shapeTypeVec;
    std::vector<Abc::uint16_t> shapeInstanceIDVec;
    std::vector<Abc::Quatf> orientationVec;
    std::vector<Abc::Quatf> angularVelocityVec;
    std::vector<Abc::C4f> colorVec;

    positionVec.reserve(numParticles);
    velocityVec.reserve(numParticles);
    scaleVec.reserve(numParticles);
    widthVec.reserve(numParticles);
    ageVec.reserve(numParticles);
    massVec.reserve(numParticles);
    shapeTimeVec.reserve(numParticles);
    idVec.reserve(numParticles);
    shapeTypeVec.reserve(numParticles);
    shapeInstanceIDVec.reserve(numParticles);
    orientationVec.reserve(numParticles);
    angularVelocityVec.reserve(numParticles);
    colorVec.reserve(numParticles);

    //std::vector<std::string> instanceNamesVec;
    Abc::Box3d bbox;
    bool constantPos = true;
    bool constantVel = true;
    bool constantScale = true;
    bool constantWidth = true;
    bool constantAge = true;
    bool constantOrientation = true;
    bool constantAngularVel = true;
	bool constantColor = true;


	if(bAutomaticInstancing){
		SetMaxSceneTime(ticks);
	}

	//The MAX interfaces return everything in world coordinates,
	//so we need to multiply the inverse the node world transform matrix
    Matrix3 nodeWorldTM = mMaxNode->GetObjTMAfterWSM(ticks);
    // Convert the max transform to alembic
    Matrix3 alembicMatrix;
    ConvertMaxMatrixToAlembicMatrix(nodeWorldTM, alembicMatrix);
    Abc::M44d nodeWorldTrans(	alembicMatrix.GetRow(0).x,  alembicMatrix.GetRow(0).y,  alembicMatrix.GetRow(0).z,  0,
										alembicMatrix.GetRow(1).x,  alembicMatrix.GetRow(1).y,  alembicMatrix.GetRow(1).z,  0,
										alembicMatrix.GetRow(2).x,  alembicMatrix.GetRow(2).y,  alembicMatrix.GetRow(2).z,  0,
										alembicMatrix.GetRow(3).x,  alembicMatrix.GetRow(3).y,  alembicMatrix.GetRow(3).z,  1);
	Abc::M44d nodeWorldTransInv = nodeWorldTrans.inverse();


	//ESS_LOG_WARNING("tick: "<<ticks<<"   numParticles: "<<numParticles<<"\n");

	ExoNullView nullView;
	particleGroupInterface groupInterface(particlesExt, obj, mMaxNode, &nullView);

    {
    ESS_PROFILE_SCOPE("AlembicPoints::SAVE - numParticlesLoop");

	for (int i = 0; i < numParticles; ++i)
	{
		Abc::V3f pos(0.0);
		Abc::V3f vel(0.0);
		Abc::V3f scale(1.0);
		Abc::C4f color(0.5, 0.5, 0.5, 1.0);
		float age = 0;
		Abc::uint64_t id = 0;
	    Abc::Quatd orientation(0.0, 0.0, 1.0, 0.0);
		Abc::Quatd spin(0.0, 0.0, 1.0, 0.0);
		// Particle size is a uniform scale multiplier in XSI.  In Max, I need to learn where to get this 
		// For now, we'll just default to 1
		float width = 1.0f;

		ShapeType shapetype = ShapeType_Point;
		float shapeInstanceTime = (float)time;
		Abc::uint16_t shapeInstanceId = 0;

#ifdef THINKING_PARTICLES
		if(pThinkingParticleMat){
            

			if(pTPMasterSystemInt->IsAlive(i) == FALSE){
				continue;
			}

			//TimeValue ageValue = particlesExt->GetParticleAgeByIndex(i);
			TimeValue ageValue = pTPMasterSystemInt->Age(i);
			if(ageValue == -1){
				continue;
			}

            ESS_PROFILE_SCOPE("AlembicPoints::SAVE - numParticlesLoop - ThinkingParticles");
			age = (float)GetSecondsFromTimeValue(ageValue);

			//pos = ConvertMaxPointToAlembicPoint(*particlesExt->GetParticlePositionByIndex(i));
			pos = ConvertMaxPointToAlembicPoint(pTPMasterSystemInt->Position(i));
			//vel = ConvertMaxVectorToAlembicVector(*particlesExt->GetParticleSpeedByIndex(i) * TIME_TICKSPERSEC);
			vel = ConvertMaxVectorToAlembicVector(pTPMasterSystemInt->Velocity(i) * TIME_TICKSPERSEC);
			scale = ConvertMaxScaleToAlembicScale(pTPMasterSystemInt->Scale(i));
			scale *= pTPMasterSystemInt->Size(i);
			
			//ConvertMaxEulerXYZToAlembicQuat(*particlesExt->GetParticleOrientationByIndex(i), orientation);

			Matrix3 alignmentMatMax = pTPMasterSystemInt->Alignment(i);
			Abc::M44d alignmentMat;
			ConvertMaxMatrixToAlembicMatrix(alignmentMatMax, alignmentMat);
			/*alignmentMat = Abc::M44d( alignmentMatMax.GetRow(0).x,  alignmentMatMax.GetRow(0).y,  alignmentMatMax.GetRow(0).z,  0,
                                 alignmentMatMax.GetRow(1).x,  alignmentMatMax.GetRow(1).y,  alignmentMatMax.GetRow(1).z,  0,
                                 alignmentMatMax.GetRow(2).x,  alignmentMatMax.GetRow(2).y,  alignmentMatMax.GetRow(2).z,  0,
                                 alignmentMatMax.GetRow(3).x,  alignmentMatMax.GetRow(3).y,  alignmentMatMax.GetRow(3).z,  1);*/
			//orientation = ConvertMaxQuatToAlembicQuat(extracctuat(alignmentMat), true);

			alignmentMat = alignmentMat * nodeWorldTransInv;
			orientation = extractQuat(alignmentMat);

			//ConvertMaxAngAxisToAlembicQuat(*particlesExt->GetParticleSpinByIndex(i), spin);
			ConvertMaxAngAxisToAlembicQuat(pTPMasterSystemInt->Spin(i), spin);


			id = particlesExt->GetParticleBornIndex(i);

			//seems to always return 0
			//int nPid = pThinkingParticleMat->ParticleID(i);
					
			int nMatId = -1;
			Matrix3 meshTM;
			meshTM.IdentityMatrix();
			BOOL bNeedDelete = FALSE;
			BOOL bChanged = FALSE;
            Mesh* pMesh = NULL;
            {
            ESS_PROFILE_SCOPE("AlembicPoints::SAVE - numParticlesLoop - ThinkingParticles - GetParticleRenderMesh");
			pMesh = pThinkingParticleMat->GetParticleRenderMesh(ticks, mMaxNode, nullView, bNeedDelete, i, meshTM, bChanged);
            }

			if(pMesh){
                ESS_PROFILE_SCOPE("AlembicPoints::SAVE - numParticlesLoop - ThinkingParticles - CacheShapeMesh");
            meshInfo mi = CacheShapeMesh(pMesh, bNeedDelete, meshTM, nMatId, i, ticks, shapetype, shapeInstanceId, shapeInstanceTime);
            Abc::V3d min = pos + mi.bbox.min;
            Abc::V3d max = pos + mi.bbox.max;
            bbox.extendBy(min);
            bbox.extendBy(max);
			}
			else{
				shapetype = ShapeType_Point;
			}
		}
		else 
#endif
		if(particlesExt && ipfSystem){

			TimeValue ageValue = particlesExt->GetParticleAgeByIndex(i);
			if(ageValue == -1){
				continue;
			}
			age = (float)GetSecondsFromTimeValue(ageValue);

			pos = ConvertMaxPointToAlembicPoint(*particlesExt->GetParticlePositionByIndex(i));
			vel = ConvertMaxVectorToAlembicVector(*particlesExt->GetParticleSpeedByIndex(i) * TIME_TICKSPERSEC);
			scale = ConvertMaxScaleToAlembicScale(*particlesExt->GetParticleScaleXYZByIndex(i));
			ConvertMaxEulerXYZToAlembicQuat(*particlesExt->GetParticleOrientationByIndex(i), orientation);
			ConvertMaxAngAxisToAlembicQuat(*particlesExt->GetParticleSpinByIndex(i), spin);
			//age = (float)GetSecondsFromTimeValue(particlesExt->GetParticleAgeByIndex(i));
			id = particlesExt->GetParticleBornIndex(i);
			if(bAutomaticInstancing){

				int nMatId = -1;
				if(ipfSystem){
					if( groupInterface.setCurrentParticle(ticks, i) ){
						nMatId = groupInterface.getCurrentMtlId();
					}
					else{
						ESS_LOG_WARNING("Error: cound retrieve material ID for particle mesh "<<i);
					}
				}

				Matrix3 meshTM;
				meshTM.IdentityMatrix();
				BOOL bNeedDelete = FALSE;
				BOOL bChanged = FALSE;
				Mesh* pMesh = pMesh = particlesExt->GetParticleShapeByIndex(i);

				if(pMesh){
					meshInfo mi = CacheShapeMesh(pMesh, bNeedDelete, meshTM, nMatId, i, ticks, shapetype, shapeInstanceId, shapeInstanceTime);
               Abc::V3d min = pos + mi.bbox.min;
               Abc::V3d max = pos + mi.bbox.max;
               bbox.extendBy(min);
               bbox.extendBy(max);
				}
				else{
					shapetype = ShapeType_Point;
				}
			}
			else{
				GetShapeType(particlesExt, i, ticks, shapetype, shapeInstanceId, shapeInstanceTime);
			}
			color = GetColor(particlesExt, i, ticks);
		}
		else if(pSimpleParticle){
			if( ! pSimpleParticle->parts.Alive( i ) ) {
				continue;
			}

			pos = ConvertMaxPointToAlembicPoint(pSimpleParticle->ParticlePosition(ticks, i));
			vel = ConvertMaxVectorToAlembicVector(pSimpleParticle->ParticleVelocity(ticks, i));
			//simple particles have no scale?
			//simple particles have no orientation?
			age = (float)GetSecondsFromTimeValue( pSimpleParticle->ParticleAge(ticks, i) );
			//simple particles have born index
			width = pSimpleParticle->ParticleSize(ticks, i);

         Abc::V3d min(pos.x - width/2, pos.y - width/2, pos.z - width/2);
         Abc::V3d max(pos.x + width/2, pos.y + width/2, pos.z + width/2);
         bbox.extendBy(min);
         bbox.extendBy(max);
		}

        {
        ESS_PROFILE_SCOPE("AlembicPoints::SAVE - numParticlesLoop - end loop save");

		//move everything from world space to local space
		pos = pos * nodeWorldTransInv;

		Abc::V4f vel4(vel.x, vel.y, vel.z, 0.0);
		vel4 = vel4 * nodeWorldTransInv;
		vel.setValue(vel4.x, vel4.y, vel4.z);

		//scale = scale * nodeWorldTransInv;
		//orientation = Abc::extractQuat(orientation.toMatrix44() * nodeWorldTransInv);
		//spin = Abc::extractQuat(spin.toMatrix44() * nodeWorldTransInv);

		bbox.extendBy( pos );




		positionVec.push_back( pos );
		velocityVec.push_back( vel );
		scaleVec.push_back( scale );
		widthVec.push_back( width );
		ageVec.push_back( age );
		idVec.push_back( id );
		orientationVec.push_back( orientation );
		angularVelocityVec.push_back( spin );

        shapeTypeVec.push_back( shapetype );
        shapeInstanceIDVec.push_back( shapeInstanceId );
        shapeTimeVec.push_back( shapeInstanceTime );
		colorVec.push_back( color );

		constantPos &= (pos == positionVec[0]);
		constantVel &= (vel == velocityVec[0]);
		constantScale &= (scale == scaleVec[0]);
		constantWidth &= (width == widthVec[0]);
		constantAge &= (age == ageVec[0]);
		constantOrientation &= (orientation == orientationVec[0]);
		constantAngularVel &= (spin == angularVelocityVec[0]);
		constantColor &= (color == colorVec[0]);

		// Set the archive bounding box
		// Positions for particles are already cnsider to be in world space
		if (mJob)
		{
			mJob->GetArchiveBBox().extendBy(pos);
		}

        }
	}

    }

  //  if (numParticles > 1)
  //  {
  //     ESS_PROFILE_SCOPE("AlembicPoints::Save - vectorResize");
  //      if (constantPos)        { positionVec.resize(1); }
  //      if (constantVel)        { velocityVec.resize(1); }
  //      if (constantScale)      { scaleVec.resize(1); }
  //      if (constantWidth)      { widthVec.resize(1); }
  //      if (constantAge)        { ageVec.resize(1); }
  //      if (constantOrientation){ orientationVec.resize(1); }
  //      if (constantAngularVel) { angularVelocityVec.resize(1); }
		//if (constantColor)		{ colorVec.resize(1); }
  //  }

    {
    ESS_PROFILE_SCOPE("AlembicPoints::Save - sample writing");
    // Store the information into our properties and points schema
    Abc::P3fArraySample positionSample( positionVec);
    Abc::P3fArraySample velocitySample(velocityVec);
    Abc::P3fArraySample scaleSample(scaleVec);
    Abc::FloatArraySample widthSample(widthVec);
    Abc::FloatArraySample ageSample(ageVec);
    Abc::FloatArraySample massSample(massVec);
    Abc::FloatArraySample shapeTimeSample(shapeTimeVec);
    Abc::UInt64ArraySample idSample(idVec);
    Abc::UInt16ArraySample shapeTypeSample(shapeTypeVec);
    Abc::UInt16ArraySample shapeInstanceIDSample(shapeInstanceIDVec);
    Abc::QuatfArraySample orientationSample(orientationVec);
    Abc::QuatfArraySample angularVelocitySample(angularVelocityVec);
    Abc::C4fArraySample colorSample(colorVec);  

    mScaleProperty.set(scaleSample);
    mAgeProperty.set(ageSample);
    mMassProperty.set(massSample);
    mShapeTimeProperty.set(shapeTimeSample);
    mShapeTypeProperty.set(shapeTypeSample);
    mShapeInstanceIDProperty.set(shapeInstanceIDSample);
    mOrientationProperty.set(orientationSample);
    mAngularVelocityProperty.set(angularVelocitySample);
    mColorProperty.set(colorSample);

    mPointsSample.setPositions(positionSample);
    mPointsSample.setVelocities(velocitySample);
    mPointsSample.setWidths(AbcG::OFloatGeomParam::Sample(widthSample, AbcG::kVertexScope));
    mPointsSample.setIds(idSample);
    mPointsSample.setSelfBounds(bbox);
	mPointsSchema.getChildBoundsProperty().set( bbox);

    mPointsSchema.set(mPointsSample);
    }

    mNumSamples++;

	//mInstanceNames.pop_back();

	if(bAutomaticInstancing){
		saveCurrentFrameMeshes();
	}

	if(bRenderStateForced){
		ipfSystem->SetRenderState(false);
	}

    if(bLastFrame){
       ESS_PROFILE_SCOPE("AlembicParticles::Save - save instance names property");

       std::vector<std::string> instanceNames(mNumShapeMeshes);

       for(faceVertexHashToShapeMap::iterator it = mShapeMeshCache.begin(); it != mShapeMeshCache.end(); it++){
          std::stringstream pathStream;
          pathStream << "/" << it->second.name<< "/" << it->second.name <<"Shape";
          instanceNames[it->second.nMeshInstanceId] = pathStream.str();
       }

	   //for some reason the .dims property is not written when there is exactly one entry if we don't push an empty string
	   //having an extra unreferenced entry seems to be harmless
	   instanceNames.push_back("");

       mInstanceNamesProperty.set(Abc::StringArraySample(instanceNames));
    }

    return true;
}
コード例 #5
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.");
	}

}
コード例 #6
0
//we have to save out all mesh encountered on the current frame of this object immediately, because 
//the pointers will no longer be valid when the object is evaluated at a new time
void AlembicPoints::saveCurrentFrameMeshes()
{
    ESS_PROFILE_FUNC();

	for(int i=0; i<mMeshesToSaveForCurrentFrame.size(); i++){

        //TODO: save immediately instead accumulating in a vector
		meshInfo* mi = mMeshesToSaveForCurrentFrame[i];

		if(mi->pMesh){
			Mesh* pMesh = mi->pMesh;
			//mi->pMesh = NULL;//each mesh only needs to be saved once

			//Matrix3 worldTrans;
			//worldTrans.IdentityMatrix();

			CommonOptions options;
         options.SetOption("exportNormals", mJob->GetOption("exportNormals"));
			options.SetOption("exportMaterialIds", mJob->GetOption("exportMaterialIds"));

			//gather the mesh data
			mi->meshTM.IdentityMatrix();
			IntermediatePolyMesh3DSMax finalPolyMesh;
            {
            ESS_PROFILE_SCOPE("AlembicPoints::saveCurrentFrameMeshes - finalPolyMesh.Save");

            Imath::M44f transform44f;
            ConvertMaxMatrixToAlembicMatrix( mi->meshTM, transform44f );
            SceneNodeMaxParticlesPtr inputSceneNode(new SceneNodeMaxParticles(pMesh, NULL, mi->nMatId));
            finalPolyMesh.Save(inputSceneNode, transform44f, options, 0.0);

            }

            AbcG::OPolyMeshSchema::Sample meshSample;
            AbcG::OPolyMeshSchema meshSchema;
            {
            ESS_PROFILE_SCOPE("AlembicPoints::saveCurrentFrameMeshes - save xforms, bbox, geo, topo");
			//save out the mesh xForm
			//std::string xformName = mi->name + "Xfo";
			AbcG::OXform xform(mJob->GetArchive().getTop(), mi->name, GetCurrentJob()->GetAnimatedTs());
			AbcG::OXformSchema& xformSchema = xform.getSchema();//mi->xformSchema;

			std::string meshName = mi->name + "Shape";
			AbcG::OPolyMesh mesh(xform, meshName, GetCurrentJob()->GetAnimatedTs());
			meshSchema = mesh.getSchema();

			AbcG::XformSample xformSample;

			Matrix3 alembicMatrix;
			alembicMatrix.IdentityMatrix();
			alembicMatrix.SetTrans(Point3(-10000.0f, -10000.0f, -10000.0f));
			Abc::M44d iMatrix;
			ConvertMaxMatrixToAlembicMatrix(alembicMatrix, iMatrix);

			xformSample.setMatrix(iMatrix);
			xformSchema.set(xformSample);

			//update the archive bounding box
			Abc::Box3d bbox;
			bbox.min = finalPolyMesh.bbox.min * iMatrix;
			bbox.max = finalPolyMesh.bbox.max * iMatrix;

			mJob->GetArchiveBBox().extendBy(bbox);

			//save out the mesh data			
			meshSample.setPositions(Abc::P3fArraySample(finalPolyMesh.posVec));
			meshSample.setSelfBounds(finalPolyMesh.bbox);
			meshSchema.getChildBoundsProperty().set(finalPolyMesh.bbox);

			meshSample.setFaceCounts(Abc::Int32ArraySample(finalPolyMesh.mFaceCountVec));
			meshSample.setFaceIndices(Abc::Int32ArraySample(finalPolyMesh.mFaceIndicesVec));
            }

			if(mJob->GetOption("validateMeshTopology")){
                ESS_PROFILE_SCOPE("AlembicPoints::saveCurrentFrameMeshes - validateMeshTopology");
				mJob->mMeshErrors += validateAlembicMeshTopo(finalPolyMesh.mFaceCountVec, finalPolyMesh.mFaceIndicesVec, mi->name);
			}

			if(mJob->GetOption("exportNormals")){
                ESS_PROFILE_SCOPE("AlembicPoints::saveCurrentFrameMeshes - exportNormals");
				AbcG::ON3fGeomParam::Sample normalSample;
				normalSample.setScope(AbcG::kFacevaryingScope);
				normalSample.setVals(Abc::N3fArraySample(finalPolyMesh.mIndexedNormals.values));
				normalSample.setIndices(Abc::UInt32ArraySample(finalPolyMesh.mIndexedNormals.indices));
				meshSample.setNormals(normalSample);
			}

			if(mJob->GetOption("exportMaterialIds")){
                ESS_PROFILE_SCOPE("AlembicPoints::saveCurrentFrameMeshes - exportMaterialIds");
				Abc::OUInt32ArrayProperty mMatIdProperty = 
					Abc::OUInt32ArrayProperty(meshSchema, ".materialids", meshSchema.getMetaData(), mJob->GetAnimatedTs());
				mMatIdProperty.set(Abc::UInt32ArraySample(finalPolyMesh.mMatIdIndexVec));

				for ( facesetmap_it it=finalPolyMesh.mFaceSets.begin(); it != finalPolyMesh.mFaceSets.end(); it++)
				{
					std::stringstream nameStream;
					int nMaterialId = it->first+1;
					nameStream<<it->second.name<<"_"<<nMaterialId;

					std::vector<Abc::int32_t>& faceSetVec = it->second.faceIds;

					AbcG::OFaceSet faceSet = meshSchema.createFaceSet(nameStream.str());
					AbcG::OFaceSetSchema::Sample faceSetSample(Abc::Int32ArraySample(&faceSetVec.front(), faceSetVec.size()));
					faceSet.getSchema().set(faceSetSample);
				}
			}

			if(mJob->GetOption("exportUVs")){
				//TODO...
			}

            {
            ESS_PROFILE_SCOPE("AlembicPoints::saveCurrentFrameMeshes meshSchema.set");
			meshSchema.set(meshSample);
            }

			if(mi->bNeedDelete){
				delete mi->pMesh;
				mi->bNeedDelete = FALSE;
			}
			mi->pMesh = NULL;
		}
	}
	
	mMeshesToSaveForCurrentFrame.clear();
}
コード例 #7
0
ファイル: ServerQAction.c プロジェクト: petermilne/mdsshell
int ServerQAction(int *addr, short *port, int *op, int *flags, int *jobid, 
                  void *p1, void *p2, void *p3, void *p4, void *p5, void *p6, void *p7, void *p8)
{
  int status;
  switch (*op)
  {
  case SrvRemoveLast:
  {
    status = RemoveLast();
    break;
  }
  case SrvAbort:
    {
      ServerSetDetailProc(0);
      KillThread();
      AbortJob(GetCurrentJob());
      ReleaseCurrentJob();
      SetCurrentJob(0);
      if (*(int *)p1)
      {
        SrvJob *job;
        while ((job = NextJob(0)) != 0)
          AbortJob(job);
      }
      status = StartThread();
      break;
    }
  case SrvAction:
    {

      SrvActionJob job;
      job.h.addr  = MdsGetClientAddr();
      job.h.port  = *port;
      job.h.op    = *op;
      job.h.length = sizeof(job);
      job.h.flags = *flags;
      job.h.jobid = *jobid;
      job.tree = strcpy(malloc(strlen((char *)p1)+1),(char *)p1);
      job.shot = *(int *)p2;
      job.nid = *(int *)p3;
      status = QJob((SrvJob *)&job);
      break;
    }
  case SrvClose:
    {
      SrvCloseJob job;
      job.h.addr  = MdsGetClientAddr();
      job.h.port  = *port;
      job.h.op    = *op;
      job.h.length = sizeof(job);
      job.h.flags = *flags;
      job.h.jobid = *jobid;
      status = QJob((SrvJob *)&job);
      break;
    }
  case SrvCreatePulse:
    {
      SrvCreatePulseJob job;
      job.h.addr  = MdsGetClientAddr();
      job.h.port  = *port;
      job.h.op    = *op;
      job.h.length = sizeof(job);
      job.h.flags = *flags;
      job.h.jobid = *jobid;
      job.tree = strcpy(malloc(strlen((char *)p1)+1),(char *)p1);
      job.shot = *(int *)p2;
      status = QJob((SrvJob *)&job);
      break;
    }
  case SrvSetLogging:
    {
      Logging = *(int *)p1;
      break;
    }
  case SrvCommand:
    {
      SrvCommandJob job;
      job.h.addr  = MdsGetClientAddr();
      job.h.port  = *port;
      job.h.op    = *op;
      job.h.length = sizeof(job);
      job.h.flags = *flags;
      job.h.jobid = *jobid;
      job.table = strcpy(malloc(strlen((char *)p1)+1),(char *)p1);
      job.command = strcpy(malloc(strlen((char *)p2)+1),(char *)p2);
      status = QJob((SrvJob *)&job);
      break;
    }
  case SrvMonitor:
    {
      SrvMonitorJob job;
      job.h.addr  = MdsGetClientAddr();
      job.h.port  = *port;
      job.h.op    = *op;
      job.h.length = sizeof(job);
      job.h.flags = *flags;
      job.h.jobid = *jobid;
      job.tree = strcpy(malloc(strlen((char *)p1)+1),(char *)p1);
      job.shot = *(int *)p2;
      job.phase  = *(int *)p3;
      job.nid  = *(int *)p4;
      job.on   = *(int *)p5;
      job.mode = *(int *)p6;
      job.server = strcpy(malloc(strlen((char *)p7)+1),(char *)p7);
      job.status = *(int *)p8; 
      status = QJob((SrvJob *)&job);
      break;
    }
  case SrvShow:
    {
      status = ShowCurrentJob((struct descriptor_xd *)p1);
      break;
    }
  case SrvStop:
    {
      printf("%s, Server stop requested\n",Now());
      exit(0);
      break;
    }
  }
  return status;
}