コード例 #1
0
ファイル: GeoAttributeCopier.cpp プロジェクト: Kthulhu/vfxgal
bool GeoAttributeCopier::createHandles(const attrib_copy& copy, GEO_AttributeHandle& hSrc,
	GEO_AttributeHandle& hDest)
{
	// find source attrib
	hSrc = copy.m_srcGeo->getAttribute(copy.m_srcDict, copy.m_srcName.c_str());
	if(!hSrc.isAttributeValid())
		return false;

	const char* destName_ = copy.m_destName.c_str();
	const GB_Attribute* srcAttrib = hSrc.getAttribute();
	assert(srcAttrib);

	// create attrib if it doesn't exist, or does but data type doesn't match
	bool createAttrib = true;
	GEO_AttributeHandle hExist = m_destGeo.getAttribute(copy.m_destDict, destName_);
	if(hExist.isAttributeValid())
	{
		const GB_Attribute* destAttrib = hExist.getAttribute();
		assert(destAttrib);
		createAttrib = (destAttrib->getType() != srcAttrib->getType());
	}

	if(createAttrib)
	{
		GB_AttributeRef aref = m_destGeo.addAttribute(destName_, srcAttrib->getSize(),
			srcAttrib->getType(), srcAttrib->getDefault(), copy.m_destDict);

		if(!aref.isValid())
			return false;
	}

	hDest = m_destGeo.getAttribute(copy.m_destDict, destName_);
	hDest.setSourceMap(hSrc);
	return true;
}
コード例 #2
0
FromHoudiniGeometryConverter::Convertability FromHoudiniPolygonsConverter::canConvert( const GU_Detail *geo )
{
	const GA_PrimitiveList &primitives = geo->getPrimitiveList();
	
	for ( GA_Iterator it=geo->getPrimitiveRange().begin(); !it.atEnd(); ++it )
	{
		const GA_Primitive *prim = primitives.get( it.getOffset() );
		if ( prim->getTypeId() != GEO_PRIMPOLY )
		{
			return Inapplicable;
		}
	}
	
	// is there a single named shape?
	const GEO_AttributeHandle attrHandle = geo->getPrimAttribute( "name" );
	if ( attrHandle.isAttributeValid() )
	{
		const GA_ROAttributeRef attrRef( attrHandle.getAttribute() );
		if ( geo->getUniqueValueCount( attrRef ) < 2 )
		{
			return Ideal;
		}
	}
	
	return Suitable;
}
コード例 #3
0
FromHoudiniGeometryConverter::Convertability FromHoudiniCurvesConverter::canConvert( const GU_Detail *geo )
{
	const GA_PrimitiveList &primitives = geo->getPrimitiveList();
	
	unsigned numPrims = geo->getNumPrimitives();
	GA_Iterator firstPrim = geo->getPrimitiveRange().begin();
	if ( !numPrims || !compatiblePrimitive( primitives.get( firstPrim.getOffset() )->getTypeId() ) )
	{
		return Inapplicable;
	}
	
	const GEO_Curve *firstCurve = (const GEO_Curve*)primitives.get( firstPrim.getOffset() );
	bool periodic = firstCurve->isClosed();
	unsigned order = firstCurve->getOrder();
	
	for ( GA_Iterator it=firstPrim; !it.atEnd(); ++it )
	{
		const GA_Primitive *prim = primitives.get( it.getOffset() );
		if ( !compatiblePrimitive( prim->getTypeId() ) )
		{
			return Inapplicable;
		}
		
		const GEO_Curve *curve = (const GEO_Curve*)prim;
		if ( curve->getOrder() != order )
		{
			return Inapplicable;
		}
		
		if ( curve->isClosed() != periodic )
		{
			return Inapplicable;
		}
	}
	
	// is there a single named shape?
	const GEO_AttributeHandle attrHandle = geo->getPrimAttribute( "name" );
	if ( attrHandle.isAttributeValid() )
	{
		const GA_ROAttributeRef attrRef( attrHandle.getAttribute() );
		if ( geo->getUniqueValueCount( attrRef ) < 2 )
		{
			return Ideal;
		}
	}
	
	return Suitable;
}
コード例 #4
0
void IECoreMantra::ProceduralPrimitive::addVisibleRenderable( VisibleRenderablePtr renderable )
{
	ToHoudiniGeometryConverterPtr converter = ToHoudiniGeometryConverter::create( renderable );
	if( !converter ) 
	{
		msg( Msg::Warning, "ProceduralPrimitive::addVisibleRenderable", "converter could not be found" );
		return;
	}
	GU_Detail *gdp = allocateGeometry();
	GU_DetailHandle handle;
	handle.allocateAndSet( (GU_Detail*)gdp, false );
	bool converted = converter->convert( handle );
	if ( !converted )
	{
		msg( Msg::Warning, "ProceduralPrimitive::addVisibleRenderable", "converter failed" );
		return;
	}
	/// \todo ToHoudiniGeometryConverter does not create a Houdini style uv attribute.
	/// We make one from s and t. This code should probably live in a converter or in an Op that
	/// remaps IECore conventions to common Houdini ones.
	MeshPrimitivePtr mesh = runTimeCast<MeshPrimitive> (renderable);
	if ( mesh )
	{
		gdp->addTextureAttribute( GA_ATTRIB_VERTEX );
		GEO_AttributeHandle auv = gdp->getAttribute( GA_ATTRIB_VERTEX, "uv" );
		GEO_AttributeHandle as = gdp->getAttribute( GA_ATTRIB_VERTEX, "s" );
		GEO_AttributeHandle at = gdp->getAttribute( GA_ATTRIB_VERTEX, "t" );
		if ( auv.isAttributeValid() && as.isAttributeValid() && at.isAttributeValid() )
		{
			GA_GBPrimitiveIterator it( *gdp );
			GA_Primitive *p = it.getPrimitive();
			while ( p )
			{
				for (int i = 0; i < p->getVertexCount(); ++i)
				{
					GA_Offset v = p->getVertexOffset(i);
					as.setVertex(v);
					at.setVertex(v);
					auv.setVertex(v);
					auv.setF( as.getF(0), 0 );
					auv.setF( ((at.getF(0) * -1.0f) + 1.0f), 1 ); // wat, t arrives upside down for some reason.
					auv.setF( 0.0f, 2 );
				}
				++it;
				p = it.getPrimitive();
			}
		}
	}

	if ( m_renderer->m_motionType == RendererImplementation::Geometry )
	{
		msg(Msg::Debug, "IECoreMantra::ProceduralPrimitive::addVisibleRenderable", "MotionBlur:Geometry" );
		if ( !m_renderer->m_motionTimes.empty() )
		{
			if ( (size_t)m_renderer->m_motionSize == m_renderer->m_motionTimes.size() )
			{
				openGeometryObject();
			}
			addGeometry(gdp, m_renderer->m_motionTimes.front());
			m_renderer->m_motionTimes.pop_front();
			if ( m_renderer->m_motionTimes.empty() )
			{
				applySettings();
				closeObject();
			}
		}
	}
	else if ( m_renderer->m_motionType == RendererImplementation::ConcatTransform ||
			  m_renderer->m_motionType == RendererImplementation::SetTransform )
	{
		// It isn't clear that this will give correct results. 
		// ConcatTransform may need to interpolate transform snapshots.
		msg(Msg::Debug, "IECoreMantra::ProceduralPrimitive::addVisibleRenderable", "MotionBlur:Transform" );
		openGeometryObject();
			addGeometry(gdp, 0.0f);
			while ( !m_renderer->m_motionTimes.empty() )
			{
				setPreTransform( convert< UT_Matrix4T<float> >(m_renderer->m_motionTransforms.front()),
								 m_renderer->m_motionTimes.front() );
				m_renderer->m_motionTimes.pop_front();
				m_renderer->m_motionTransforms.pop_front();
			}
			applySettings();
		closeObject();
		m_renderer->m_motionType = RendererImplementation::Unknown;
	}
	else if ( m_renderer->m_motionType == RendererImplementation::Velocity )
	{
		msg(Msg::Debug, "IECoreMantra::ProceduralPrimitive::addVisibleRenderable", "MotionBlur:Velocity" );
		openGeometryObject();
			addGeometry(gdp, 0.0f);
			addVelocityBlurGeometry(gdp, m_preBlur, m_postBlur);
			applySettings();
		closeObject();
		m_renderer->m_motionType = RendererImplementation::Unknown;
	}
	else
	{
		msg(Msg::Debug, "IECoreMantra::ProceduralPrimitive::addVisibleRenderable", "MotionBlur:None" );
		openGeometryObject();
			addGeometry( gdp, 0.0f );
			setPreTransform( convert< UT_Matrix4T<float> >(m_renderer->m_transformStack.top()), 0.0f);
			applySettings();
		closeObject();
	}
}
コード例 #5
0
ファイル: empload.C プロジェクト: chunkified/Naiad-Buddies
Geo2Emp::ErrorCode Geo2Emp::loadMeshShape( const Nb::Body* pBody )
{	
	if (!_gdp)
	{
		//If we don't have a GDP for writing data into Houdini, return error.
		return EC_NULL_WRITE_GDP;
	}

	LogInfo() << "=============== Loading mesh shape ===============" << std::endl; 

	const Nb::TriangleShape* pShape;

	pShape = pBody->queryConstTriangleShape();

	if (!pShape)
	{
		//NULL mesh shape, so return right now.
		return EC_NO_TRIANGLE_SHAPE;
	}

	//Get access to shapes we need to loading a mesh (point and triangle)
	const Nb::TriangleShape& triShape = pBody->constTriangleShape();
	const Nb::PointShape& ptShape = pBody->constPointShape();

	//Retrieve the number of points and channels
	int64_t size = ptShape.size();
	int channelCount = ptShape.channelCount();

	//Attribute Lookup Tables
	std::vector< GEO_AttributeHandle > attribLut;
	std::vector<GeoAttributeInfo> attribInfo; //houdini types for the naiad channels.
	GeoAttributeInfo* pInfo;
	GEO_AttributeHandle attr;
	std::string attrName;

	float zero3f[3] = {0,0,0};
	float zero1f = 0;
	int zero3i[3] = {0,0,0};
	int zero1i = 0;
	const void* data;

	attribLut.clear();
	attribInfo.clear();
	attribLut.resize( channelCount );
	attribInfo.resize( channelCount );

	//Prepare for a blind copy of Naiad channels to Houdini attributes.
	//Iterate over the channels and create the corresponding attributes in the GDP
	for (int i = 0; i < channelCount; i++)
	{
		//std::cout << "channel: " << i << std::endl;
		const Nb::ChannelCowPtr& chan = ptShape.channel(i);

		if ( _empAttribMangle.find( chan->name() ) != _empAttribMangle.end() )
			attrName = _empAttribMangle[ chan->name() ];
		else
			attrName = chan->name();

		LogDebug() << "Processing EMP Channel: " << chan->name() << "; mangled: " << attrName << std::endl;

		//Determine the attribute type, and store it
		pInfo = &(attribInfo[ i ]);
		pInfo->supported = false;
		pInfo->size = 0;
		pInfo->use64 = false;

		switch ( chan->type() )
		{
			case Nb::ValueBase::IntType:
				LogDebug() << "IntType " << std::endl;
				pInfo->type = GB_ATTRIB_INT;
				pInfo->entries = 1;
				pInfo->size = sizeof(int);
				pInfo->supported = true;
				data = &zero1i;
				break;
			case Nb::ValueBase::Int64Type: //NOTE: This might need to be handled differently ... just remember this 'hack'
				pInfo->type = GB_ATTRIB_INT;
				pInfo->entries = 1;
				pInfo->size = sizeof(int);
				pInfo->supported = true;
				data = &zero1i;
				break;
			case Nb::ValueBase::FloatType:
				LogDebug() << "FloatType " << std::endl;
				pInfo->type = GB_ATTRIB_FLOAT;
				pInfo->size = sizeof(float);
				pInfo->entries = 1;
				pInfo->supported = true;
				data = &zero1f;
				break;
			case Nb::ValueBase::Vec3fType:
				LogDebug() << "Vec3fType " << std::endl;
				pInfo->type = GB_ATTRIB_VECTOR;
				pInfo->size = sizeof(float);
				pInfo->entries = 3;
				pInfo->supported = true;
				data = &zero3f;
				break;
			default:
				pInfo->supported = false;
				break;
		}

		//If the attribute is not supported, then continue with the next one.
		if (!pInfo->supported)
		{
			LogVerbose() << "Unsupported attribute. Skipping:" << attrName << std::endl;
			continue;
		}

		//Check whether the attribute exists or not
		attr = _gdp->getPointAttribute( attrName.c_str() );
		if ( !attr.isAttributeValid() )
		{
			LogDebug() << "Creating attribute in GDP:" << attrName << std::endl;
			_gdp->addPointAttrib( attrName.c_str(), pInfo->size * pInfo->entries, pInfo->type, data);
			attr = _gdp->getPointAttribute( attrName.c_str() );
		}

		//Put the attribute handle in a Lut for easy access later (during transfer)
		attribLut[i] = attr;
	}	

	//Get index buffer from the triangle shape
	const Nb::Buffer3i& bufIndex ( triShape.constBuffer3i("index") );
	int64_t indexBufSize = bufIndex.size();

	//Before we start adding points to the GDP, just record how many points are already there.
	int initialPointCount = _gdp->points().entries();	

	GEO_Point *ppt;
	//Now, copy all the points into the GDP.
	for (int ptNum = 0; ptNum < ptShape.size(); ptNum ++)
	{
		ppt = _gdp->appendPoint();
		
		//Iterate over the channels in the point shape and copy the data
		for (int channelIndex = 0; channelIndex < channelCount; channelIndex++)
		{
			pInfo = &(attribInfo[ channelIndex ]);
			//If the attribute is not supported then skip it
			if (!pInfo->supported)
			{
				continue;
			}

			attribLut[ channelIndex ].setElement( ppt );

			//Transfer supported attributes (this includes the point Position)
			switch ( pInfo->type )
			{
				case GB_ATTRIB_INT:
					{
						const Nb::Buffer1i& channelData =  ptShape.constBuffer1i(channelIndex);
						//Get the Houdini point attribute using the name list we built earlier.
						attribLut[channelIndex].setI( channelData(ptNum) );
					}
					break;
				case GB_ATTRIB_FLOAT:
					{
						//TODO: Handle more that 1 entry here, if we ever get something like that ... although I doubt it would happen.
						const Nb::Buffer1f& channelData( ptShape.constBuffer1f(channelIndex) );
						//Get the Houdini point attribute using the name list we built earlier.
						attribLut[channelIndex].setF( channelData(ptNum) );
					}
					break;
				case GB_ATTRIB_VECTOR:
					{
						const Nb::Buffer3f& channelData = ptShape.constBuffer3f(channelIndex);
						//Get the Houdini point attribute using the name list we built earlier.
						attribLut[channelIndex].setV3( UT_Vector3( channelData(ptNum)[0], channelData(ptNum)[1], channelData(ptNum)[2]  ) );
					}
					break;
				default:
					//not yet implemented.
					continue;
					break;
			}

		}

	}

	//Now that all the points are in the GDP, build the triangles
	GU_PrimPoly *pPrim;
	for (int tri = 0; tri < indexBufSize; tri++)
	{
		pPrim = GU_PrimPoly::build(_gdp, 3, GU_POLY_CLOSED, 0); //Build a closed poly with 3 points, but don't add them to the GDP.
		//Set the three vertices of the triangle
		for (int i = 0; i < 3; i++ )
		{
			pPrim->setVertex(i, _gdp->points()[ initialPointCount + bufIndex(tri)[i] ] );
		}
	}

	return EC_SUCCESS;
}
コード例 #6
0
ファイル: empload.C プロジェクト: chunkified/Naiad-Buddies
Geo2Emp::ErrorCode Geo2Emp::loadParticleShape( const Nb::Body* pBody )
{
	if (!_gdp)
	{
		//If we don't have a GDP for writing data into Houdini, return error.
		return EC_NULL_WRITE_GDP;
	}

	const Nb::ParticleShape* pShape;

	LogInfo() << "=============== Loading particle shape ===============" << std::endl; 

	pShape = pBody->queryConstParticleShape();

	if (!pShape)
	{
		//std::cout << "Received NULL particle shape!" << std::endl;
		return EC_NO_PARTICLE_SHAPE;
	}

	//Attribute Lookup Tables
	std::vector< GEO_AttributeHandle > attribLut;
	std::vector<GeoAttributeInfo> attribInfo; //houdini types for the naiad channels.
	GeoAttributeInfo* pInfo;
	std::string attrName;

	//We have a valid particle shape. Start copying particle data over to the GDP
	int64_t size = pShape->size();
	int channelCount = pShape->channelCount();
	GEO_Point *ppt;
	GEO_AttributeHandle attr;
	GU_PrimParticle *pParticle;
	std::vector<std::string> houdiniNames; //houdini names that correspond to naiad channels.
	std::vector<GB_AttribType> houdiniTypes; //houdini types for the naiad channels.
	//Default values for attributes
	float zero3f[3] = {0,0,0};
	float zero1f = 0;
	//int zero3i[3] = {0,0,0};
	int zero1i = 0;
	const void* data;

	LogVerbose() << "Particle shape size: " << size << std::endl;
	LogVerbose() << "Particle shape channel count: " << channelCount << std::endl;

	LogVerbose() << "Building particle primitive...";
	pParticle = GU_PrimParticle::build(_gdp, 0);
	LogVerbose() << "done." << std::endl;

	attribLut.clear();
	attribInfo.clear();
	attribLut.resize( channelCount );
	attribInfo.resize( channelCount );

	//Prepare for a blind copy of Naiad channels to Houdini attributes.
	//Iterate over the channels and create the corresponding attributes in the GDP
	for (int i = 0; i < channelCount; i++)
	{
		//std::cout << "channel: " << i << std::endl;
		const Nb::ChannelCowPtr& chan = pShape->channel(i);

		if ( _empAttribMangle.find( chan->name() ) != _empAttribMangle.end() )
			attrName = _empAttribMangle[ chan->name() ];
		else
			attrName = chan->name();

		LogDebug() << "Processing EMP Channel: " << chan->name() << "; mangled: " << attrName << std::endl;

		//Determine the attribute type, and store it
		pInfo = &(attribInfo[ i ]);
		pInfo->supported = false;
		pInfo->size = 0;
		pInfo->use64 = false;

		if (attrName.compare("P") == 0)
			//Don't treat position as an attribute. This needs to be handled separately.
			continue;

		switch ( chan->type() )
		{
			case Nb::ValueBase::IntType:
				pInfo->type = GB_ATTRIB_INT;
				pInfo->entries = 1;
				pInfo->size = sizeof(int);
				pInfo->supported = true;
				data = &zero1i;
				break;			
			case Nb::ValueBase::Int64Type: //NOTE: This might need to be handled differently ... just remember this 'hack'
				pInfo->type = GB_ATTRIB_INT;
				pInfo->entries = 1;
				pInfo->size = sizeof(int);
				pInfo->supported = true;
				pInfo->use64 = true;
				data = &zero1i;
				break;
			case Nb::ValueBase::FloatType:
				pInfo->type = GB_ATTRIB_FLOAT;
				pInfo->size = sizeof(float);
				pInfo->entries = 1;
				pInfo->supported = true;
				data = &zero1f;
				break;
			case Nb::ValueBase::Vec3fType:
				pInfo->type = GB_ATTRIB_VECTOR;
				pInfo->size = sizeof(float);
				pInfo->entries = 3;
				pInfo->supported = true;
				data = &zero3f;
				break;
			default:
				pInfo->supported = false;
				break;
		}

		//If the attribute is not supported, then continue with the next one.
		if (!pInfo->supported)
		{
			LogVerbose() << "Unsupported attribute. Skipping:" << attrName << std::endl;
			continue;
		}

		//Check whether the attribute exists or not
		attr = _gdp->getPointAttribute( attrName.c_str() );
		if ( !attr.isAttributeValid() )
		{
			LogVerbose() << "Creating attribute in GDP:" << attrName << std::endl;
			LogDebug() << "Name: " << attrName << std::endl << "Entries: " << pInfo->entries << std::endl << "Size: " << pInfo->size << std::endl;
			_gdp->addPointAttrib( attrName.c_str(), pInfo->size * pInfo->entries, pInfo->type, data);
			attr = _gdp->getPointAttribute( attrName.c_str() );
		}

		//Put the attribute handle in a Lut for easy access later.
		attribLut[i] = attr;
	}	

	//The channel values for particle shapes are stored in blocks/tiles.
	unsigned int absPtNum = 0;

	//Get the block array for the positions channel
	const em::block3_array3f& positionBlocks( pShape->constBlocks3f("position") );	
	unsigned int numBlocks = positionBlocks.block_count();
	unsigned int bsize;
	float dec_accumulator = 0.0f;
	float dec = (1.0f - (_decimation)/100.0f);
	LogInfo() << "Keeping decimation value: " << dec << std::endl;

	for (int blockIndex = 0; blockIndex < numBlocks; blockIndex ++)
	{
		//if (ptNum % 100 == 0)
		//Get a single block from the position blocks
		const em::block3vec3f& posBlock = positionBlocks(blockIndex);

		if ( blockIndex % 100 == 0 )
			LogDebug() << "Block: " << blockIndex << "/" << numBlocks << std::endl;
		//Iterate over all the points/particles in the position block
		bsize = posBlock.size();

		//Only process the point if the decimation accumulator is greater than one.

		for (int ptNum = 0; ptNum < bsize; ptNum++, absPtNum++)
		{
			dec_accumulator += dec;
			if (dec_accumulator < 1.0f)
				//Skip this point
				continue;
			//Process this point, remove the dec_accumulator rollover.
			dec_accumulator -= (int) dec_accumulator;

			ppt = _gdp->appendPoint();
			pParticle->appendParticle(ppt);

			ppt->setPos( UT_Vector3( posBlock(ptNum)[0], posBlock(ptNum)[1], posBlock(ptNum)[2] ) );
			
			//Loop over the channels and add the attributes
			//This loop needs to be as fast as possible.
			for (int channelIndex = 0; channelIndex < channelCount; channelIndex++)
			{
				pInfo = &(attribInfo[ channelIndex ]);
				//If the attribute is not supported then skip it
				if (!pInfo->supported)
				{
					continue;
				}

				attribLut[ channelIndex ].setElement( ppt );

				switch ( pInfo->type )
				{
					case GB_ATTRIB_INT:
						{
							if (pInfo->use64)
							{
								const em::block3i64& channelData( pShape->constBlocks1i64(channelIndex)(blockIndex) );
								//Get the Houdini point attribute using the name list we built earlier.
								attribLut[channelIndex].setI( channelData(ptNum) );
							}
							else
							{
								const em::block3i& channelData( pShape->constBlocks1i(channelIndex)(blockIndex) );
								//Get the Houdini point attribute using the name list we built earlier.
								attribLut[channelIndex].setI( channelData(ptNum) );
							}
						}
						break;
					case GB_ATTRIB_FLOAT:
						{
							//TODO: Handle more that 1 entry here, if we ever get something like that ... although I doubt it would happen.
							const em::block3f& channelData( pShape->constBlocks1f(channelIndex)(blockIndex) );
							//Get the Houdini point attribute using the name list we built earlier.
							attribLut[channelIndex].setF( channelData(ptNum) );
						}
						break;
					case GB_ATTRIB_VECTOR:
						{
							const em::block3vec3f& channelData( pShape->constBlocks3f(channelIndex)(blockIndex) );
							//Get the Houdini point attribute using the name list we built earlier.
							attribLut[channelIndex].setV3( UT_Vector3( channelData(ptNum)[0], channelData(ptNum)[1], channelData(ptNum)[2]  ) );
						}
						break;
					default:
						//not yet implemented.
						continue;
						break;
				}

			}
		}	
	}

	//std::cout << "all done. " << std::endl;
	return EC_SUCCESS;
}
コード例 #7
0
FromHoudiniGeometryConverter::Convertability FromHoudiniGroupConverter::canConvert( const GU_Detail *geo )
{
	const GA_PrimitiveList &primitives = geo->getPrimitiveList();
	
	// are there multiple primitives?
	unsigned numPrims = geo->getNumPrimitives();
	if ( numPrims < 2 )
	{
		return Admissible;
	}
	
	// are there mixed primitive types?
	GA_Iterator firstPrim = geo->getPrimitiveRange().begin();
	GA_PrimitiveTypeId firstPrimId = primitives.get( firstPrim.getOffset() )->getTypeId();
	for ( GA_Iterator it=firstPrim; !it.atEnd(); ++it )
	{
		if ( primitives.get( it.getOffset() )->getTypeId() != firstPrimId )
		{
			return Ideal;
		}
	}
	
	// are there multiple named shapes?
	const GEO_AttributeHandle attrHandle = geo->getPrimAttribute( "name" );
	if ( attrHandle.isAttributeValid() )
	{
		const GA_ROAttributeRef attrRef( attrHandle.getAttribute() );
		if ( geo->getUniqueValueCount( attrRef ) > 1 )
		{
			return Ideal;
		}
	}
	
	// are the primitives split into groups?
	UT_PtrArray<const GA_ElementGroup*> primGroups;
	geo->getElementGroupList( GA_ATTRIB_PRIMITIVE, primGroups );
	if ( primGroups.isEmpty() )
	{
		return Admissible;
	}
	
	bool externalGroups = false;
	for ( unsigned i=0; i < primGroups.entries(); ++i )
	{
		const GA_ElementGroup *group = primGroups[i];
		if ( group->getInternal() )
		{
			continue;
		}
		
		if ( group->entries() == numPrims )
		{
			return Admissible;
		}
		
		externalGroups = true;
	}
	
	if ( externalGroups )
	{
		return Ideal;
	}
	
	return Admissible;
}
コード例 #8
0
void Geo2Emp::transferParticlePointAttribs(int numAttribs, GEO_AttributeHandleList& attribList, std::map<int, AttributeInfo>& attrLut, Nb::ParticleShape& shape, const GEO_Point* ppt)
{
	GEO_AttributeHandle* pAttr;
	AttributeInfo* pAttrInfo;

	for (int i = 0; i < numAttribs; i++)
	{
		pAttr = attribList[i];
		pAttrInfo = &( attrLut[i] );

		if (!pAttrInfo->supported)
			//Skip unsupported attributes
			continue;

		pAttr->setElement( ppt );
		if (! pAttr->isAttributeValid() )
		{
			LogDebug() << "Invalid attribute handle on supported attribute!! [" << pAttr->getName() << "]" << std::endl;
		}

		LogDebug() << "Transferring attribute: " << pAttr->getName() << std::endl;

		switch ( pAttrInfo->type )
		{
			case GB_ATTRIB_FLOAT:
				//LogDebug() << "Transfer Float" << pAttrInfo->entries << "[" << pAttr->getName() << "]" << std::endl;
				switch ( pAttrInfo->entries )
				{
					case 1:
						{
							//LogDebug() << "Float1: " << pAttr->getV3() << std::endl;
							//Get the channel from the point shape
							em::block3_array1f& vecData = shape.mutableBlocks1f( pAttrInfo->empIndex );
							//Write the data into the buffer
							vecData(0).push_back( pAttr->getF() );
						}
						break;
					case 3:
						{
							LogDebug() << "Float3: " << pAttr->getV3() << std::endl;
							//Get the channel from the particle shape
							em::block3_array3f& vecData = shape.mutableBlocks3f( pAttrInfo->empIndex );
							//Write the data into the buffer
							vecData(0).push_back( em::vec3f( pAttr->getF(0), pAttr->getF(1), pAttr->getF(2) ) );
						}
						break;
				}
				break;
			case GB_ATTRIB_INT:
				LogDebug() << "Int " << pAttrInfo->entries << std::endl;
				switch ( pAttrInfo->entries )
				{
					case 1:
						{
							//LogDebug() << "Float1: " << pAttr->getV3() << std::endl;
							//Get the channel from the point shape
							em::block3_array1i& vecData = shape.mutableBlocks1i( pAttrInfo->empIndex );
							//Write the data into the buffer
							vecData(0).push_back( pAttr->getI() );
						}
						break;
					case 3:
						{
							LogDebug() << "Int3: " << std::endl;
							//Get the channel from the particle shape
							em::block3_array3i& vecData = shape.mutableBlocks3i( pAttrInfo->empIndex );
							//Write the data into the buffer
							vecData(0).push_back( em::vec3i( pAttr->getI(0), pAttr->getI(1), pAttr->getI(2) ) );
						}
						break;
				}
				break;
			case GB_ATTRIB_VECTOR:
				{
					//LogDebug() << "Transfer Vector3 [" << pAttr->getName() << "] " <<  pAttr->getF(0) << "," << pAttr->getF(1) << "," << pAttr->getF(2)<< std::endl;
					//If we have a vector, we need to invert it (reverse winding).
					em::block3_array3f& vecData = shape.mutableBlocks3f( pAttrInfo->empIndex );
					//Write the data into the buffer
					vecData(0).push_back( em::vec3f( pAttr->getF(0), pAttr->getF(1), pAttr->getF(2) ) );
					break;
				}
			case GB_ATTRIB_MIXED:
			case GB_ATTRIB_INDEX:
			default:
				//Unsupported attribute, so give it a skip.
				LogDebug() << " !!!!! SHOULDNT GET THIS !!!! Unsupported attribute type for blind copy [" << pAttrInfo->type << "]" << std::endl;
				continue;
				break;
		}

	}

}