OP_ERROR SOP_Cleave::cookMySop(OP_Context &context) { const GA_PrimitiveGroup *polyGroup; GEO_Primitive *prim; GQ_Detail *gqd; int i,j,k; UT_Vector4 np,p; // Before we do anything, we must lock our inputs. Before returning, // we have to make sure that the inputs get unlocked. if (lockInputs(context) >= UT_ERROR_ABORT) return error(); float now = context.getTime(); duplicateSource(0, context, 0, 1); // Here we determine which groups we have to work on. We only // handle poly groups. UT_String groups; getGroups(groups); if (groups.isstring()) polyGroup = parsePrimitiveGroups(groups); else polyGroup = 0; if (error() >= UT_ERROR_ABORT) { unlockInputs(); return error(); } UT_Interrupt* boss = UTgetInterrupt(); // Start the interrupt server boss->opStart("Cleaving Polys"); // separate out all polys to be cleaved GA_PrimitiveGroup* cleave_group = gdp->newPrimitiveGroup("cleave",1); GA_PrimitiveGroup* not_cleave_group = gdp->newPrimitiveGroup("not_cleave",1); if (polyGroup) { GA_FOR_ALL_PRIMITIVES(gdp,prim) { if ( (prim->getTypeId()==GEO_PRIMPOLY) && (polyGroup->contains(prim)!=0)) cleave_group->add(prim); else not_cleave_group->add(prim); } } else {
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(); }
/// Cook the SOP! This method does all the work OP_ERROR SOP_ProceduralHolder::cookMySop( OP_Context &context ) { IECore::MessageHandler::Scope handlerScope( getMessageHandler() ); // some defaults and useful variables float now = context.getTime(); // force eval of our nodes parameters with our hidden parameter expression evalInt( "__evaluateParameters", 0, now ); // update parameters on procedural from our Houdini parameters IECore::ParameterisedProceduralPtr procedural = IECore::runTimeCast<IECore::ParameterisedProcedural>( getParameterised() ); // check for a valid parameterised on this SOP if ( !procedural ) { UT_String msg( "Procedural Holder has no parameterised class to operate on!" ); addError( SOP_MESSAGE, msg ); return error(); } if( lockInputs(context) >= UT_ERROR_ABORT ) { return error(); } // start our work UT_Interrupt *boss = UTgetInterrupt(); boss->opStart("Building ProceduralHolder Geometry..."); gdp->clearAndDestroy(); setParameterisedValues( now ); ToHoudiniCortexObjectConverterPtr converter = new ToHoudiniCortexObjectConverter( procedural ); if ( !converter->convert( myGdpHandle ) ) { addError( SOP_MESSAGE, "Unable to store procedural on gdp" ); } // tidy up & go home! 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_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(); }
// the bit that does all the work OP_ERROR SOP_rmanPtc::cookMySop(OP_Context &context) { // get some useful bits & bobs UT_Interrupt *boss; float now = context.myTime; UT_String ptcFile = getPtcFile(now); int loadPercentage = getLoadPercentage(now); int displayPercentage = getDisplayPercentage(now); float pointSize = getPointSize(now); int useDisk = getUseDisk(now); int boundOnLoad = getBoundOnLoad(now); int displayChannel = getDisplayChannel(now); int onlyOutputDisplayChannel = getOnlyOutputDisplayChannel(now); /* float nearDensity = getNearDensity(now); float farDensity = getFarDensity(now); UT_String cullCamera = getCullCamera(now); */ // lock out inputs if ( lockInputs(context) >= UT_ERROR_ABORT) error(); // Check to see that there hasn't been a critical error in cooking the SOP. if (error() < UT_ERROR_ABORT) { boss = UTgetInterrupt(); // here we make sure our detail is an instance of rmanPtcDetail rmanPtcDetail *ptc_gdp = dynamic_cast<rmanPtcSop::rmanPtcDetail *>(gdp); if ( !ptc_gdp ) ptc_gdp = allocateNewDetail(); // clear our gdp ptc_gdp->clearAndDestroy(); // start our work boss->opStart("Loading point cloud"); // get our bbox bool has_bbox = false; const GU_Detail *input_geo = inputGeo( 0, context ); updateBBox( input_geo ); // pass information to our detail ptc_gdp->point_size = pointSize; ptc_gdp->use_disk = useDisk; ptc_gdp->cull_bbox = mBBox; ptc_gdp->use_cull_bbox = (mHasBBox&&(!mBoundOnLoad))?true:false; ptc_gdp->display_probability = displayPercentage/100.f; ptc_gdp->display_channel = displayChannel; if ( onlyOutputDisplayChannel ) ptc_gdp->display_channel = 0; // here we load our ptc if ( mReload ) { // clear everything mChannelNames.clear(); cachePoints.clear(); cacheNormals.clear(); cacheRadius.clear(); cacheData.clear(); mRedraw = true; // open the point cloud PtcPointCloud ptc = PtcSafeOpenPointCloudFile( const_cast<char*>(ptcFile.buffer()) ); if ( !ptc ) { UT_String msg( "Unable to open input file: " ); msg += ptcFile; addError( SOP_MESSAGE, msg); boss->opEnd(); return error(); } // get some information from the ptc ptc_gdp->path = std::string(ptcFile.fileName()); char **vartypes, **varnames; PtcGetPointCloudInfo( ptc, const_cast<char*>("npoints"), &ptc_gdp->nPoints ); PtcGetPointCloudInfo( ptc, const_cast<char*>("npointvars"), &ptc_gdp->nChannels ); PtcGetPointCloudInfo( ptc, const_cast<char*>("pointvartypes"), &vartypes ); PtcGetPointCloudInfo( ptc, const_cast<char*>("pointvarnames"), &varnames ); PtcGetPointCloudInfo( ptc, const_cast<char*>("datasize"), &ptc_gdp->datasize ); PtcGetPointCloudInfo( ptc, const_cast<char*>("bbox"), ptc_gdp->bbox ); // process our channel names ptc_gdp->types.clear(); ptc_gdp->names.clear(); for ( unsigned int i=0; i<ptc_gdp->nChannels; ++i ) { ptc_gdp->types.push_back( std::string(vartypes[i]) ); ptc_gdp->names.push_back( std::string(varnames[i]) ); std::string name = ptc_gdp->types[i] + " " + ptc_gdp->names[i]; mChannelNames.push_back( name ); } // what percentage of points should we load? float load_probability = loadPercentage/100.f; // load points into memory float point[3], normal[3]; float radius; float data[ptc_gdp->datasize]; srand(0); for ( unsigned int i=0; i<ptc_gdp->nPoints; ++i ) { PtcReadDataPoint( ptc, point, normal, &radius, data ); // bound on load if ( boundOnLoad ) { UT_Vector3 pt( point[0], point[1], point[2] ); if ( !mBBox.isInside(pt) ) continue; } // discard a percentage of our points if ( rand()/(float)RAND_MAX>load_probability ) continue; // put points into our cache cachePoints.push_back( point ); cacheNormals.push_back( normal ); cacheRadius.push_back( radius ); for ( unsigned int j=0; j<ptc_gdp->datasize; ++j ) cacheData.push_back( data[j] ); // break for the interrupt handler (i.e. press ESC) if ( boss->opInterrupt() ) break; } ptc_gdp->nLoaded = cachePoints.size(); // mark our detail as valid and close our ptc PtcClosePointCloudFile( ptc ); mReload = false; // force update on channel parameter getParm("chan").revertToDefaults(now); } // build a new primitive GU_PrimParticle::build( ptc_gdp, cachePoints.size(), 0 ); // create our output geometry using the output % parameter // this is the same variable as GR_ uses to preview std::vector<UT_Vector3>::const_iterator pos_it = cachePoints.begin(); std::vector<UT_Vector3>::const_iterator norm_it = cacheNormals.begin(); std::vector<float>::const_iterator rad_it = cacheRadius.begin(); std::vector<float>::const_iterator data_it = cacheData.begin(); // add some standard attributes GB_AttributeRef n_attrib = ptc_gdp->addPointAttrib( "N", sizeof(UT_Vector3), GB_ATTRIB_VECTOR, 0 ); GB_AttributeRef r_attrib = ptc_gdp->addPointAttrib( "radius", sizeof(float), GB_ATTRIB_FLOAT, 0 ); ptc_gdp->N_attrib = n_attrib; ptc_gdp->R_attrib = r_attrib; // process the rest of our data attributes std::vector<GB_AttribType> data_types; std::vector<GB_AttributeRef> data_attribs; std::vector<int> data_size, data_offset; int offset_total = 0; ptc_gdp->attributes.clear(); ptc_gdp->attribute_size.clear(); for ( unsigned int i=0; i<ptc_gdp->nChannels; ++i ) { GB_AttribType type = GB_ATTRIB_FLOAT; // float, vector int size = 1; if ( ptc_gdp->types[i] == "point" || ptc_gdp->types[i] == "vector" || ptc_gdp->types[i] == "normal" ) { type = GB_ATTRIB_VECTOR; size = 3; } if ( ptc_gdp->types[i] == "color" ) { size=3; } if ( ptc_gdp->types[i] == "matrix" ) { size=16; } offset_total += size; data_types.push_back( type ); data_size.push_back( size ); data_offset.push_back( offset_total ); if ( onlyOutputDisplayChannel ) { if ( displayChannel==i ) { GB_AttributeRef attrib = ptc_gdp->addPointAttrib( ptc_gdp->names[i].c_str(), sizeof(float)*size, type, 0 ); ptc_gdp->attributes.push_back( attrib ); ptc_gdp->attribute_size.push_back( size ); data_attribs.push_back( attrib ); } } else { GB_AttributeRef attrib = ptc_gdp->addPointAttrib( ptc_gdp->names[i].c_str(), sizeof(float)*size, type, 0 ); ptc_gdp->attributes.push_back( attrib ); ptc_gdp->attribute_size.push_back( size ); data_attribs.push_back( attrib ); } } cacheDataOffsets = data_offset; /* // cull camera bool use_cull_cam = false; UT_Vector3 cam_pos(0,0,0); float cam_near=0.0, cam_far=0.0; if ( cullCamera!="" ) { OBJ_Node *cam_node = OPgetDirector()->findOBJNode( cullCamera ); if ( cam_node ) { OBJ_Camera *cam = cam_node->castToOBJCamera(); if ( cam ) { UT_DMatrix4 mtx; cam->getWorldTransform( mtx, context ); std::cerr << "mtx: " << mtx << std::endl; cam_pos *= mtx; std::cerr << "pos: " << cam_pos << std::endl; use_cull_cam = true; cam_near = cam->getNEAR(now); cam_far = cam->getFAR(now); std::cerr << "near: " << cam_near << std::endl; std::cerr << "far: " << cam_far << std::endl; mRedraw = true; } } std::cerr << "cull camera: " << cullCamera << std::endl; std::cerr << nearDensity << ", " << farDensity << std::endl; } */ // add data from our cached points to geometry // based on display/output probability srand(0); float density_mult = 1.f; while( pos_it!=cachePoints.end() ) { /* if ( use_cull_cam ) { float dist = ((*pos_it)-cam_pos).length(); if ( dist<cam_near ) density_mult = nearDensity; else if ( dist>cam_far ) density_mult = farDensity; else { float normalize_dist =( dist - cam_near ) / ( cam_far - cam_near ); density_mult = 1.f - normalize_dist; } } */ if ( rand()/(float)RAND_MAX < ptc_gdp->display_probability*density_mult ) { if ( (!ptc_gdp->use_cull_bbox) || (ptc_gdp->use_cull_bbox && ptc_gdp->cull_bbox.isInside( *pos_it ) ) ) { // add to our SOP geometry GEO_Point *pt = ptc_gdp->appendPoint(); pt->setPos( *pos_it ); (*pt->castAttribData<UT_Vector3>(n_attrib)) = *norm_it; (*pt->castAttribData<float>(r_attrib)) = *rad_it; const float *data = &*data_it; for ( unsigned int i=0; i<data_types.size(); ++i ) { if ( onlyOutputDisplayChannel ) { if ( i==displayChannel ) { pt->set( data_attribs[0], data, data_size[i] ); } data += data_size[i]; } else { pt->set( data_attribs[i], data, data_size[i] ); data += data_size[i]; } } } } // increment our interators pos_it++; norm_it++; rad_it++; data_it+=ptc_gdp->datasize; } // delete our particle primitive ptc_gdp->deletePrimitive(0,0); // info in sop's message area std::stringstream ss; ss << "Name: " << ptc_gdp->path << std::endl; ss << "Points: " << ptc_gdp->nPoints << " - [ " << ptc_gdp->nLoaded << " loaded ]" << std::endl; ss << "Channels: " << ptc_gdp->nChannels << std::endl; for ( unsigned int i=0; i<ptc_gdp->nChannels; ++i ) ss << " " << i << ": " << mChannelNames[i] << std::endl; addMessage( SOP_MESSAGE, ss.str().c_str() ); // Tell the interrupt server that we've completed boss->opEnd(); // force update? ptc_gdp->redraw = mRedraw; mRedraw = false; } // tidy up & go home unlockInputs(); return error(); }
void OBJ_SceneCacheTransform::expandHierarchy( const SceneInterface *scene ) { if ( !scene ) { return; } Parameters params; params.geometryType = getGeometryType(); params.depth = (Depth)evalInt( pDepth.getToken(), 0, 0 ); params.hierarchy = (Hierarchy)evalInt( pHierarchy.getToken(), 0, 0 ); params.tagGroups = getTagGroups(); getAttributeFilter( params.attributeFilter ); getAttributeCopy( params.attributeCopy ); getShapeFilter( params.shapeFilter ); getTagFilter( params.tagFilterStr ); getTagFilter( params.tagFilter ); getFullPathName( params.fullPathName ); if ( params.hierarchy == FlatGeometry ) { // Collapse first, in case the immediate object was already created on during parent expansion collapseHierarchy(); doExpandObject( scene, this, params ); setInt( pExpanded.getToken(), 0, 0, 1 ); return; } OBJ_Node *rootNode = this; if ( scene->hasObject() ) { Parameters rootParams( params ); rootParams.hierarchy = SubNetworks; rootParams.depth = Children; OBJ_Node *objNode = doExpandObject( scene, this, rootParams ); if ( params.hierarchy == Parenting ) { rootNode = objNode; } } else if ( params.hierarchy == Parenting ) { /// \todo: this is terrible. can we use the subnet input instead? rootNode = reinterpret_cast<OBJ_Node*>( createNode( "geo", "TMP" ) ); } if ( params.hierarchy == Parenting ) { rootNode->setIndirectInput( 0, this->getParentInput( 0 ) ); } UT_Interrupt *progress = UTgetInterrupt(); if ( !progress->opStart( ( "Expand Hierarchy for " + getPath() ).c_str() ) ) { return; } doExpandChildren( scene, rootNode, params ); setInt( pExpanded.getToken(), 0, 0, 1 ); if ( params.hierarchy == Parenting && !scene->hasObject() ) { destroyNode( rootNode ); } progress->opEnd(); }
OP_ERROR SOP_CudaParticles::cookMySop(OP_Context &context) { oldf = f; f = context.getFrame(); GEO_ParticleVertex* pvtx; double t = context.getTime(); particlesSystem->dt = 1/(OPgetDirector()->getChannelManager()->getSamplesPerSec() * SUBSTEPS(t)); particlesSystem->preview = PREVIEW(t); particlesSystem->partsLife = LIFE(t); particlesSystem->partsLifeVar = LIFEVAR(t); particlesSystem->velDamp = VELDAMP(t); particlesSystem->gravityStrength = GRAVITYSTR(t); particlesSystem->gravityDir = cu::make_float3(GRAVITYX(t),GRAVITYY(t),GRAVITYZ(t)); particlesSystem->fluidStrength = FLUIDSTR(t); particlesSystem->noiseAmp = cu::make_float3(NOISEAMP(t),NOISEAMP(t),NOISEAMP(t)); particlesSystem->noiseOct = NOISEOCT(t); particlesSystem->noiseFreq = NOISEFREQ(t); particlesSystem->noiseLac = NOISELACUN(t); particlesSystem->noiseOffset = cu::make_float3(NOISEOFFSETX(t),NOISEOFFSETY(t),NOISEOFFSETZ(t)); particlesSystem->pointSize = POINTSIZE(t); particlesSystem->opacity = OPACITY(t); particlesSystem->startColor = cu::make_float3(STARTCOLORX(t),STARTCOLORY(t),STARTCOLORZ(t)); particlesSystem->endColor = cu::make_float3(ENDCOLORX(t),ENDCOLORY(t),ENDCOLORZ(t)); UT_Interrupt *boss; OP_Node::flags().timeDep = 1; if (error() < UT_ERROR_ABORT) { boss = UTgetInterrupt(); // Start the interrupt server if (boss->opStart("Building Particles")){ //gdp->clearAndDestroy(); static float zero = 0.0; GB_AttributeRef partsAtt = gdp->addAttrib("cudaParticlesPreview", sizeof(int), GB_ATTRIB_INT, &zero); gdp->attribs().getElement().setValue<int>(partsAtt, particlesSystem->preview); GB_AttributeRef systemIdAtt = gdp->addAttrib("systemId", sizeof(int), GB_ATTRIB_INT, &zero); gdp->attribs().getElement().setValue<int>(systemIdAtt, particlesSystem->id); if (f < STARTFRAME(t)) { gdp->clearAndDestroy(); particlesSystem->resetParticles(); } else if (f == STARTFRAME(t)) { gdp->clearAndDestroy(); particlesSystem->resetParticles(); int maxParts = MAXPARTS(t); if (particlesSystem->nParts!=maxParts) particlesSystem->changeMaxParts(maxParts); //hSystem = (GEO_PrimParticle *)gdp->appendPrimitive(GEOPRIMPART); //hSystem->clearAndDestroy(); GB_AttributeRef hVelocity = gdp->addPointAttrib("v", sizeof(UT_Vector3),GB_ATTRIB_VECTOR, 0); GB_AttributeRef hLife = gdp->addPointAttrib("life", sizeof(float)*2,GB_ATTRIB_FLOAT, 0); if(particlesSystem->preview!=1) { UT_Vector4 orig = UT_Vector4(0,0,0,1); for (int i = 0; i<particlesSystem->nParts; i++) { GEO_Point* newPoint = gdp->appendPoint(); newPoint->setPos(orig); /*pvtx = hSystem->giveBirth(); GEO_Point* ppt = pvtx->getPt(); //ppt->getPos().assign(0,0,0,1);*/ hSystemInit = 1; } } } else { if(particlesSystem->nParts != -1) { if(lockInputs(context) >= UT_ERROR_ABORT) return error(); if(getInput(0)){ GU_Detail* emittersInput = (GU_Detail*)inputGeo(0, context); GEO_PointList emittersList = emittersInput->points(); int numEmitters = emittersList.entries(); if (numEmitters != particlesSystem->nEmit) { delete particlesSystem->emitters; particlesSystem->nEmit = numEmitters; particlesSystem->emitters = new ParticlesEmitter[numEmitters]; } GEO_AttributeHandle radAh, amountAh; GEO_AttributeHandle initVelAh, radVelAmpAh, noiseVelAmpAh, noiseVelOffsetAh, noiseVelOctAh, noiseVelLacAh, noiseVelFreqAh; radAh = emittersInput->getPointAttribute("radius"); amountAh = emittersInput->getPointAttribute("amount"); initVelAh = emittersInput->getPointAttribute("initVel"); radVelAmpAh = emittersInput->getPointAttribute("radVelAmp"); noiseVelAmpAh = emittersInput->getPointAttribute("noiseVelAmp"); noiseVelOffsetAh = emittersInput->getPointAttribute("noiseVelOffset"); noiseVelOctAh = emittersInput->getPointAttribute("noiseVelOct"); noiseVelLacAh = emittersInput->getPointAttribute("noiseVelLac"); noiseVelFreqAh = emittersInput->getPointAttribute("noiseVelFreq"); for (int i = 0; i < numEmitters; i++) { UT_Vector4 emitPos = emittersList[i]->getPos(); UT_Vector3 emitPos3(emitPos); particlesSystem->emitters[i].posX = emitPos.x(); particlesSystem->emitters[i].posY = emitPos.y(); particlesSystem->emitters[i].posZ = emitPos.z(); radAh.setElement(emittersList[i]); amountAh.setElement(emittersList[i]); initVelAh.setElement(emittersList[i]); radVelAmpAh.setElement(emittersList[i]); noiseVelAmpAh.setElement(emittersList[i]); noiseVelOffsetAh.setElement(emittersList[i]); noiseVelOctAh.setElement(emittersList[i]); noiseVelLacAh.setElement(emittersList[i]); noiseVelFreqAh.setElement(emittersList[i]); particlesSystem->emitters[i].radius = radAh.getF(0); particlesSystem->emitters[i].amount = amountAh.getF(0); particlesSystem->emitters[i].velX = initVelAh.getF(0); particlesSystem->emitters[i].velY = initVelAh.getF(1); particlesSystem->emitters[i].velZ = initVelAh.getF(2); particlesSystem->emitters[i].radVelAmp = radVelAmpAh.getF(0); particlesSystem->emitters[i].noiseVelAmpX = noiseVelAmpAh.getF(0); particlesSystem->emitters[i].noiseVelAmpY = noiseVelAmpAh.getF(1); particlesSystem->emitters[i].noiseVelAmpZ = noiseVelAmpAh.getF(2); particlesSystem->emitters[i].noiseVelOffsetX = noiseVelOffsetAh.getF(0); particlesSystem->emitters[i].noiseVelOffsetY = noiseVelOffsetAh.getF(1); particlesSystem->emitters[i].noiseVelOffsetZ = noiseVelOffsetAh.getF(2); particlesSystem->emitters[i].noiseVelOct = noiseVelOctAh.getF(0); particlesSystem->emitters[i].noiseVelLac = noiseVelLacAh.getF(0); particlesSystem->emitters[i].noiseVelFreq = noiseVelFreqAh.getF(0); } } else { particlesSystem->nEmit = 0; } if(getInput(1)){ GU_Detail* fluidInput = (GU_Detail*)inputGeo(1, context); GEO_AttributeHandle fluidIdAh= fluidInput->getDetailAttribute("solverId"); fluidIdAh.setElement(fluidInput); int sId = fluidIdAh.getI(); VHFluidSolver3D* curr3DSolver = VHFluidSolver3D::solverList[sId]; particlesSystem->fluidSolver = curr3DSolver; } unlockInputs(); if (f!=oldf) { particlesSystem->emitParticles(); particlesSystem->updateParticles(); } if(particlesSystem->preview!=1 && hSystemInit == 1) { cu::cudaMemcpy( particlesSystem->host_pos, particlesSystem->dev_pos, particlesSystem->nParts*sizeof(cu::float3), cu::cudaMemcpyDeviceToHost ); GEO_Point* ppt; int i = 0; UT_Vector4 p; FOR_ALL_GPOINTS(gdp, ppt) { ppt->getPos() = UT_Vector4(particlesSystem->host_pos[i*3], particlesSystem->host_pos[i*3+1], particlesSystem->host_pos[i*3+2], 1); i++; } /*pvtx = hSystem->iterateInit(); for (int i =0; i<particlesSystem->nParts; i++){ pvtx->getPos().assign(particlesSystem->host_pos[i*3], particlesSystem->host_pos[i*3+1], particlesSystem->host_pos[i*3+2], 1); pvtx = hSystem->iterateFastNext(pvtx); }*/ } } }
/// Cook the SOP! This method does all the work OP_ERROR SOP_OpHolder::cookMySop( OP_Context &context ) { IECore::MessageHandler::Scope handlerScope( getMessageHandler() ); // some defaults and useful variables Imath::Box3f bbox( Imath::V3f(-1,-1,-1), Imath::V3f(1,1,1) ); float now = context.getTime(); // force eval of our nodes parameters with our hidden parameter expression evalInt( "__evaluateParameters", 0, now ); // get our op IECore::OpPtr op = IECore::runTimeCast<IECore::Op>( getParameterised() ); // check for a valid parameterised on this SOP if ( !op ) { UT_String msg( "Op Holder has no parameterised class to operate on!" ); addError( SOP_MESSAGE, msg ); return error(); } if( lockInputs(context)>=UT_ERROR_ABORT ) { return error(); } // start our work UT_Interrupt *boss = UTgetInterrupt(); boss->opStart("Building OpHolder Geometry..."); gdp->clearAndDestroy(); setParameterisedValues( now ); try { // make our Cortex op do it's thing... op->operate(); // pass ourselves onto the GR_Cortex render hook IECoreHoudini::NodePassData data( this, IECoreHoudini::NodePassData::CORTEX_OPHOLDER ); GA_RWAttributeRef attrRef = gdp->createAttribute( GA_ATTRIB_DETAIL, GA_SCOPE_PRIVATE, "IECoreHoudiniNodePassData", NULL, NULL, "blinddata" ); GA_Attribute *attr = attrRef.getAttribute(); const GA_AIFBlindData *blindData = attr->getAIFBlindData(); blindData->setDataSize( attr, sizeof(IECoreHoudini::NodePassData), &data ); // if our result is a visible renderable then set our bounds on our output gdp const IECore::Object *result = op->resultParameter()->getValue(); IECore::ConstVisibleRenderablePtr renderable = IECore::runTimeCast<const IECore::VisibleRenderable>( result ); if ( renderable ) { Imath::Box3f bbox = renderable->bound(); gdp->cube( bbox.min.x, bbox.max.x, bbox.min.y, bbox.max.y, bbox.min.z, bbox.max.z, 0, 0, 0, 1, 1 ); } } catch( boost::python::error_already_set ) { addError( SOP_MESSAGE, "Error raised during Python evaluation!" ); IECorePython::ScopedGILLock lock; PyErr_Print(); } catch( const IECore::Exception &e ) { addError( SOP_MESSAGE, e.what() ); } catch( const std::exception &e ) { addError( SOP_MESSAGE, e.what() ); } catch( ... ) { addError( SOP_MESSAGE, "Caught unknown exception!" ); } // tidy up & go home! boss->opEnd(); unlockInputs(); return error(); }
OP_ERROR SOP_Scallop::cookMySop(OP_Context &context) { //OP_Node::flags().timeDep = 1; bool clip = (lockInputs(context) < UT_ERROR_ABORT); UT_BoundingBox bbox; if(clip) { const GU_Detail* input = inputGeo(0,context); if(input != NULL) { //UT_Matrix4 bm; int res = input->getBBox(&bbox); if(res == 0) clip = false; } else clip = false; unlockInputs(); }; float now = context.getTime(); Daemon::now=now; Daemon::caller=this; Daemon::bias = evalFloat("bias",0,now); UT_Ramp ramp; float rampout[4]; bool useRamp = (evalInt("parmcolor",0,now)!=0); if(useRamp) { //PRM_Template *rampTemplate = PRMgetRampTemplate ("ramp", PRM_MULTITYPE_RAMP_RGB, NULL, NULL); if (ramp.getNodeCount () < 2) { ramp.addNode (0, UT_FRGBA (0, 0, 0, 1)); ramp.addNode (1, UT_FRGBA (1, 1, 1, 1)); }; updateRampFromMultiParm(now, getParm("ramp"), ramp); }; gdp->clearAndDestroy(); bool showPts = (evalInt("showpts",0,now)!=0); /* if(showPts) { float sz = evalInt("ptssz",0,now); if(sz > 0) { float one = 1.0f; gdp->addAttribute("showpoints",4,GA_ATTRIB_FLOAT_&one); gdp->addAttribute("revealsize",4,GB_ATTRIB_FLOAT,&sz); }; }; */ int cnt = evalInt("daemons", 0, now); Daemon* daemons=new Daemon[cnt]; float weights = 0; int totd=0; for(int i=1;i<=cnt;i++) { bool skip = (evalIntInst("enabled#",&i,0,now)==0); if(skip) continue; Daemon& d = daemons[totd]; UT_String path = ""; evalStringInst("obj#", &i, path, 0, now); if(path == "") continue; SOP_Node* node = getSOPNode(path); OBJ_Node* obj = dynamic_cast<OBJ_Node*>(node->getParent()); if(obj == NULL) continue; addExtraInput(obj, OP_INTEREST_DATA); //d.xform = obj->getWorldTransform(context); // 10.0 obj->getWorldTransform(d.xform, context); d.weight = evalFloatInst("weight#",&i,0,now); if(!useRamp) { d.c[0] = evalFloatInst("color#",&i,0,now); d.c[1] = evalFloatInst("color#",&i,1,now); d.c[2] = evalFloatInst("color#",&i,2,now); }; int mth = evalIntInst("model#",&i,0,now); switch(mth) { case 1: d.method = Methods::Spherical; break; case 2: d.method = Methods::Polar; break; case 3: d.method = Methods::Swirl; break; case 4: d.method = Methods::Trigonometric; break; case 5: { UT_String script; evalStringInst("vexcode#", &i, script, 0, now); d.SetupCVEX(script); if(d.useVex) { OP_Node* shop = (OP_Node*)findSHOPNode(script); addExtraInput(shop, OP_INTEREST_DATA); } break; } case 0: default: d.method = Methods::Linear; }; d.power = evalFloatInst("power#",&i,0,now); d.radius = evalFloatInst("radius#",&i,0,now); d.parameter = evalFloatInst("parameter#",&i,0,now); weights+=d.weight; totd++; }; if(totd == 0) { delete [] daemons; return error(); } float base = 0.0; for(int i=0;i<totd;i++) { Daemon& d = daemons[i]; d.range[0]=base; d.range[1] = base+d.weight/weights; base=d.range[1]; }; int total = evalInt("count",0,now); int degr = evalInt("degr",0,now); total >>= degr; GA_RWHandleI cntt(gdp->addIntTuple(GA_ATTRIB_POINT, "count", 4, GA_Defaults(1.0))); GB_AttributeRef dt(gdp->addDiffuseAttribute(GEO_POINT_DICT)); gdp->addVariableName("Cd","Cd"); UT_Vector3 current(0,0,0); float C[3] = { 0,0,0 }; float R=1.0f; bool trackRadii = (evalInt("trackradii",0,now)!=0); float rScale = evalFloat("radiiscale",0,now); GB_AttributeRef rt; if(trackRadii) { float one=1.0f; rt = gdp->addPointAttrib("width",4,GB_ATTRIB_FLOAT,&one); if(!GBisAttributeRefValid(rt)) trackRadii=false; else gdp->addVariableName("width","WIDTH"); }; float zero=0.0f; GB_AttributeRef pt = gdp->addPointAttrib("parameter",4,GB_ATTRIB_FLOAT,&zero); if(GBisAttributeRefValid(pt)) gdp->addVariableName("parameter","PARAMETER"); float param=0.0f; srand(0); UT_Interrupt* boss = UTgetInterrupt(); boss->opStart("Computing..."); for(int i=-50;i<total;i++) { bool ok = false; if (boss->opInterrupt()) break; float w = double(rand())/double(RAND_MAX); for(int j=0;j<totd;j++) { ok = daemons[j].Transform(w,current,C,R,param); if(ok) break; }; if(i<0) continue; if(clip) { if(!bbox.isInside(current)) continue; }; if(ok) { GEO_Point* p = gdp->appendPoint(); p->setPos(current); float* Cd=p->castAttribData<float>(dt); if(useRamp) { ramp.rampLookup(param,C); } memcpy(Cd,C,12); if(trackRadii) { float* _R = p->castAttribData<float>(rt); *_R=rScale*R; }; if(GBisAttributeRefValid(pt)) { float* _p = p->castAttribData<float>(pt); *_p=param; } }; }; boss->opEnd(); delete [] daemons; return error(); };
OP_ERROR SOP_Ocean::cookMySop(OP_Context &context) { float now = context.getTime(); //std::cout << "cook ocean, t = " << now << std::endl; // lock inputs if (lockInputs(context) >= UT_ERROR_ABORT ) { return error(); } GEO_Point *ppt; UT_Interrupt *boss; // Check to see that there hasn't been a critical error in cooking the SOP. if (error() < UT_ERROR_ABORT) { boss = UTgetInterrupt(); // Start the interrupt server boss->opStart("Updating Ocean"); duplicatePointSource(0,context); int gridres = 1 << int(GRID_RES(now)); float stepsize = GRID_SIZE(now) / (float)gridres; bool do_chop = CHOP(now); bool do_jacobian = JACOBIAN(now); bool do_normals = NORMALS(now) && !do_chop; if (!_ocean || _ocean_needs_rebuild) { if (_ocean) { delete _ocean; } if (_ocean_context) { delete _ocean_context; } _ocean = new drw::Ocean(gridres,gridres,stepsize,stepsize, V(0),L(0),1.0,W(0),1-DAMP(0),ALIGN(0), DEPTH(0),SEED(0)); _ocean_scale = _ocean->get_height_normalize_factor(); _ocean_context = _ocean->new_context(true,do_chop,do_normals,do_jacobian); _ocean_needs_rebuild = false; // std::cout << "######### SOP, rebuilt ocean, norm_factor = " << _ocean_scale // << " chop = " << do_chop // << " norm = " << do_normals // << " jacobian = " << do_jacobian // << std::endl; } float chop_amount = CHOPAMOUNT(now); // sum up the waves at this timestep _ocean->update(TIME(now),*_ocean_context,true,do_chop,do_normals,do_jacobian, _ocean_scale * SCALE(now),chop_amount); bool linterp = ! INTERP(now); // get our attribute indices GA_RWAttributeRef normal_index; GA_RWAttributeRef jminus_index; GA_RWAttributeRef eminus_index; if (do_normals) { normal_index = gdp->addNormalAttribute(GEO_POINT_DICT); } if (do_jacobian) { // jminus_index = gdp->addPointAttrib("mineigval",sizeof(float),GB_ATTRIB_FLOAT,0); // eminus_index = gdp->addPointAttrib("mineigvec",sizeof(UT_Vector3),GB_ATTRIB_VECTOR,0); jminus_index = gdp->addTuple(GA_STORE_REAL32,GA_ATTRIB_POINT,"mineigval",1,GA_Defaults(0)); eminus_index = gdp->addFloatTuple(GA_ATTRIB_POINT,"mineigvec",1,GA_Defaults(0)); } // this is not that fast, can it be done quicker ??? GA_FOR_ALL_GPOINTS(gdp, ppt) { UT_Vector4 p = ppt->getPos(); if (linterp) { _ocean_context->eval_xz(p(0),p(2)); } else { _ocean_context->eval2_xz(p(0),p(2)); } if (do_chop) { p.assign( p(0) + _ocean_context->disp[0], p(1) + _ocean_context->disp[1], p(2) + _ocean_context->disp[2] ); } else { // ppt->getPos()(1) += _ocean_context->disp[1]; UT_Vector4 tmp_p = ppt->getPos(); tmp_p(1) += _ocean_context->disp[1]; ppt->setPos(tmp_p); } if (do_normals) { /* UT_Vector3* normal = (UT_Vector3*) ppt->castAttribData<UT_Vector3>(normal_index); normal->assign(_ocean_context->normal[0], _ocean_context->normal[1], _ocean_context->normal[2]); normal->normalize(); */ ppt->getValue<UT_Vector3>(normal_index).assign(_ocean_context->normal[0], _ocean_context->normal[1], _ocean_context->normal[2]); ppt->getValue<UT_Vector3>(normal_index).normalize(); } if (do_jacobian) {/* float *js = (float*)ppt->castAttribData<float>(jminus_index); *js = _ocean_context->Jminus; UT_Vector3* eminus = (UT_Vector3*)ppt->castAttribData<UT_Vector3>(eminus_index); eminus->assign(_ocean_context->Eminus[0],0,_ocean_context->Eminus[1]); */ ppt->setValue<float>(jminus_index,_ocean_context->Jminus); ppt->getValue<UT_Vector3>(eminus_index).assign(_ocean_context->Eminus[0],0,_ocean_context->Eminus[1]); } ppt->setPos(p); }
OP_ERROR SOP_FluidSolver2D::cookMySop(OP_Context &context) { oldf = f; double t = context.getTime(); int f = context.getFrame(); UT_Interrupt *boss; GU_PrimVolume *volume; OP_Node::flags().timeDep = 1; fluidSolver->fps = OPgetDirector()->getChannelManager()->getSamplesPerSec(); int newResX = RESX(t); int newResY = RESY(t); if ( newResX != fluidSolver->res.x || newResY != fluidSolver->res.y) { fluidSolver->changeFluidRes(newResX,newResY); } UT_Vector3 fluidPos(POSX(t), POSY(t), POSZ(t)); UT_Vector3 fluidRot(ROTX(t), ROTY(t), ROTZ(t)); fluidRot.degToRad(); fluidSolver->fluidSize.x = FLUIDSIZEX(t); fluidSolver->fluidSize.y = FLUIDSIZEY(t); fluidSolver->borderNegX = BORDERNEGX(t); fluidSolver->borderPosX = BORDERPOSX(t); fluidSolver->borderNegY = BORDERNEGY(t); fluidSolver->borderPosY = BORDERPOSY(t); fluidSolver->preview = PREVIEW(t); fluidSolver->previewType = PREVIEWTYPE(t); fluidSolver->bounds = BOUNDS(t); fluidSolver->substeps = SUBSTEPS(t); fluidSolver->jacIter = JACITER(t); fluidSolver->densDis = DENSDIS(t); fluidSolver->densBuoyStrength = DENSBUOYSTRENGTH(t); float ddirX = DENSBUOYDIRX(t); float ddirY = DENSBUOYDIRY(t); fluidSolver->densBuoyDir = cu::make_float2(ddirX,ddirY); fluidSolver->velDamp = VELDAMP(t); fluidSolver->vortConf = VORTCONF(t); fluidSolver->noiseStr = NOISESTR(t); fluidSolver->noiseFreq = NOISEFREQ(t); fluidSolver->noiseOct = NOISEOCT(t); fluidSolver->noiseLacun = NOISELACUN(t); fluidSolver->noiseSpeed = NOISESPEED(t); fluidSolver->noiseAmp = NOISEAMP(t); if (error() < UT_ERROR_ABORT) { boss = UTgetInterrupt(); gdp->clearAndDestroy(); // Start the interrupt server if (boss->opStart("Building Volume")){ static float zero = 0.0; #ifdef HOUDINI_11 GB_AttributeRef fluidAtt = gdp->addAttrib("cudaFluidPreview", sizeof(int), GB_ATTRIB_INT, &zero); gdp->attribs().getElement().setValue<int>(fluidAtt, fluidSolver->preview); GB_AttributeRef solverIdAtt = gdp->addAttrib("solverId", sizeof(int), GB_ATTRIB_INT, &zero); gdp->attribs().getElement().setValue<int>(solverIdAtt, fluidSolver->id); #else GA_WOAttributeRef fluidAtt = gdp->addIntTuple(GA_ATTRIB_DETAIL, "cudaFluidPreview", 1); gdp->element().setValue<int>(fluidAtt, fluidSolver->preview); GA_WOAttributeRef solverIdAtt = gdp->addIntTuple(GA_ATTRIB_DETAIL, "solverId", 1); gdp->element().setValue<int>(solverIdAtt, fluidSolver->id); #endif UT_Matrix3 xform; const UT_XformOrder volXFormOrder; volume = (GU_PrimVolume *)GU_PrimVolume::build(gdp); #ifdef HOUDINI_11 volume->getVertex().getPt()->getPos() = fluidPos; #else volume->getVertexElement(0).getPt()->setPos(fluidPos); #endif xform.identity(); xform.scale(fluidSolver->fluidSize.x*0.5, fluidSolver->fluidSize.y*0.5, 0.25); xform.rotate(fluidRot.x(), fluidRot.y(), fluidRot.z(), volXFormOrder); volume->setTransform(xform); xform.identity(); xform.rotate(fluidRot.x(), fluidRot.y(), fluidRot.z(), volXFormOrder); xform.invert(); if(lockInputs(context) >= UT_ERROR_ABORT) return error(); if(getInput(0)){ GU_Detail* emittersInput = (GU_Detail*)inputGeo(0, context); GEO_PointList emittersList = emittersInput->points(); int numEmitters = emittersList.entries(); if (numEmitters != fluidSolver->nEmit) { delete fluidSolver->emitters; fluidSolver->nEmit = numEmitters; fluidSolver->emitters = new FluidEmitter[numEmitters]; } GEO_AttributeHandle radAh, amountAh; radAh = emittersInput->getPointAttribute("radius"); amountAh = emittersInput->getPointAttribute("amount"); for (int i = 0; i < numEmitters; i++) { UT_Vector4 emitPos = emittersList[i]->getPos(); UT_Vector3 emitPos3(emitPos); emitPos3 -= fluidPos; emitPos3 = emitPos3*xform; fluidSolver->emitters[i].posX = emitPos3.x(); fluidSolver->emitters[i].posY = emitPos3.y(); radAh.setElement(emittersList[i]); amountAh.setElement(emittersList[i]); fluidSolver->emitters[i].radius = radAh.getF(0); fluidSolver->emitters[i].amount = amountAh.getF(0); } } else { fluidSolver->nEmit = 0; } if(getInput(1)) { GU_Detail* collidersInput = (GU_Detail*)inputGeo(1, context); GEO_PointList collidersList = collidersInput->points(); int numColliders = collidersList.entries(); if (numColliders != fluidSolver->nColliders) { delete fluidSolver->colliders; fluidSolver->nColliders = numColliders; fluidSolver->colliders = new Collider[numColliders]; } GEO_AttributeHandle colRadAh; colRadAh = collidersInput->getPointAttribute("radius"); for (int i = 0; i < numColliders; i++) { UT_Vector4 colPos = collidersList[i]->getPos(); UT_Vector3 colPos3(colPos); colPos3 -= fluidPos; colPos3 = colPos3*xform; if (f > STARTFRAME(t)) { fluidSolver->colliders[i].oldPosX = fluidSolver->colliders[i].posX; fluidSolver->colliders[i].oldPosY = fluidSolver->colliders[i].posY; } else { fluidSolver->colliders[i].oldPosX = colPos3.x(); fluidSolver->colliders[i].oldPosY = colPos3.y(); } fluidSolver->colliders[i].posX = colPos3.x(); fluidSolver->colliders[i].posY = colPos3.y(); colRadAh.setElement(collidersList[i]); fluidSolver->colliders[i].radius = colRadAh.getF(0); } } else { fluidSolver->nColliders = 0; } unlockInputs(); if (f <= STARTFRAME(t)) { fluidSolver->resetFluid(); if (fluidSolver->preview != 1) { { UT_VoxelArrayWriteHandleF handle = volume->getVoxelWriteHandle(); handle->constant(0); } } } else { if (f!=oldf) { fluidSolver->solveFluid(); } if (fluidSolver->preview != 1) { cu::cudaMemcpy( fluidSolver->host_dens, fluidSolver->dev_dens, fluidSolver->res.x*fluidSolver->res.y*sizeof(float), cu::cudaMemcpyDeviceToHost ); { UT_VoxelArrayWriteHandleF handle = volume->getVoxelWriteHandle(); handle->size(fluidSolver->res.x, fluidSolver->res.y, 1); for (int i = 0; i < fluidSolver->res.x; i++) { for (int j = 0; j < fluidSolver->res.y; j++) { handle->setValue(i, j, 0, fluidSolver->host_dens[(j*fluidSolver->res.x + i)]); } } } } } select(GU_SPrimitive); } // Tell the interrupt server that we've completed. Must do this // regardless of what opStart() returns. boss->opEnd(); } gdp->notifyCache(GU_CACHE_ALL); return error(); }
OP_ERROR SOP_FluidSolver3D::cookMySop(OP_Context &context) { oldf = f; f = context.getFrame(); double t = context.getTime(); fluidSolver->fps = OPgetDirector()->getChannelManager()->getSamplesPerSec(); UT_Interrupt *boss; GU_PrimVolume *volume; GU_PrimVolume *velXVolume; GU_PrimVolume *velYVolume; GU_PrimVolume *velZVolume; OP_Node::flags().timeDep = 1; int newResX = RESX(t); int newResY = RESY(t); int newResZ = RESZ(t); if ( newResX != fluidSolver->res.width || newResY != fluidSolver->res.height || newResZ != fluidSolver->res.depth) { fluidSolver->changeFluidRes(newResX,newResY,newResZ); } UT_Vector3 fluidPos(POSX(t), POSY(t), POSZ(t)); UT_Vector3 fluidRot(ROTX(t), ROTY(t), ROTZ(t)); fluidRot.degToRad(); fluidSolver->fluidSize.x = FLUIDSIZEX(t); fluidSolver->fluidSize.y = FLUIDSIZEY(t); fluidSolver->fluidSize.z = FLUIDSIZEZ(t); fluidSolver->borderNegX = BORDERNEGX(t); fluidSolver->borderPosX = BORDERPOSX(t); fluidSolver->borderNegY = BORDERNEGY(t); fluidSolver->borderPosY = BORDERPOSY(t); fluidSolver->borderNegZ = BORDERNEGZ(t); fluidSolver->borderPosZ = BORDERPOSZ(t); fluidSolver->substeps = SUBSTEPS(t); fluidSolver->jacIter = JACITER(t); fluidSolver->densDis = DENSDIS(t); fluidSolver->densBuoyStrength = DENSBUOYSTRENGTH(t); float ddirX = DENSBUOYDIRX(t); float ddirY = DENSBUOYDIRY(t); float ddirZ = DENSBUOYDIRZ(t); fluidSolver->densBuoyDir = cu::make_float3(ddirX,ddirY,ddirZ); fluidSolver->velDamp = VELDAMP(t); fluidSolver->vortConf = VORTCONF(t); fluidSolver->noiseStr = NOISESTR(t); fluidSolver->noiseFreq = NOISEFREQ(t); fluidSolver->noiseOct = NOISEOCT(t); fluidSolver->noiseLacun = NOISELACUN(t); fluidSolver->noiseSpeed = NOISESPEED(t); fluidSolver->noiseAmp = NOISEAMP(t); fluidSolver->preview = PREVIEW(t); fluidSolver->drawCube = DRAWCUBE(t); fluidSolver->opaScale = OPASCALE(t); fluidSolver->stepMul = STEPMUL(t); fluidSolver->displayRes = DISPLAYRES(t); fluidSolver->doShadows = DOSHADOWS(t); float lightPosX = LIGHTPOSX(t); float lightPosY = LIGHTPOSY(t); float lightPosZ = LIGHTPOSZ(t); fluidSolver->lightPos = cu::make_float3(lightPosX,lightPosY,lightPosZ); fluidSolver->shadowDens = SHADOWDENS(t); fluidSolver->shadowStepMul = SHADOWSTEPMUL(t); fluidSolver->shadowThres = SHADOWTHRES(t); fluidSolver->displaySlice = DISPLAYSLICE(t); fluidSolver->sliceType = SLICETYPE(t); fluidSolver->sliceAxis = SLICEAXIS(t); fluidSolver->slicePos = SLICEPOS(t); fluidSolver->sliceBounds = SLICEBOUNDS(t); if (error() < UT_ERROR_ABORT) { boss = UTgetInterrupt(); gdp->clearAndDestroy(); // Start the interrupt server if (boss->opStart("Building Volume")){ static float zero = 0.0; GB_AttributeRef fluidAtt = gdp->addAttrib("cudaFluid3DPreview", sizeof(int), GB_ATTRIB_INT, &zero); gdp->attribs().getElement().setValue<int>(fluidAtt, fluidSolver->preview); GB_AttributeRef fluidSliceAtt = gdp->addAttrib("sliceDisplay", sizeof(int), GB_ATTRIB_INT, &zero); gdp->attribs().getElement().setValue<int>(fluidSliceAtt, fluidSolver->displaySlice); GB_AttributeRef solverIdAtt = gdp->addAttrib("solverId", sizeof(int), GB_ATTRIB_INT, &zero); gdp->attribs().getElement().setValue<int>(solverIdAtt, fluidSolver->id); GEO_AttributeHandle name_gah; int def = -1; gdp->addPrimAttrib("name", sizeof(int), GB_ATTRIB_INDEX, &def); name_gah = gdp->getPrimAttribute("name"); UT_Matrix3 xform; const UT_XformOrder volXFormOrder; volume = (GU_PrimVolume *)GU_PrimVolume::build(gdp); volume->getVertex().getPt()->getPos() = fluidPos; xform.identity(); xform.scale(fluidSolver->fluidSize.x*0.5, fluidSolver->fluidSize.y*0.5, fluidSolver->fluidSize.z*0.5); xform.rotate(fluidRot.x(), fluidRot.y(), fluidRot.z(), volXFormOrder); volume->setTransform(xform); name_gah.setElement(volume); name_gah.setString("density"); velXVolume = (GU_PrimVolume *)GU_PrimVolume::build(gdp); velXVolume->getVertex().getPt()->getPos() = fluidPos; velXVolume->setTransform(xform); name_gah.setElement(velXVolume); name_gah.setString("vel.x"); velYVolume = (GU_PrimVolume *)GU_PrimVolume::build(gdp); velYVolume->getVertex().getPt()->getPos() = fluidPos; velYVolume->setTransform(xform); name_gah.setElement(velYVolume); name_gah.setString("vel.y"); velZVolume = (GU_PrimVolume *)GU_PrimVolume::build(gdp); velZVolume->getVertex().getPt()->getPos() = fluidPos; velZVolume->setTransform(xform); name_gah.setElement(velZVolume); name_gah.setString("vel.z"); xform.identity(); xform.rotate(fluidRot.x(), fluidRot.y(), fluidRot.z(), volXFormOrder); xform.invert(); if(lockInputs(context) >= UT_ERROR_ABORT) return error(); if(getInput(0)){ GU_Detail* emittersInput = (GU_Detail*)inputGeo(0, context); GEO_PointList emittersList = emittersInput->points(); int numEmitters = emittersList.entries(); if (numEmitters != fluidSolver->nEmit) { delete fluidSolver->emitters; fluidSolver->nEmit = numEmitters; fluidSolver->emitters = new VHFluidEmitter[numEmitters]; } GEO_AttributeHandle radAh, amountAh; radAh = emittersInput->getPointAttribute("radius"); amountAh = emittersInput->getPointAttribute("amount"); for (int i = 0; i < numEmitters; i++) { UT_Vector4 emitPos = emittersList[i]->getPos(); UT_Vector3 emitPos3(emitPos); emitPos3 -= fluidPos; emitPos3 = emitPos3*xform; fluidSolver->emitters[i].posX = emitPos3.x(); fluidSolver->emitters[i].posY = emitPos3.y(); fluidSolver->emitters[i].posZ = emitPos3.z(); radAh.setElement(emittersList[i]); amountAh.setElement(emittersList[i]); fluidSolver->emitters[i].radius = radAh.getF(0); fluidSolver->emitters[i].amount = amountAh.getF(0); } } else { fluidSolver->nEmit = 0; } if(getInput(1)) { GU_Detail* collidersInput = (GU_Detail*)inputGeo(1, context); GEO_PointList collidersList = collidersInput->points(); int numColliders = collidersList.entries(); if (numColliders != fluidSolver->nColliders) { delete fluidSolver->colliders; fluidSolver->nColliders = numColliders; fluidSolver->colliders = new VHFluidCollider[numColliders]; } GEO_AttributeHandle colRadAh; colRadAh = collidersInput->getPointAttribute("radius"); for (int i = 0; i < numColliders; i++) { UT_Vector4 colPos = collidersList[i]->getPos(); UT_Vector3 colPos3(colPos); colPos3 -= fluidPos; colPos3 = colPos3*xform; if (f > STARTFRAME(t)) { fluidSolver->colliders[i].oldPosX = fluidSolver->colliders[i].posX; fluidSolver->colliders[i].oldPosY = fluidSolver->colliders[i].posY; fluidSolver->colliders[i].oldPosZ = fluidSolver->colliders[i].posZ; } else { fluidSolver->colliders[i].oldPosX = colPos3.x(); fluidSolver->colliders[i].oldPosY = colPos3.y(); fluidSolver->colliders[i].oldPosZ = colPos3.z(); } fluidSolver->colliders[i].posX = colPos3.x(); fluidSolver->colliders[i].posY = colPos3.y(); fluidSolver->colliders[i].posZ = colPos3.z(); colRadAh.setElement(collidersList[i]); fluidSolver->colliders[i].radius = colRadAh.getF(0); } } else { fluidSolver->nColliders = 0; } unlockInputs(); if (f <= STARTFRAME(t)) { fluidSolver->resetFluid(); if (COPYDENS(t)) { { UT_VoxelArrayWriteHandleF handle = volume->getVoxelWriteHandle(); handle->constant(0); UT_VoxelArrayWriteHandleF velXHandle = velXVolume->getVoxelWriteHandle(); velXHandle->constant(0); UT_VoxelArrayWriteHandleF velYHandle = velYVolume->getVoxelWriteHandle(); velYHandle->constant(0); UT_VoxelArrayWriteHandleF velZHandle = velZVolume->getVoxelWriteHandle(); velZHandle->constant(0); } } } else { if (f!=oldf) { fluidSolver->solveFluid(); } if (COPYDENS(t)) { cu::cudaMemcpy( fluidSolver->host_dens, fluidSolver->dev_dens, fluidSolver->res.width*fluidSolver->res.height*fluidSolver->res.depth*sizeof(float), cu::cudaMemcpyDeviceToHost ); { UT_VoxelArrayWriteHandleF handle = volume->getVoxelWriteHandle(); handle->size(fluidSolver->res.width, fluidSolver->res.height, fluidSolver->res.depth); for (int i = 0; i < fluidSolver->res.width; i++) { for (int j = 0; j < fluidSolver->res.height; j++) { for (int k = 0; k < fluidSolver->res.depth; k++) { handle->setValue(i, j, k, fluidSolver->host_dens[k*fluidSolver->res.width*fluidSolver->res.height + j*fluidSolver->res.width + i]); } } } } if (COPYVEL(t)) { cu::cudaMemcpy( fluidSolver->host_vel, fluidSolver->dev_vel, fluidSolver->res.width*fluidSolver->res.height*fluidSolver->res.depth*sizeof(cu::float4), cu::cudaMemcpyDeviceToHost ); { UT_VoxelArrayWriteHandleF velXHandle = velXVolume->getVoxelWriteHandle(); velXHandle->size(fluidSolver->res.width, fluidSolver->res.height, fluidSolver->res.depth); UT_VoxelArrayWriteHandleF velYHandle = velYVolume->getVoxelWriteHandle(); velYHandle->size(fluidSolver->res.width, fluidSolver->res.height, fluidSolver->res.depth); UT_VoxelArrayWriteHandleF velZHandle = velZVolume->getVoxelWriteHandle(); velZHandle->size(fluidSolver->res.width, fluidSolver->res.height, fluidSolver->res.depth); for (int i = 0; i < fluidSolver->res.width; i++) { for (int j = 0; j < fluidSolver->res.height; j++) { for (int k = 0; k < fluidSolver->res.depth; k++) { velXHandle->setValue(i, j, k, fluidSolver->host_vel[4*(k*fluidSolver->res.width*fluidSolver->res.height + j*fluidSolver->res.width + i)]); velYHandle->setValue(i, j, k, fluidSolver->host_vel[4*(k*fluidSolver->res.width*fluidSolver->res.height + j*fluidSolver->res.width + i)+1]); velZHandle->setValue(i, j, k, fluidSolver->host_vel[4*(k*fluidSolver->res.width*fluidSolver->res.height + j*fluidSolver->res.width + i)+2]); } } } } } } } select(GU_SPrimitive); } // Tell the interrupt server that we've completed. Must do this // regardless of what opStart() returns. boss->opEnd(); } gdp->notifyCache(GU_CACHE_ALL); return error(); }