void FromHoudiniGroupConverter::doUnnamedConversion( const GU_Detail *geo, Group *result, const CompoundObject *operands, const std::string &name ) const
{
	GU_Detail newGeo( (GU_Detail*)geo );
	GA_PrimitiveGroup *newGroup = static_cast<GA_PrimitiveGroup*>( newGeo.createInternalElementGroup( GA_ATTRIB_PRIMITIVE, "FromHoudiniGroupConverter__doUnnamedConversion" ) );
	newGroup->toggleRange( newGeo.getPrimitiveRange() );
	
	VisibleRenderablePtr renderable = 0;
	doGroupConversion( &newGeo, newGroup, renderable, operands );
	if ( renderable )
	{
		if ( Group *group = IECore::runTimeCast<Group>( renderable ) )
		{
			const Group::ChildContainer &children = group->children();
			for ( Group::ChildContainer::const_iterator it = children.begin(); it != children.end(); ++it )
			{
				if ( name != "" )
				{
					(*it)->blindData()->member<StringData>( "name", false, true )->writable() = name;
				}
				
				result->addChild( *it );
			}
		}
		else
		{
			if ( name != "" )
			{
				renderable->blindData()->member<StringData>( "name", false, true )->writable() = name;
			}
			
			result->addChild( renderable );
		}
	}
}
void SOP_groupAsAttr::groupToAttrPrims(const UT_String& in_attr, const int& debug_in)
{

    groupNameIndex = gdp->findStringTuple(GA_ATTRIB_PRIMITIVE, in_attr);

    if(groupNameIndex.isInvalid())
    {
        groupNameIndex = gdp->addStringTuple(GA_ATTRIB_PRIMITIVE, in_attr, 1);
        if(groupNameIndex.isInvalid())
        {
            addError(SOP_ATTRIBUTE_INVALID, "Unable to create primitive attribut");

        }
    }


    //iterate thru all the points and for every point iterate thru all the groups
    GA_Primitive *prim;
    GA_FOR_ALL_PRIMITIVES(gdp, prim)
    {
        bool exist = false;

        //set our current group
        GA_PrimitiveGroup *curGrp;
        //for all the point groups
        GA_FOR_ALL_PRIMGROUPS(gdp, curGrp)
        {
            if(curGrp)
            {
                if(exist == false)
                {
                    if(curGrp->contains(*prim))
                    {
                        prim->setString(groupNameIndex, curGrp->getName());
                        exist = true;
                    }
                    else
                    {
                        prim->setString(groupNameIndex, "no group");
                    }
                }
            }
        }
    }
예제 #3
0
bool SOP_SceneCacheSource::convertObject( const IECore::Object *object, const std::string &name, const SceneInterface *scene, Parameters &params )
{
	ToHoudiniGeometryConverterPtr converter = nullptr;
	if ( params.geometryType == Cortex )
	{
		converter = new ToHoudiniCortexObjectConverter( object );
	}
	else
	{
		const VisibleRenderable *renderable = IECore::runTimeCast<const VisibleRenderable>( object );
		if ( !renderable )
		{
			return false;
		}

		converter = ToHoudiniGeometryConverter::create( renderable );
	}

	if ( !converter )
	{
		return false;
	}

	// we need to set the name regardless of whether
	// we're reusing prims or doing the full conversion
	// because this parameter can have an affect in
	// transferAttribs() as well as convert()
	converter->nameParameter()->setTypedValue( name );

	// check the primitve range map to see if this shape exists already
	std::map<std::string, GA_Range>::iterator rIt = params.namedRanges.find( name );
	if ( rIt != params.namedRanges.end() && !rIt->second.isEmpty() )
	{
		GA_Range primRange = rIt->second;
		const Primitive *primitive = IECore::runTimeCast<const Primitive>( object );
		if ( primitive && !params.hasAnimatedTopology && params.hasAnimatedPrimVars )
		{
			// this means constant topology and primitive variables, even though multiple samples were written
			if ( params.animatedPrimVars.empty() )
			{
				return true;
			}

			GA_Range pointRange( *gdp, primRange, GA_ATTRIB_POINT, GA_Range::primitiveref(), false );

			// update the animated primitive variables only
			std::string animatedPrimVarStr = "";
			for ( std::vector<InternedString>::const_iterator it = params.animatedPrimVars.begin(); it != params.animatedPrimVars.end(); ++it )
			{
				animatedPrimVarStr += it->string() + " ";
			}

			converter->attributeFilterParameter()->setTypedValue( animatedPrimVarStr );

			try
			{
				converter->transferAttribs( gdp, pointRange, primRange );
				return true;
			}
			catch ( std::exception &e )
			{
				addWarning( SOP_MESSAGE, e.what() );
				return false;
			}
			catch ( ... )
			{
				addWarning( SOP_MESSAGE, "Attribute transfer failed for unknown reasons" );
				return false;
			}
		}
		else
		{
			// topology is changing, so destroy the exisiting primitives
			gdp->destroyPrimitives( primRange, true );
		}
	}

	// fallback to full conversion
	converter->attributeFilterParameter()->setTypedValue( params.attributeFilter );

	try
	{
		GA_Offset firstNewPrim = gdp->getPrimitiveMap().lastOffset() + 1;

		bool status = converter->convert( myGdpHandle );

		// adds the full path in addition to the relative name
		const GA_IndexMap &primMap = gdp->getPrimitiveMap();
		GA_Range newPrims( primMap, firstNewPrim, primMap.lastOffset() + 1 );

		if ( params.fullPathName != "" )
		{
			if ( newPrims.isValid() )
			{
				std::string fullName;
				SceneInterface::Path path;
				scene->path( path );
				SceneInterface::pathToString( path, fullName );

				GA_RWAttributeRef pathAttribRef = ToHoudiniStringVectorAttribConverter::convertString( params.fullPathName, fullName, gdp, newPrims );
				status = status && pathAttribRef.isValid();
			}
		}

		if ( params.tagGroups )
		{
			static UT_StringMMPattern convertTagFilter;
			if( convertTagFilter.isEmpty() )
			{
				convertTagFilter.compile( "ObjectType:*" );
			}
			SceneInterface::NameList tags;
			scene->readTags( tags, IECoreScene::SceneInterface::LocalTag );
			for ( SceneInterface::NameList::const_iterator it=tags.begin(); it != tags.end(); ++it )
			{
				UT_String tag( *it );
				// skip this tag because it's used behind the scenes
				if ( tag.multiMatch( convertTagFilter ) )
				{
					continue;
				}

				// replace this special character found in SCC tags that will prevent the group from being created
				tag.substitute(":", "_");

				tag.prepend("ieTag_");

				GA_PrimitiveGroup *group = gdp->findPrimitiveGroup(tag);
				if ( !group )
				{
					group = gdp->newPrimitiveGroup(tag);
				}
				group->addRange(newPrims);
			}
		}

		return status;
	}
	catch ( std::exception &e )
	{
		addWarning( SOP_MESSAGE, e.what() );
		return false;
	}
	catch ( ... )
	{
		addWarning( SOP_MESSAGE, "Conversion failed for unknown reasons" );
		return false;
	}
}
예제 #4
0
void HoudiniScene::readTags( NameList &tags, bool includeChildren ) const
{
	tags.clear();
	
	const OP_Node *node = retrieveNode();
	if ( !node )
	{
		return;
	}
	
	// add user supplied tags if we're not inside a SOP
	if ( !m_contentIndex && node->hasParm( pTags.getToken() ) )
	{
		UT_String parmTagStr;
		node->evalString( parmTagStr, pTags.getToken(), 0, 0 );
		if ( !parmTagStr.equal( UT_String::getEmptyString() ) )
		{
			UT_WorkArgs tokens;
			parmTagStr.tokenize( tokens, " " );
			for ( int i = 0; i < tokens.getArgc(); ++i )
			{
				tags.push_back( tokens[i] );
			}
		}
	}
	
	// add tags from the registered tag readers
	std::vector<CustomTagReader> &tagReaders = customTagReaders();
	for ( std::vector<CustomTagReader>::const_iterator it = tagReaders.begin(); it != tagReaders.end(); ++it )
	{
		NameList values;
		it->m_read( node, values, includeChildren );
		tags.insert( tags.end(), values.begin(), values.end() );
	}
	
	// add tags based on primitive groups
	OBJ_Node *contentNode = retrieveNode( true )->castToOBJNode();
	if ( contentNode && contentNode->getObjectType() == OBJ_GEOMETRY && m_splitter )
	{
		GU_DetailHandle newHandle = m_splitter->split( contentPathValue() );
		if ( !newHandle.isNull() )
		{
			GU_DetailHandleAutoReadLock readHandle( newHandle );
			if ( const GU_Detail *geo = readHandle.getGdp() )
			{
				GA_Range prims = geo->getPrimitiveRange();
				for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it )
				{
					GA_PrimitiveGroup *group = static_cast<GA_PrimitiveGroup*>( it.group() );
					if ( group->getInternal() || group->isEmpty() )
					{
						continue;
					}
					
					const UT_String &groupName = group->getName();
					if ( groupName.startsWith( tagGroupPrefix ) && group->containsAny( prims ) )
					{
						UT_String tag;
						groupName.substr( tag, tagGroupPrefix.length() );
						tag.substitute( "_", ":" );
						tags.push_back( tag.buffer() );
					}
				}
			}
		}
	}
}
예제 #5
0
bool HoudiniScene::hasTag( const Name &name, bool includeChildren ) const
{
	const OP_Node *node = retrieveNode();
	if ( !node )
	{
		return false;
	}
	
	// check for user supplied tags if we're not inside a SOP
	if ( !m_contentIndex && node->hasParm( pTags.getToken() ) )
	{
		UT_String parmTags;
		node->evalString( parmTags, pTags.getToken(), 0, 0 );
		if ( UT_String( name.c_str() ).multiMatch( parmTags ) )
		{
			return true;
		}
	}
	
	// check with the registered tag readers
	std::vector<CustomTagReader> &tagReaders = customTagReaders();
	for ( std::vector<CustomTagReader>::const_iterator it = tagReaders.begin(); it != tagReaders.end(); ++it )
	{
		if ( it->m_has( node, name ) )
		{
			return true;
		}
	}
	
	// check tags based on primitive groups
	OBJ_Node *contentNode = retrieveNode( true )->castToOBJNode();
	if ( contentNode && contentNode->getObjectType() == OBJ_GEOMETRY && m_splitter )
	{
		GU_DetailHandle newHandle = m_splitter->split( contentPathValue() );
		if ( !newHandle.isNull() )
		{
			GU_DetailHandleAutoReadLock readHandle( newHandle );
			if ( const GU_Detail *geo = readHandle.getGdp() )
			{
				GA_Range prims = geo->getPrimitiveRange();
				for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it )
				{
					GA_PrimitiveGroup *group = static_cast<GA_PrimitiveGroup*>( it.group() );
					if ( group->getInternal() || group->isEmpty() )
					{
						continue;
					}
					
					const UT_String &groupName = group->getName();
					if ( groupName.startsWith( tagGroupPrefix ) && group->containsAny( prims ) )
					{
						UT_String tag;
						groupName.substr( tag, tagGroupPrefix.length() );
						tag.substitute( "_", ":" );
						if ( tag.equal( name.c_str() ) )
						{
							return true;
						}
					}
				}
			}
		}
	}
	
	return false;
}
ObjectPtr FromHoudiniGroupConverter::doConversion( ConstCompoundObjectPtr operands ) const
{
	GU_DetailHandleAutoReadLock readHandle( handle() );
	const GU_Detail *geo = readHandle.getGdp();
	if ( !geo )
	{
		return 0;
	}
	
	size_t numResultPrims = 0;
	size_t numOrigPrims = geo->getNumPrimitives();
	
	GroupPtr result = new Group();
	
	if ( operands->member<const IntData>( "groupingMode" )->readable() == NameAttribute )
	{
		GA_ROAttributeRef attributeRef = geo->findPrimitiveAttribute( "name" );
		if ( attributeRef.isInvalid() || !attributeRef.isString() )
		{
			GU_Detail ungroupedGeo( (GU_Detail*)geo );
			GA_PrimitiveGroup *ungrouped = static_cast<GA_PrimitiveGroup*>( ungroupedGeo.createInternalElementGroup( GA_ATTRIB_PRIMITIVE, "FromHoudiniGroupConverter__ungroupedPrimitives" ) );
			ungrouped->toggleRange( ungroupedGeo.getPrimitiveRange() );
			
			VisibleRenderablePtr renderable = 0;
			doGroupConversion( &ungroupedGeo, ungrouped, renderable, operands );
			if ( renderable )
			{
				Group *group = runTimeCast<Group>( renderable );
				if ( group )
				{
					const Group::ChildContainer &children = group->children();
					for ( Group::ChildContainer::const_iterator it = children.begin(); it != children.end(); ++it )
					{
						result->addChild( *it );
					}
				}
				else
				{
					result->addChild( renderable );
				}
			}
			
			return result;
		}
		
		GU_Detail groupGeo( (GU_Detail*)geo );
		
		AttributePrimIdGroupMap groupMap;
		regroup( &groupGeo, groupMap, attributeRef );
		
		for ( AttributePrimIdGroupMapIterator it=groupMap.begin(); it != groupMap.end(); ++it )
		{
			convertAndAddPrimitive( &groupGeo, it->second, result, operands, it->first.first );
		}
	}
	else
	{
		for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it )
		{
			GA_PrimitiveGroup *group = static_cast<GA_PrimitiveGroup*>( it.group() );
			if ( group->getInternal() || group->isEmpty() )
			{
				continue;
			}

			VisibleRenderablePtr renderable = 0;
			numResultPrims += doGroupConversion( geo, group, renderable, operands );
			if( !renderable )
			{
				continue;
			}
			
			renderable->blindData()->member<StringData>( "name", false, true )->writable() = group->getName().toStdString();
			result->addChild( renderable );
		}

		if ( numOrigPrims == numResultPrims )
		{
			return result;
		}

		GU_Detail ungroupedGeo( (GU_Detail*)geo );
		GA_PrimitiveGroup *ungrouped = static_cast<GA_PrimitiveGroup*>( ungroupedGeo.createInternalElementGroup( GA_ATTRIB_PRIMITIVE, "FromHoudiniGroupConverter__ungroupedPrimitives" ) );
		for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it )
		{
			*ungrouped |= *static_cast<GA_PrimitiveGroup*>( it.group() );
		}
		ungrouped->toggleRange( ungroupedGeo.getPrimitiveRange() );

		if ( ungrouped->isEmpty() )
		{
			return result;
		}

		VisibleRenderablePtr renderable = 0;
		doGroupConversion( &ungroupedGeo, ungrouped, renderable, operands );
		if ( renderable )
		{
			result->addChild( renderable );
		}
	}
	
	return result;
}
ObjectPtr FromHoudiniGroupConverter::doConversion( ConstCompoundObjectPtr operands ) const
{
	GroupPtr result = new Group();
	
	if ( operands->member<const IntData>( "groupingMode" )->readable() == NameAttribute )
	{
		DetailSplitterPtr splitter = new DetailSplitter( handle() );
		std::vector<std::string> children;
		splitter->values( children );
		
		if ( children.empty() )
		{
			doUnnamedConversion( GU_DetailHandleAutoReadLock( handle() ).getGdp(), result, operands );
			return result;
		}
		
		for ( std::vector<std::string>::iterator it = children.begin(); it != children.end(); ++it )
		{
			const std::string &name = *it;
			GU_DetailHandle childHandle = splitter->split( name );
			if ( childHandle.isNull() )
			{
				continue;
			}
			
			GU_DetailHandleAutoReadLock readHandle( childHandle );
			const GU_Detail *childGeo = readHandle.getGdp();
			ObjectPtr child = doDetailConversion( childGeo, operands );
			if ( !child )
			{
				// this happens when mismatched primitives share the same name
				doUnnamedConversion( childGeo, result, operands, name );
			}
			else if ( VisibleRenderablePtr renderable = IECore::runTimeCast<VisibleRenderable>( child ) )
			{
				if ( name != "" )
				{
					renderable->blindData()->member<StringData>( "name", false, true )->writable() = name;
				}
				
				result->addChild( renderable );
			}
		}
	}
	else
	{
		GU_DetailHandleAutoReadLock readHandle( handle() );
		const GU_Detail *geo = readHandle.getGdp();
		if ( !geo )
		{
			return 0;
		}

		size_t numResultPrims = 0;
		size_t numOrigPrims = geo->getNumPrimitives();

		for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it )
		{
			GA_PrimitiveGroup *group = static_cast<GA_PrimitiveGroup*>( it.group() );
			if ( group->getInternal() || group->isEmpty() )
			{
				continue;
			}

			VisibleRenderablePtr renderable = 0;
			numResultPrims += doGroupConversion( geo, group, renderable, operands );
			if( !renderable )
			{
				continue;
			}
			
			renderable->blindData()->member<StringData>( "name", false, true )->writable() = group->getName().toStdString();
			result->addChild( renderable );
		}

		if ( numOrigPrims == numResultPrims )
		{
			return result;
		}

		GU_Detail ungroupedGeo( (GU_Detail*)geo );
		GA_PrimitiveGroup *ungrouped = static_cast<GA_PrimitiveGroup*>( ungroupedGeo.createInternalElementGroup( GA_ATTRIB_PRIMITIVE, "FromHoudiniGroupConverter__ungroupedPrimitives" ) );
		for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it )
		{
			*ungrouped |= *static_cast<GA_PrimitiveGroup*>( it.group() );
		}
		ungrouped->toggleRange( ungroupedGeo.getPrimitiveRange() );

		if ( ungrouped->isEmpty() )
		{
			return result;
		}

		VisibleRenderablePtr renderable = 0;
		doGroupConversion( &ungroupedGeo, ungrouped, renderable, operands );
		if ( renderable )
		{
			result->addChild( renderable );
		}
	}
	
	return result;
}