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? GA_ROAttributeRef attrRef = geo->findPrimitiveAttribute( "name" ); if ( attrRef.isValid() && attrRef.isString() ) { const GA_Attribute *nameAttr = attrRef.getAttribute(); const GA_AIFSharedStringTuple *tuple = nameAttr->getAIFSharedStringTuple(); GA_StringTableStatistics stats; tuple->getStatistics( nameAttr, stats ); if ( stats.getEntries() < 2 ) { return Ideal; } } return Suitable; }
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; }
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? GA_ROAttributeRef attrRef = geo->findPrimitiveAttribute( "name" ); if ( attrRef.isValid() && attrRef.isString() ) { const GA_Attribute *nameAttr = attrRef.getAttribute(); const GA_AIFSharedStringTuple *tuple = nameAttr->getAIFSharedStringTuple(); if ( tuple->getTableEntries( nameAttr ) > 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; }