OP_ERROR SOP_SceneCacheSource::cookMySop( OP_Context &context ) { flags().setTimeDep( true ); std::string file; if ( !ensureFile( file ) ) { addError( SOP_ATTRIBUTE_INVALID, ( file + " is not a valid .scc" ).c_str() ); gdp->clearAndDestroy(); return error(); } std::string path = getPath(); Space space = getSpace(); UT_String shapeFilterStr; evalString( shapeFilterStr, pShapeFilter.getToken(), 0, 0 ); UT_StringMMPattern shapeFilter; shapeFilter.compile( shapeFilterStr ); UT_String p( "P" ); UT_String attributeFilter; evalString( attributeFilter, pAttributeFilter.getToken(), 0, 0 ); if ( !p.match( attributeFilter ) ) { attributeFilter += " P"; } ConstSceneInterfacePtr scene = this->scene( file, path ); if ( !scene ) { addError( SOP_ATTRIBUTE_INVALID, ( path + " is not a valid location in " + file ).c_str() ); gdp->clearAndDestroy(); return error(); } MurmurHash hash; hash.append( file ); hash.append( path ); hash.append( space ); hash.append( shapeFilterStr ); hash.append( attributeFilter ); if ( !m_loaded || m_hash != hash ) { gdp->clearAndDestroy(); } Imath::M44d transform = ( space == World ) ? worldTransform( file, path, context.getTime() ) : Imath::M44d(); SceneInterface::Path rootPath; scene->path( rootPath ); loadObjects( scene, transform, context.getTime(), space, shapeFilter, attributeFilter.toStdString(), rootPath.size() ); m_loaded = true; m_hash = hash; return error(); }
int ROP_SceneCacheWriter::startRender( int nframes, fpreal s, fpreal e ) { UT_String value; evalString( value, pRootObject.getToken(), 0, 0 ); try { SceneInterface::Path emptyPath; m_liveScene = new IECoreHoudini::HoudiniScene( value, emptyPath, emptyPath ); } catch ( IECore::Exception &e ) { addError( ROP_MESSAGE, e.what() ); return false; } evalString( value, pFile.getToken(), 0, 0 ); std::string file = value.toStdString(); try { m_outScene = SceneInterface::create( file, IndexedIO::Write ); } catch ( IECore::Exception &e ) { addError( ROP_MESSAGE, ( "Could not create a writable IECore::SceneInterface at \"" + file + "\"" ).c_str() ); return false; } return true; }
std::string getStringParam(OP_Parameters& node, OP_Context &context, const std::string& label, bool trimspace) { UT_String s; node.evalString(s, label.c_str(), 0, context.getTime()); if(trimspace) s.trimSpace(); return s.toStdString(); }
std::string GusdGetErrors(UT_ErrorManager* mgr, UT_ErrorSeverity sev) { std::string err; if(mgr && mgr->getSeverity() >= SYSmin(sev, UT_ERROR_MESSAGE)) { UT_String msg; mgr->getErrorMessages(msg, sev, /*headerflag*/ 0); err = msg.toStdString(); } return err; }
OP_ERROR SOP_CortexConverter::cookMySop( OP_Context &context ) { if( lockInputs( context ) >= UT_ERROR_ABORT ) { return error(); } UT_Interrupt *boss = UTgetInterrupt(); boss->opStart("Building CortexConverter Geometry..."); gdp->clearAndDestroy(); UT_String nameFilterStr; evalString( nameFilterStr, pNameFilter.getToken(), 0, 0 ); UT_StringMMPattern nameFilter; nameFilter.compile( nameFilterStr ); UT_String p( "P" ); UT_String attributeFilter; evalString( attributeFilter, pAttributeFilter.getToken(), 0, 0 ); if ( !p.match( attributeFilter ) ) { attributeFilter += " P"; } const std::string attributeFilterStr = attributeFilter.toStdString(); ResultType type = (ResultType)this->evalInt( pResultType.getToken(), 0, 0 ); bool convertStandardAttributes = evalInt( pConvertStandardAttributes.getToken(), 0, 0 ); DetailSplitterPtr splitter = new DetailSplitter( inputGeoHandle( 0 ) ); std::vector<std::string> names; splitter->values( names ); for ( std::vector<std::string>::const_iterator it = names.begin(); it != names.end(); ++it ) { const std::string &name = *it; // we want match all to also match no-name if ( UT_String( name ).multiMatch( nameFilter ) || ( name == "" && UT_String( "*" ).multiMatch( nameFilter ) ) ) { doConvert( splitter->split( name ), name, type, attributeFilterStr, convertStandardAttributes ); } else { doPassThrough( splitter->split( name ), name ); } } boss->opEnd(); unlockInputs(); return error(); }
OP_ERROR SOP_SceneCacheSource::cookMySop( OP_Context &context ) { // make sure the state is valid if ( boost::indeterminate( m_static ) ) { sceneChanged(); } flags().setTimeDep( bool( !m_static ) ); std::string file; if ( !ensureFile( file ) ) { addError( SOP_ATTRIBUTE_INVALID, ( file + " is not a valid .scc" ).c_str() ); gdp->clearAndDestroy(); return error(); } std::string path = getPath(); Space space = getSpace(); GeometryType geometryType = (GeometryType)this->evalInt( pGeometryType.getToken(), 0, 0 ); UT_String shapeFilterStr; evalString( shapeFilterStr, pShapeFilter.getToken(), 0, 0 ); UT_StringMMPattern shapeFilter; shapeFilter.compile( shapeFilterStr ); UT_String p( "P" ); UT_String attributeFilter; evalString( attributeFilter, pAttributeFilter.getToken(), 0, 0 ); if ( !p.match( attributeFilter ) ) { attributeFilter += " P"; } ConstSceneInterfacePtr scene = this->scene( file, path ); if ( !scene ) { addError( SOP_ATTRIBUTE_INVALID, ( path + " is not a valid location in " + file ).c_str() ); gdp->clearAndDestroy(); return error(); } MurmurHash hash; hash.append( file ); hash.append( path ); hash.append( space ); hash.append( shapeFilterStr ); hash.append( attributeFilter ); hash.append( geometryType ); hash.append( getObjectOnly() ); if ( !m_loaded || m_hash != hash ) { gdp->clearAndDestroy(); } Imath::M44d transform = ( space == World ) ? worldTransform( file, path, context.getTime() ) : Imath::M44d(); SceneInterface::Path rootPath; scene->path( rootPath ); UT_Interrupt *progress = UTgetInterrupt(); if ( !progress->opStart( ( "Cooking objects for " + getPath() ).c_str() ) ) { addError( SOP_ATTRIBUTE_INVALID, "Cooking interrupted before it started" ); gdp->clearAndDestroy(); return error(); } loadObjects( scene, transform, context.getTime(), space, shapeFilter, attributeFilter.toStdString(), geometryType, rootPath.size() ); if ( progress->opInterrupt( 100 ) ) { addError( SOP_ATTRIBUTE_INVALID, "Cooking interrupted" ); gdp->clearAndDestroy(); m_loaded = false; m_hash = MurmurHash(); } else { m_loaded = true; m_hash = hash; } progress->opEnd(); return error(); }
OP_ERROR SOP_AddEdges::cookMySop(OP_Context &context) { typedef dgal::simple_mesh<Imath::V3f> simple_mesh; typedef dgal::EdgeIntersection<unsigned int, float> edge_intersection; typedef std::pair<unsigned int, unsigned int> edge_type; hdk_utils::ScopedCook scc(*this, context, "Performing edges add"); if(!scc.good()) return error(); double now = context.getTime(); // inputs const GU_Detail* gdp0 = inputGeo(0); if (!gdp0 ) { SOP_ADD_FATAL(SOP_MESSAGE, "Not enough sources specified."); } unsigned int npoints0 = gdp0->points().entries(); UT_String edgesAttrib; evalString(edgesAttrib, "edges_string", 0, now); std::string edgesAttribStr = edgesAttrib.toStdString(); std::vector<std::string> toks; pystring::split(edgesAttribStr, toks); if(toks.empty()) { duplicateSource(0, context); return error(); } simple_mesh m, m2; simple_mesh* pm = NULL; std::vector<int> points_remap; std::vector<int> polys_remap; dgal::MeshRemapSettings<int> remap_settings(true, true, true, 0, 0, &points_remap, &polys_remap); std::map<std::string, unsigned int> new_points; // create new points { std::vector<edge_intersection> edgeints; std::string s = pystring::replace(edgesAttribStr, ",", " "); std::vector<std::string> toks; pystring::split(s, toks); for(unsigned int i=0; i<toks.size(); ++i) { // new point will be in form 'X-Y:f' if(toks[i].find('-') != std::string::npos) { s = pystring::replace(toks[i], "-", " "); s = pystring::replace(s, ":", " "); std::istringstream strm(s); edge_intersection ei; try { strm >> ei.m_point1 >> ei.m_point2 >> ei.m_u; } catch(const std::exception&) { continue; } new_points[toks[i]] = npoints0 + edgeints.size(); edgeints.push_back(ei); } } if(new_points.empty()) { // no new points means no point remapping remap_settings.m_genPointRemapping = false; remap_settings.m_identity_point_mapping = true; } else { dgal::addMeshPoints<GEO_Detail, std::vector<edge_intersection>::const_iterator>( *gdp0, m, edgeints.begin(), edgeints.end(), &points_remap, &polys_remap); pm = &m; } }
OP_ERROR SOP_SceneCacheSource::cookMySop( OP_Context &context ) { // make sure the state is valid if ( boost::indeterminate( m_static ) ) { sceneChanged(); } flags().setTimeDep( bool( !m_static ) ); std::string file; if ( !ensureFile( file ) ) { addError( SOP_ATTRIBUTE_INVALID, ( file + " is not a valid .scc" ).c_str() ); gdp->clearAndDestroy(); return error(); } std::string path = getPath(); Space space = getSpace(); GeometryType geometryType = (GeometryType)this->evalInt( pGeometryType.getToken(), 0, 0 ); UT_String tagFilterStr; getTagFilter( tagFilterStr ); UT_StringMMPattern tagFilter; tagFilter.compile( tagFilterStr ); UT_String shapeFilterStr; getShapeFilter( shapeFilterStr ); UT_StringMMPattern shapeFilter; shapeFilter.compile( shapeFilterStr ); UT_String p( "P" ); UT_String attributeFilter; getAttributeFilter( attributeFilter ); if ( !p.match( attributeFilter ) ) { attributeFilter += " P"; } UT_String attributeCopy; getAttributeCopy( attributeCopy ); UT_String fullPathName; getFullPathName( fullPathName ); ConstSceneInterfacePtr scene = this->scene( file, path ); if ( !scene ) { addError( SOP_ATTRIBUTE_INVALID, ( path + " is not a valid location in " + file ).c_str() ); gdp->clearAndDestroy(); return error(); } MurmurHash hash; hash.append( file ); hash.append( path ); hash.append( space ); hash.append( tagFilterStr ); hash.append( shapeFilterStr ); hash.append( attributeFilter ); hash.append( attributeCopy ); hash.append( fullPathName ); hash.append( geometryType ); hash.append( getObjectOnly() ); if ( !m_loaded || m_hash != hash ) { gdp->clearAndDestroy(); } double readTime = time( context ); Imath::M44d transform = ( space == World ) ? worldTransform( file, path, readTime ) : Imath::M44d(); SceneInterface::Path rootPath; scene->path( rootPath ); UT_Interrupt *progress = UTgetInterrupt(); if ( !progress->opStart( ( "Cooking objects for " + getPath() ).c_str() ) ) { addError( SOP_ATTRIBUTE_INVALID, "Cooking interrupted before it started" ); gdp->clearAndDestroy(); return error(); } Parameters params; UT_String attribFilter; getAttributeFilter( attribFilter ); params.attributeFilter = attribFilter.toStdString(); params.attributeCopy = attributeCopy.toStdString(); params.fullPathName = fullPathName.toStdString(); params.geometryType = getGeometryType(); getShapeFilter( params.shapeFilter ); getTagFilter( params.tagFilter ); // Building a map from shape name to primitive range, which will be used during // convertObject() to do a lazy update of animated primvars where possible, and // to destroy changing topology shapes when necessary. GA_ROAttributeRef nameAttrRef = gdp->findStringTuple( GA_ATTRIB_PRIMITIVE, "name" ); if ( nameAttrRef.isValid() ) { const GA_Attribute *attr = nameAttrRef.getAttribute(); const GA_AIFSharedStringTuple *tuple = attr->getAIFSharedStringTuple(); std::map<std::string, GA_OffsetList> offsets; GA_Range primRange = gdp->getPrimitiveRange(); for ( GA_Iterator it = primRange.begin(); !it.atEnd(); ++it ) { std::string current = ""; if ( const char *value = tuple->getString( attr, it.getOffset() ) ) { current = value; } std::map<std::string, GA_OffsetList>::iterator oIt = offsets.find( current ); if ( oIt == offsets.end() ) { oIt = offsets.insert( std::pair<std::string, GA_OffsetList>( current, GA_OffsetList() ) ).first; } oIt->second.append( it.getOffset() ); } for ( std::map<std::string, GA_OffsetList>::iterator oIt = offsets.begin(); oIt != offsets.end(); ++oIt ) { params.namedRanges[oIt->first] = GA_Range( gdp->getPrimitiveMap(), oIt->second ); } } loadObjects( scene.get(), transform, readTime, space, params, rootPath.size() ); if ( progress->opInterrupt( 100 ) ) { addError( SOP_ATTRIBUTE_INVALID, "Cooking interrupted" ); gdp->clearAndDestroy(); m_loaded = false; m_hash = MurmurHash(); } else { m_loaded = true; m_hash = hash; } progress->opEnd(); return error(); }
std::string SceneCacheNode<BaseType>::getPath() const { UT_String value; this->evalString( value, pRoot.getToken(), 0, 0 ); return ( value == "" ) ? "/" : value.toStdString(); }
std::string SceneCacheNode<BaseType>::getFile() const { UT_String value; this->evalString( value, pFile.getToken(), 0, 0 ); return value.toStdString(); }
OP_ERROR SOP_InterpolatedCacheReader::cookMySop( OP_Context &context ) { flags().setTimeDep( true ); if ( lockInputs( context ) >= UT_ERROR_ABORT ) { return error(); } gdp->stashAll(); float time = context.getTime(); float frame = context.getFloatFrame(); UT_String paramVal; evalString( paramVal, "cacheSequence", 0, time ); std::string cacheFileName = paramVal.toStdString(); evalString( paramVal, "objectFixes", 0, time ); std::string objectPrefix = paramVal.toStdString(); evalString( paramVal, "objectFixes", 1, time ); std::string objectSuffix = paramVal.toStdString(); evalString( paramVal, "attributeFixes", 0, time ); std::string attributePrefix = paramVal.toStdString(); evalString( paramVal, "attributeFixes", 1, time ); std::string attributeSuffix = paramVal.toStdString(); evalString( paramVal, "transformAttribute", 0, time ); std::string transformAttribute = paramVal.toStdString(); int samplesPerFrame = evalInt( "samplesPerFrame", 0, time ); InterpolatedCache::Interpolation interpolation = (InterpolatedCache::Interpolation)evalInt( "interpolation", 0, time ); GroupingMode groupingMode = (GroupingMode)evalInt( "groupingMode", 0, time ); // create the InterpolatedCache if ( cacheFileName.compare( m_cacheFileName ) != 0 || samplesPerFrame != m_samplesPerFrame || interpolation != m_interpolation ) { try { float fps = OPgetDirector()->getChannelManager()->getSamplesPerSec(); OversamplesCalculator calc( fps, samplesPerFrame ); m_cache = new InterpolatedCache( cacheFileName, interpolation, calc ); } catch ( IECore::InvalidArgumentException e ) { addWarning( SOP_ATTRIBUTE_INVALID, e.what() ); unlockInputs(); return error(); } m_cacheFileName = cacheFileName; m_samplesPerFrame = samplesPerFrame; m_interpolation = interpolation; } if ( !m_cache ) { addWarning( SOP_MESSAGE, "SOP_InterpolatedCacheReader: Cache Sequence not found" ); unlockInputs(); return error(); } std::vector<InterpolatedCache::ObjectHandle> objects; std::vector<InterpolatedCache::AttributeHandle> attrs; try { m_cache->objects( frame, objects ); } catch ( IECore::Exception e ) { addWarning( SOP_ATTRIBUTE_INVALID, e.what() ); unlockInputs(); return error(); } duplicatePointSource( 0, context ); GA_ElementGroupTable *groups = 0; if ( groupingMode == PointGroup ) { groups = &gdp->pointGroups(); } else if ( groupingMode == PrimitiveGroup ) { groups = &gdp->primitiveGroups(); } for ( GA_GroupTable::iterator<GA_ElementGroup> it=groups->beginTraverse(); !it.atEnd(); ++it ) { GA_ElementGroup *group = it.group(); if ( group->getInternal() || group->isEmpty() ) { continue; } // match GA_ElementGroup name to InterpolatedCache::ObjectHandle std::string searchName = objectPrefix + group->getName().toStdString() + objectSuffix; std::vector<InterpolatedCache::ObjectHandle>::iterator oIt = find( objects.begin(), objects.end(), searchName ); if ( oIt == objects.end() ) { continue; } CompoundObjectPtr attributes = 0; try { m_cache->attributes( frame, *oIt, attrs ); attributes = m_cache->read( frame, *oIt ); } catch ( IECore::Exception e ) { addError( SOP_ATTRIBUTE_INVALID, e.what() ); unlockInputs(); return error(); } const CompoundObject::ObjectMap &attributeMap = attributes->members(); GA_Range pointRange; GA_Range primRange; GA_Range vertexRange; if ( groupingMode == PointGroup ) { pointRange = gdp->getPointRange( (GA_PointGroup*)it.group() ); } else if ( groupingMode == PrimitiveGroup ) { primRange = gdp->getPrimitiveRange( (GA_PrimitiveGroup*)it.group() ); const GA_PrimitiveList &primitives = gdp->getPrimitiveList(); GA_OffsetList pointOffsets; GA_OffsetList vertOffsets; for ( GA_Iterator it=primRange.begin(); !it.atEnd(); ++it ) { const GA_Primitive *prim = primitives.get( it.getOffset() ); GA_Range primPointRange = prim->getPointRange(); for ( GA_Iterator pIt=primPointRange.begin(); !pIt.atEnd(); ++pIt ) { pointOffsets.append( pIt.getOffset() ); } size_t numPrimVerts = prim->getVertexCount(); for ( size_t v=0; v < numPrimVerts; v++ ) { if ( prim->getTypeId() == GEO_PRIMPOLY ) { vertOffsets.append( prim->getVertexOffset( numPrimVerts - 1 - v ) ); } else { vertOffsets.append( prim->getVertexOffset( v ) ); } } } pointOffsets.sortAndRemoveDuplicates(); pointRange = GA_Range( gdp->getPointMap(), pointOffsets ); vertexRange = GA_Range( gdp->getVertexMap(), vertOffsets ); } // transfer the InterpolatedCache::Attributes onto the GA_ElementGroup for ( CompoundObject::ObjectMap::const_iterator aIt=attributeMap.begin(); aIt != attributeMap.end(); aIt++ ) { Data *data = IECore::runTimeCast<Data>( aIt->second ); if ( !data ) { continue; } ToHoudiniAttribConverterPtr converter = ToHoudiniAttribConverter::create( data ); if ( !converter ) { continue; } // strip the prefix/suffix from the GA_Attribute name std::string attrName = aIt->first.value(); size_t prefixLength = attributePrefix.length(); if ( prefixLength && ( search( attrName.begin(), attrName.begin()+prefixLength, attributePrefix.begin(), attributePrefix.end() ) == attrName.begin() ) ) { attrName.erase( attrName.begin(), attrName.begin() + prefixLength ); } size_t suffixLength = attributeSuffix.length(); if ( suffixLength && ( search( attrName.end() - suffixLength, attrName.end(), attributeSuffix.begin(), attributeSuffix.end() ) == ( attrName.end() - suffixLength ) ) ) { attrName.erase( attrName.end() - suffixLength, attrName.end() ); } if ( attrName == "P" ) { const V3fVectorData *positions = IECore::runTimeCast<const V3fVectorData>( data ); if ( !positions ) { continue; } size_t index = 0; size_t entries = pointRange.getEntries(); const std::vector<Imath::V3f> &pos = positions->readable(); // Attempting to account for the vertex difference between an IECore::CurvesPrimitive and Houdini curves. // As Houdini implicitly triples the endpoints of a curve, a cache generated from a single CurvesPrimitive // will have exactly four extra vertices. In this case, we adjust the cache by ignoring the first two and // last two V3fs. In all other cases, we report a warning and don't apply the cache to these points. if ( pos.size() - 4 == entries ) { index = 2; } else if ( pos.size() != entries ) { addWarning( SOP_ATTRIBUTE_INVALID, ( boost::format( "Geometry/Cache mismatch: %s contains %d points, while cache expects %d values for P." ) % group->getName().toStdString() % entries % pos.size() ).str().c_str() ); continue; } /// \todo: try multi-threading this with a GA_SplittableRange for ( GA_Iterator it=pointRange.begin(); !it.atEnd(); ++it, ++index ) { gdp->setPos3( it.getOffset(), IECore::convert<UT_Vector3>( pos[index] ) ); } } else if ( groupingMode == PrimitiveGroup ) { GA_Range currentRange; unsigned size = despatchTypedData<TypedDataSize, TypeTraits::IsVectorTypedData, DespatchTypedDataIgnoreError>( data ); // check for existing attributes if ( gdp->findPrimitiveAttribute( attrName.c_str() ).isValid() && size == primRange.getEntries() ) { currentRange = primRange; } else if ( gdp->findPointAttribute( attrName.c_str() ).isValid() && size == pointRange.getEntries() ) { currentRange = pointRange; } else if ( gdp->findVertexAttribute( attrName.c_str() ).isValid() && size == vertexRange.getEntries() ) { currentRange = vertexRange; } // fall back to Cortex standard inferred order else if ( size == primRange.getEntries() ) { currentRange = primRange; } else if ( size == pointRange.getEntries() ) { currentRange = pointRange; } else if ( size == vertexRange.getEntries() ) { currentRange = vertexRange; } else { addWarning( SOP_ATTRIBUTE_INVALID, ( boost::format( "Geometry/Cache mismatch: %s: cache expects %d values for %s." ) % group->getName().toStdString() % size % attrName ).str().c_str() ); continue; } converter->convert( attrName, gdp, currentRange ); } else { converter->convert( attrName, gdp, pointRange ); } } // if transformAttribute is specified, use to to transform the points if ( transformAttribute != "" ) { const TransformationMatrixdData *transform = attributes->member<TransformationMatrixdData>( transformAttribute ); if ( transform ) { UT_Matrix4 matrix( IECore::convert<UT_Matrix4T<double> >( transform->readable().transform() ) ); gdp->transformGroup( matrix, *group ); } else { const TransformationMatrixfData *transform = attributes->member<TransformationMatrixfData>( transformAttribute ); if ( transform ) { UT_Matrix4 matrix = IECore::convert<UT_Matrix4>( transform->readable().transform() ); gdp->transformGroup( matrix, *group ); } } } } unlockInputs(); return error(); }