Example #1
0
static void
addField(GU_Detail *gdp, const SIM_RawField *rawfield)
{
    GU_PrimVolume	*vol;

    vol = (GU_PrimVolume *) GU_PrimVolume::build(gdp);

    vol->getVertex().getPt()->setPos(
	rawfield->getOrig() + rawfield->getSize()*0.5 );
    
    UT_Matrix3		 scale;
    scale.identity();
    scale.scale(rawfield->getSize().x(), rawfield->getSize().y(), rawfield->getSize().z());
    scale.scale(0.5, 0.5, 0.5);
    vol->setTransform(scale);

    // If we use setVoxels, we'll have to make a copy of the field.
    // If we use steal, we can avoid this, but then we *must* leak
    // the gdp or we'll delete the field out from under DOPs.
    // vol->setVoxels(rawfield->fieldNC());
    vol->stealVoxels(rawfield->fieldNC());
}
Example #2
0
void GR_Fluid::renderWire(GU_Detail *gdp, RE_Render &ren, const GR_AttribOffset & /*ptinfo*/,
		    const GR_DisplayOption *dopt, float /*lod*/, const GU_PrimGroupClosure * /*hidden_geometry*/)
{

	GEO_AttributeHandle fluidAh= gdp->getDetailAttribute("cudaFluidPreview");
	fluidAh.setElement(gdp);

	GEO_AttributeHandle fluid3DAh= gdp->getDetailAttribute("cudaFluid3DPreview");
	fluid3DAh.setElement(gdp);

	GEO_AttributeHandle fluid3DSliceAh= gdp->getDetailAttribute("sliceDisplay");
	fluid3DSliceAh.setElement(gdp);

	GEO_AttributeHandle fluidAh= gdp->getDetailAttribute("cudaFluidPreview");
	fluidAh.setElement(gdp);

	GEO_AttributeHandle fluidIdAh= gdp->getDetailAttribute("solverId");
	fluidIdAh.setElement(gdp);

	if (fluidAh.getI()== 1) {

		VHFluidSolver* currSolver = VHFluidSolver::solverList[fluidIdAh.getI()];

		UT_Vector4 fluidPos(0,0,0);
		UT_Vector3D fluidRot(0,0,0);

		if(gdp->volumeCount() == 1) {
			GEO_Primitive* pprim = gdp->primitives().head();
			GU_PrimVolume* volume = (GU_PrimVolume *)pprim;
			UT_Matrix4 fluidRotMat;
			volume->getTransform4(fluidRotMat);

			UT_XformOrder rotOrder;
			UT_Vector3D scale, trans;
			fluidRotMat.explode(rotOrder, fluidRot, scale, trans);
			fluidRot.radToDeg();
			fluidPos = volume->getVertex().getPt()->getPos();
		}

		float sizeX = currSolver->fluidSize.x*0.5;
		float sizeY = currSolver->fluidSize.y*0.5;

		int newResX = currSolver->res.x;
		int newResY = currSolver->res.y;


		if(displayX != newResX || displayY != newResY) {
			displayX = newResX;
			displayY = newResY;
			initPixelBuffer(true);
		}
					
		cu::cutilSafeCall(cu::cudaGraphicsMapResources(1, &cuda_pbo_resource, 0));
		cu::float4 *d_output;
		size_t num_bytes; 
		cu::cutilSafeCall(cu::cudaGraphicsResourceGetMappedPointer((void **)&d_output, &num_bytes,  cuda_pbo_resource));
		cu::cudaMemset(d_output, 0, displayX*displayY*sizeof(cu::float4));

		currSolver->renderFluid(d_output);

		cu::cutilSafeCall(cu::cudaGraphicsUnmapResources(1, &cuda_pbo_resource, 0));

		//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
		glBindTexture(GL_TEXTURE_2D, gl_Tex);
		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, displayX, displayY, GL_RGBA, GL_FLOAT, 0);
		glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

		glEnable(GL_TEXTURE_2D);

		glPushMatrix();
		glTranslatef(fluidPos.x(),fluidPos.y(),fluidPos.z());
		glRotatef(fluidRot.z(),0,0,1);
		glRotatef(fluidRot.y(),0,1,0);
		glRotatef(fluidRot.x(),1,0,0);

		//glColor3f(1.0,1.0,1.0);
		//glDisable(GL_BLEND);
		//glDisable(GL_LIGHTING);

		//glBegin( GL_QUADS );
		//glTexCoord2f(0.0f, 0.0f); glVertex3f(-sizeX,-sizeY,0.0f);
		//glTexCoord2f(0.0f, 1.0f); glVertex3f(-sizeX,sizeY,0.0f);
		//glTexCoord2f(1.0f, 1.0f); glVertex3f(sizeX,sizeY,0.0f);
		//glTexCoord2f(1.0f, 0.0f); glVertex3f(sizeX,-sizeY,0.0f);
		//glEnd();

		ren.setColor(1,1,1,1);
		ren.blend(0);
		ren.toggleLighting(0);


		const float t0[] = {0,0};
		const float t1[] = {0,1};
		const float t2[] = {1,1};
		const float t3[] = {1,0};

		ren.beginQuads();
		ren.t2DW(t0); ren.vertex3DW(-sizeX,-sizeY,0.0f);
		ren.t2DW(t1); ren.vertex3DW(-sizeX,sizeY,0.0f);
		ren.t2DW(t2); ren.vertex3DW(sizeX,sizeY,0.0f);
		ren.t2DW(t3); ren.vertex3DW(sizeX,-sizeY,0.0f);
		ren.endQuads();

		glDisable(GL_TEXTURE_2D);

		glBindTexture(GL_TEXTURE_2D, 0);

		ren.beginClosedLine();
		ren.vertex3DW(-sizeX,-sizeY,0.0f);
		ren.vertex3DW(-sizeX,sizeY,0.0f);
		ren.vertex3DW(sizeX,sizeY,0.0f);
		ren.vertex3DW(sizeX,-sizeY,0.0f);
		ren.endClosedLine();

		ren.toggleLighting(1);

		glPopMatrix();

	}

	if (fluid3DAh.getI() == 1 || fluid3DSliceAh.getI()== 1) {

		ren.toggleLighting(0);

		VHFluidSolver3D* curr3DSolver = VHFluidSolver3D::solverList[fluidIdAh.getI()];

		UT_Vector4 fluidPos(0,0,0);
		UT_Vector3D fluidRot(0,0,0);

		if(gdp->volumeCount() == 1) {
			GEO_Primitive* pprim = gdp->primitives().head();
			GU_PrimVolume* volume = (GU_PrimVolume *)pprim;
			UT_Matrix4 fluidRotMat;
			volume->getTransform4(fluidRotMat);

			UT_XformOrder rotOrder;
			UT_Vector3D scale, trans;
			fluidRotMat.explode(rotOrder, fluidRot, scale, trans);
			fluidRot.radToDeg();
			fluidPos = volume->getVertex().getPt()->getPos();
		}


		float sizeX = curr3DSolver->fluidSize.x*0.5;
		float sizeY = curr3DSolver->fluidSize.y*0.5;
		float sizeZ = curr3DSolver->fluidSize.z*0.5;

		if(curr3DSolver->drawCube) {
			glPushMatrix();
			glTranslatef(fluidPos.x(),fluidPos.y(),fluidPos.z());
			glRotatef(fluidRot.z(),0,0,1);
			glRotatef(fluidRot.y(),0,1,0);
			glRotatef(fluidRot.x(),1,0,0);
			drawWireCube(sizeX,sizeY,sizeZ, ren);
			glPopMatrix();
		}

			if (fluid3DAh.getI()== 1) {

				curr3DSolver->drawFluid();


			}

			if (fluid3DSliceAh.getI()== 1) {

				curr3DSolver->drawFluidSlice();


			}

			ren.toggleLighting(1);

		}



}
Example #3
0
void GR_CudaHardware::renderWire(GU_Detail *gdp, RE_Render &ren, const GR_AttribOffset & /*ptinfo*/,
		    const GR_DisplayOption *dopt, float /*lod*/, const GU_PrimGroupClosure * /*hidden_geometry*/)
{

	GEO_AttributeHandle fluidAh= gdp->getDetailAttribute("cudaFluidPreview");
	fluidAh.setElement(gdp);

	if (fluidAh.getI()== 1) {

		GEO_AttributeHandle fluidIdAh= gdp->getDetailAttribute("solverId");
		fluidIdAh.setElement(gdp);

		VHFluidSolver* currSolver = VHFluidSolver::solverList[fluidIdAh.getI()];

		UT_Vector4 fluidPos(0,0,0);
		UT_Vector3D fluidRot(0,0,0);

		if(gdp->volumeCount() == 1) {
			GEO_Primitive* pprim = gdp->primitives().head();
			GU_PrimVolume* volume = (GU_PrimVolume *)pprim;
			UT_Matrix4 fluidRotMat;
			volume->getTransform4(fluidRotMat);

			UT_XformOrder rotOrder;
			UT_Vector3D scale, trans;
			fluidRotMat.explode(rotOrder, fluidRot, scale, trans);
			fluidRot.radToDeg();
			fluidPos = volume->getVertex().getPt()->getPos();
		}

		currSolver->drawFluid(fluidRot.x(), fluidRot.y(), fluidRot.z(),
										fluidPos.x(), fluidPos.y(), fluidPos.z());

	}

	GEO_AttributeHandle partsAh= gdp->getDetailAttribute("cudaParticlesPreview");
	partsAh.setElement(gdp);

	if (partsAh.getI()== 1) {

		GEO_AttributeHandle partsIdAh= gdp->getDetailAttribute("systemId");
		partsIdAh.setElement(gdp);

		ren.toggleLighting(0);

		VHParticlesSystem* currSystem = VHParticlesSystem::systemsList[partsIdAh.getI()];

		glClear(GL_COLOR_BUFFER_BIT);

		glEnable( GL_BLEND );
		glBlendFunc( GL_SRC_ALPHA, GL_ONE );

		currSystem->draw();

		glDisable( GL_BLEND );

		ren.toggleLighting(1);

	
	}

	GEO_AttributeHandle fluid3DAh= gdp->getDetailAttribute("cudaFluid3DPreview");
	fluid3DAh.setElement(gdp);

	GEO_AttributeHandle fluid3DSliceAh= gdp->getDetailAttribute("sliceDisplay");
	fluid3DSliceAh.setElement(gdp);

	if (fluid3DAh.getI() == 1 || fluid3DSliceAh.getI()== 1) {

		GEO_AttributeHandle fluidIdAh= gdp->getDetailAttribute("solverId");
		fluidIdAh.setElement(gdp);

		ren.toggleLighting(0);

		VHFluidSolver3D* curr3DSolver = VHFluidSolver3D::solverList[fluidIdAh.getI()];

		UT_Vector4 fluidPos(0,0,0);
		UT_Vector3D fluidRot(0,0,0);

		if(gdp->volumeCount() > 0) {
			GEO_Primitive* pprim = gdp->primitives().head();
			GU_PrimVolume* volume = (GU_PrimVolume *)pprim;
			UT_Matrix4 fluidRotMat;
			volume->getTransform4(fluidRotMat);

			UT_XformOrder rotOrder;
			UT_Vector3D scale, trans;
			fluidRotMat.explode(rotOrder, fluidRot, scale, trans);
			fluidRot.radToDeg();
			fluidPos = volume->getVertex().getPt()->getPos();
		}


		float sizeX = curr3DSolver->fluidSize.x*0.5;
		float sizeY = curr3DSolver->fluidSize.y*0.5;
		float sizeZ = curr3DSolver->fluidSize.z*0.5;

		if(curr3DSolver->drawCube) {
			glPushMatrix();
			glTranslatef(fluidPos.x(),fluidPos.y(),fluidPos.z());
			glRotatef(fluidRot.z(),0,0,1);
			glRotatef(fluidRot.y(),0,1,0);
			glRotatef(fluidRot.x(),1,0,0);
			drawWireCube(sizeX,sizeY,sizeZ, ren);
			glPopMatrix();
		}

			if (fluid3DAh.getI()== 1) {

				curr3DSolver->drawFluid(fluidRot.x(), fluidRot.y(), fluidRot.z(),
										fluidPos.x(), fluidPos.y(), fluidPos.z());

			}

			if (fluid3DSliceAh.getI()== 1) {

				curr3DSolver->drawFluidSlice(fluidRot.x(), fluidRot.y(), fluidRot.z(),
										fluidPos.x(), fluidPos.y(), fluidPos.z());

			}

			ren.toggleLighting(1);

		}




}
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();
}
Example #5
-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();
}