Exemple #1
0
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 {
Exemple #2
0
bool
GusdUSD_StageProxy::MultiAccessor::Bind(
    const UT_Array<GusdUSD_StageProxyHandle>& proxies,
    const UT_Array<SdfPath>& paths,
    UT_Array<UsdPrim>& prims,
    UsdStage::InitialLoadSet loadSet,
    GusdUT_ErrorContext* err)
{
    Release();

    UT_ASSERT(paths.isEmpty() || paths.size() == proxies.size());

    if(proxies.size() == 0)
        return true;

    /* We have an input arrays of proxies and paths.
       Many of the paths will be associated with the same proxy,
       but they may also point at different proxies.
       
       To avoid having to lock every individual prim, we want to compute
       a mapping of indices from those input arrays into indices in
       an array containing just the unique set of proxies.*/

    UT_Array<GusdUSD_StageProxyHandle> uniqueProxies;
    if(!_ComputeUniqueProxies(uniqueProxies, _indexMap, proxies))
        return false;

    _numAccessors = uniqueProxies.size();
    _accessors = new Accessor[_numAccessors];
    _size = proxies.size();

    /* Now the unique set of proxies is known, so acquire accessors
       (I.e., lock and load stages) */
    std::atomic_bool workerInterrupt(false);
    UTparallelForHeavyItems(UT_BlockedRange<size_t>(0, _numAccessors),
                            _BindAccessorsFn(_accessors, uniqueProxies,
                                             loadSet, err, workerInterrupt));
    if(UTgetInterrupt()->opInterrupt() || workerInterrupt)
        return false;

    /* Any entries referencing proxies that couldn't be bound 
       should have an invalid index; no point in accessing invalid accessors.*/
    for(exint i = 0; i < _indexMap.size(); ++i) {
        int idx = _indexMap(i);
        if(idx >= 0) {
            if(!_accessors[idx])
                _indexMap(i) = -1;
        }
    }

    return _GetPrims(paths, prims, err);
}
Exemple #3
0
bool
GusdUSD_StageProxy::MultiAccessor::_GetPrims(
    const UT_Array<SdfPath>& primPaths,
    UT_Array<UsdPrim>& prims,
    GusdUT_ErrorContext* err)
{
    if(!_Load(primPaths))
        return false;

    prims.setSize(primPaths.size());

    std::atomic_bool workerInterrupt(false);
    UTparallelFor(UT_BlockedRange<size_t>(0, primPaths.size()),
                  _GetPrimsFn(*this, primPaths, prims, err, workerInterrupt));
    return !UTgetInterrupt()->opInterrupt() && !workerInterrupt;
}
Exemple #4
0
        void    operator()(const UT_BlockedRange<size_t>& r) const
                {
                    auto* boss = UTgetInterrupt();
                    char bcnt = 0;

                    for(size_t i = r.begin(); i < r.end(); ++i) {
                        if(BOOST_UNLIKELY(!++bcnt && boss->opInterrupt()))
                            return;
                        
                        exint idx = _indexMap(i);
                        if(idx >= 0) {
                            if(auto* loader = _loaders(idx)) {
                                const SdfPath& path = _paths(i);
                                if(!path.IsEmpty() && !loader->IsLoaded(path))
                                    _pathSets(idx)->insert(path);
                            }
                        }
                    }
                }
Exemple #5
0
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);

						}*/

					}
				}

			}
Exemple #6
0
bool
GusdUSD_StageProxy::MultiAccessor::_Load(const UT_Array<SdfPath>& paths)
{
    if(paths.isEmpty())
        return true;

    UT_ASSERT_P(paths.size() == _size);

    typedef tbb::concurrent_unordered_set<
        SdfPath,SdfPath::Hash> ConcurrentPathSet;

    struct _ComputeUnloadedPrimsFn
    {
        _ComputeUnloadedPrimsFn(const UT_Array<SdfPath>& paths,
                                const UT_Array<exint>& indexMap,
                                const UT_Array<_PrimLoader*>& loaders,
                                UT_Array<ConcurrentPathSet*>& pathSets)
            : _paths(paths), _indexMap(indexMap),
              _loaders(loaders), _pathSets(pathSets) {}

        void    operator()(const UT_BlockedRange<size_t>& r) const
                {
                    auto* boss = UTgetInterrupt();
                    char bcnt = 0;

                    for(size_t i = r.begin(); i < r.end(); ++i) {
                        if(BOOST_UNLIKELY(!++bcnt && boss->opInterrupt()))
                            return;
                        
                        exint idx = _indexMap(i);
                        if(idx >= 0) {
                            if(auto* loader = _loaders(idx)) {
                                const SdfPath& path = _paths(i);
                                if(!path.IsEmpty() && !loader->IsLoaded(path))
                                    _pathSets(idx)->insert(path);
                            }
                        }
                    }
                }

    private:
        const UT_Array<SdfPath>&        _paths;
        const UT_Array<exint>&          _indexMap;
        const UT_Array<_PrimLoader*>&   _loaders;
        UT_Array<ConcurrentPathSet*>    _pathSets;
    };

    /* Compute sets of unloaded prims.
       This constitutes the bulk of binding time, so do this parallel.*/
    UT_Array<_PrimLoader*> loaders(_numAccessors, _numAccessors);
    UT_Array<ConcurrentPathSet*> pathSets(_numAccessors, _numAccessors);
    for(exint i = 0; i < _numAccessors; ++i) {
        if ( _accessors[i] ) {
            auto* loader = _accessors[i].GetProxy()->_primLoader;
            if(loader) {
                loaders(i) = loader;
                pathSets(i) = new ConcurrentPathSet;
            }
        }
    }

    UTparallelFor(UT_BlockedRange<size_t>(0, _size),
                  _ComputeUnloadedPrimsFn(paths, _indexMap, loaders, pathSets));

    if(UTgetInterrupt()->opInterrupt())
        return false;

    /* Load the actual prims.
       This could be done in parallel, but is probably not worth it since
       there's only work to perform the first time a prim load is requested.*/
    for(exint i = 0; i < _numAccessors; ++i) {
        if(auto* pathSet = pathSets(i)) {
            SdfPathSet pathsToLoad(pathSet->begin(), pathSet->end());
            _accessors[i]._Load(pathsToLoad);
            
            delete pathSet;
        }
    }

    return true;
}
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();
}
Exemple #9
-1
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();
}