コード例 #1
0
void
DrawMolItem::draw_volume_isosurface_lines (const VolumetricData * v,
    float isovalue, int stepsize, int thickness)
{
  int i, usecolor;
  IsoSurface *s = new IsoSurface;
  s->clear ();
  s->compute (v, isovalue, stepsize);

  if (s->numtriangles > 0)
  {
    append (DMATERIALOFF); // enable lighting and shading
    cmdLineType.putdata (SOLIDLINE, cmdList);
    cmdLineWidth.putdata (thickness, cmdList);

    usecolor = draw_volume_get_colorid ();
    cmdColorIndex.putdata (usecolor, cmdList);

    // draw triangles
    for (i = 0; i < s->numtriangles; i++)
    {
      float *addr;
      addr = &(s->v[i * 9]);
      cmdLine.putdata (&addr[0], &addr[3], cmdList);
      cmdLine.putdata (&addr[3], &addr[6], cmdList);
      cmdLine.putdata (&addr[6], &addr[0], cmdList);
    }
  }

  delete s; // we don't need this stuff after this point 
}
コード例 #2
0
void
DrawMolItem::draw_volume_isosurface_trimesh (const VolumetricData * v,
    float isovalue, int stepsize)
{
  int i, usecolor;
  IsoSurface s;
  s.clear (); // initialize isosurface data
  s.compute (v, isovalue, stepsize); // compute the isosurface
  s.vertexfusion (v, 36, 36); // identify and eliminate duplicated vertices
  s.normalize (); // normalize interpolated gradient/surface normals

  if (s.numtriangles > 0)
  {
    append (DMATERIALON); // enable lighting and shading
    usecolor = draw_volume_get_colorid ();
    cmdColorIndex.putdata (usecolor, cmdList);

    // draw surface with per-vertex normals using a vertex array
    float *c = new float[s.numtriangles * 9];
    const float *fp = scene->color_value (usecolor);
    for (i = 0; i < s.numtriangles; i++)
    {
      int ind = i * 9;

      c[ind] = fp[0]; // Red
      c[ind + 1] = fp[1]; // Green
      c[ind + 2] = fp[2]; // Blue

      ind += 3;
      c[ind] = fp[0]; // Red
      c[ind + 1] = fp[1]; // Green
      c[ind + 2] = fp[2]; // Blue

      ind += 3;
      c[ind] = fp[0]; // Red
      c[ind + 1] = fp[1]; // Green
      c[ind + 2] = fp[2]; // Blue
    }

    // Create a triangle mesh
    // XXX don't try to stripify it since this triggers a crash in ACTC for
    //     unknown reasons
    cmdTriMesh.putdata (&s.v[0], &s.n[0], c, s.v.num () / 3, &s.f[0],
        s.numtriangles, 0, cmdList, &cmdTriMesh);

    delete[] c;
  }
}
コード例 #3
0
void DefaultState::Load(void) 
{ 	
	// < Add a light to our sample scene.
	m_pLight = Leadwerks::DirectionalLight::Create();
	m_pLight->SetRotation(35.0f, -35.0f, 0.0f);

	// < Create a base for the sample scene.
	m_pGround = Leadwerks::Model::Box(10.0f, 0.5f, 10.0f);	
	m_pGround->Move(0.0f, 0.0f, 4.0f);

	// < Create the world for our components and a sample camera to move
	// * about our scene.
	m_pWorld = new Components::World();
	m_cameraDynamic = Entities::CameraDynamic::Create(m_pWorld, m_pCameraHndl, "./Scripts/Camera.lua");    
	
	m_pCameraHndl->getInst()->SetDrawMode(DRAW_WIREFRAME);
    
	// < Set the input manager to reset the mouse-position to the center of the
	// * screen every frame.
	m_pInputMgr->ToggleMouseCenter();
	
	// < Initialize our isosurface and the voxel buffer we will be using.
	m_pIsosurface = new IsoSurface<float>();
	m_pBuffer = new VoxelBuffer<float>(NUM_VOXELS, NUM_VOXELS, NUM_VOXELS);

	ModelerInput<float> input;
	Modeler<float> modeler;
	modeler.Assign(*m_pBuffer);

	// < Here, lets use the modeler to feed out voxel data into our isosurface.
	for (unsigned z = 0; z <= 8; z += 1)
		for (unsigned y = 0; y <= 8; y += 1)
			for (unsigned x = 0; x <= 8; x += 1) {
				input.pt[0] = x; input.pt[1] = y; input.pt[2] = z;
				
				// < Formula for a circle.
				if ( (sqrt((x - 4) * (x - 4) + (y - 4) * (y - 4) + (z - 4) * (z - 4)) < 4) )
					input.val = -1.0f;
				else
					input.val = 1.0f;

				modeler.AddInput(input);
			} // end for
	
	modeler.Execute();

	// < Generate our isosurface.
	m_pModel = Leadwerks::Model::Create();	
	m_pModel->Move(-4.0f, 0.0f, 0.0f);
	unsigned nTriangles = m_pIsosurface->GenerateSurface(*m_pModel,
		*m_pBuffer,
		0.0,
		CELLS_PER_ISOSURFACE,
		CELLS_PER_ISOSURFACE,
		CELLS_PER_ISOSURFACE,
		VOXEL_SIZE,
		VOXEL_SIZE,
		VOXEL_SIZE);

}
コード例 #4
0
int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
{
	if(! isSimworldOk() ) return 1;
	
	// already inited?
	if(mpLbm) return 0;
	
	mpGlob = glob;
	if(!getVisible()) {
		mpAttrs->setAllUsed();
		return 0;
	}


	mGeoInitId = mpAttrs->readInt("geoinitid", mGeoInitId,"LbmSolverInterface", "mGeoInitId", false);
	//mDimension, mSolverType are deprecated
	string mSolverType(""); 
	mSolverType = mpAttrs->readString("solver", mSolverType, "SimulationObject","mSolverType", false ); 

	mpLbm = createSolver(); 
  /* check lbm pointer */
	if(mpLbm == NULL) {
		errFatal("SimulationObject::initializeLbmSimulation","Unable to init LBM solver! ", SIMWORLD_INITERROR);
		return 2;
	}
	debMsgStd("SimulationObject::initialized",DM_MSG,"IdStr:"<<mpLbm->getIdString() <<" LBM solver! ", 2);

	mpParts = new ParticleTracer();

	// for non-param simulations
	mpLbm->setParametrizer( mpParam );
	mpParam->setAttrList( getAttributeList() );
	// not needed.. done in solver_init: mpParam->setSize ... in solver_interface
	mpParam->parseAttrList();

	mpLbm->setAttrList( getAttributeList() );
	mpLbm->setSwsAttrList( getSwsAttributeList() );
	mpLbm->parseAttrList();
	mpParts->parseAttrList( getAttributeList() );

	if(! isSimworldOk() ) return 3;
	mpParts->setName( getName() + "_part" );
	mpParts->initialize( glob );
	if(! isSimworldOk() ) return 4;
	
	// init material settings
	string matMc("default");
	matMc = mpAttrs->readString("material_surf", matMc, "SimulationObject","matMc", false );
	mShowSurface   = mpAttrs->readInt("showsurface", mShowSurface, "SimulationObject","mShowSurface", false ); 
	mShowParticles = mpAttrs->readInt("showparticles", mShowParticles, "SimulationObject","mShowParticles", false ); 

	checkBoundingBox( mGeoStart, mGeoEnd, "SimulationObject::initializeSimulation" );
	mpLbm->setLbmInitId( mGeoInitId );
	mpLbm->setGeoStart( mGeoStart );
	mpLbm->setGeoEnd( mGeoEnd );
	mpLbm->setRenderGlobals( mpGlob );
	mpLbm->setName( getName() + "_lbm" );
	mpLbm->setParticleTracer( mpParts );
	if(mpElbeemSettings) {
		// set further settings from API struct init
		if(mpElbeemSettings->outputPath) this->mOutFilename = string(mpElbeemSettings->outputPath);
		mpLbm->initDomainTrafo( mpElbeemSettings->surfaceTrafo );
		mpLbm->setSmoothing(1.0 * mpElbeemSettings->surfaceSmoothing, 1.0 * mpElbeemSettings->surfaceSmoothing);
		mpLbm->setIsoSubdivs(mpElbeemSettings->surfaceSubdivs);
		mpLbm->setSizeX(mpElbeemSettings->resolutionxyz);
		mpLbm->setSizeY(mpElbeemSettings->resolutionxyz);
		mpLbm->setSizeZ(mpElbeemSettings->resolutionxyz);
		mpLbm->setPreviewSize(mpElbeemSettings->previewresxyz);
		mpLbm->setRefinementDesired(mpElbeemSettings->maxRefine);
		mpLbm->setGenerateParticles(mpElbeemSettings->generateParticles);
		// set initial particles
		mpParts->setNumInitialParticles(mpElbeemSettings->numTracerParticles);
		
		// surface generation flag
		mpLbm->setSurfGenSettings(mpElbeemSettings->mFsSurfGenSetting);

		string dinitType = string("no");
		if     (mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_PARTSLIP) dinitType = string("part"); 
		else if(mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_FREESLIP) dinitType = string("free"); 
		else /*if(mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_NOSLIP)*/ dinitType = string("no"); 
		mpLbm->setDomainBound(dinitType);
		mpLbm->setDomainPartSlip(mpElbeemSettings->domainobsPartslip);
		mpLbm->setDumpVelocities(mpElbeemSettings->generateVertexVectors);
		mpLbm->setFarFieldSize(mpElbeemSettings->farFieldSize);
		debMsgStd("SimulationObject::initialize",DM_MSG,"Added domain bound: "<<dinitType<<" ps="<<mpElbeemSettings->domainobsPartslip<<" vv"<<mpElbeemSettings->generateVertexVectors<<","<<mpLbm->getDumpVelocities(), 9 );

		debMsgStd("SimulationObject::initialize",DM_MSG,"Set ElbeemSettings values "<<mpLbm->getGenerateParticles(),10);
	}

	if(! mpLbm->initializeSolverMemory()   )         { errMsg("SimulationObject::initialize","initializeSolverMemory failed"); mPanic=true; return 10; }
	if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverMemory status"); mPanic=true; return 11; } 
	if(! mpLbm->initializeSolverGrids()    )         { errMsg("SimulationObject::initialize","initializeSolverGrids  failed"); mPanic=true; return 12; }
	if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverGrids  status"); mPanic=true; return 13; } 
	if(! mpLbm->initializeSolverPostinit() )         { errMsg("SimulationObject::initialize","initializeSolverPostin failed"); mPanic=true; return 14; }
	if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverPostin status"); mPanic=true; return 15; } 

	// print cell type stats
	bool printStats = true;
	if(glob_mpnum>0) printStats=false; // skip in this case
	if(printStats) {
		const int jmax = sizeof(CellFlagType)*8;
		int totalCells = 0;
		int flagCount[jmax];
		for(int j=0; j<jmax ; j++) flagCount[j] = 0;
		int diffInits = 0;
		LbmSolverInterface::CellIdentifier cid = mpLbm->getFirstCell();
		for(; mpLbm->noEndCell( cid );
					mpLbm->advanceCell( cid ) ) {
			int flag = mpLbm->getCellFlag(cid,0);
			int flag2 = mpLbm->getCellFlag(cid,1);
			if(flag != flag2) {
				diffInits++;
			}
			for(int j=0; j<jmax ; j++) {
				if( flag&(1<<j) ) flagCount[j]++;
			}
			totalCells++;
		}
		mpLbm->deleteCellIterator( &cid );

		char charNl = '\n';
		debugOutNnl("SimulationObject::initializeLbmSimulation celltype stats: " <<charNl, 5);
		debugOutNnl("no. of cells = "<<totalCells<<", "<<charNl ,5);
		for(int j=0; j<jmax ; j++) {
			std::ostringstream out;
			if(flagCount[j]>0) {
				out<<"\t" << flagCount[j] <<" x "<< convertCellFlagType2String( (CellFlagType)(1<<j) ) <<", " << charNl;
				debugOutNnl(out.str(), 5);
			}
		}
		// compute dist. of empty/bnd - fluid - if
		// cfEmpty   = (1<<0), cfBnd  = (1<< 2), cfFluid   = (1<<10), cfInter   = (1<<11),
		if(1){
			std::ostringstream out;
			out.precision(2); out.width(4);
			int totNum = flagCount[1]+flagCount[2]+flagCount[7]+flagCount[8];
			double ebFrac = (double)(flagCount[1]+flagCount[2]) / totNum;
			double flFrac = (double)(flagCount[7]) / totNum;
			double ifFrac = (double)(flagCount[8]) / totNum;
			//???
			out<<"\tFractions: [empty/bnd - fluid - interface - ext. if]  =  [" << ebFrac<<" - " << flFrac<<" - " << ifFrac<<"] "<< charNl;

			if(diffInits > 0) {
				debMsgStd("SimulationObject::initializeLbmSimulation",DM_MSG,"celltype Warning: Diffinits="<<diffInits<<"!" , 5);
			}
			debugOutNnl(out.str(), 5);
		}
	} // cellstats

	// might be modified by mpLbm
	//mpParts->setStart( mGeoStart );?  mpParts->setEnd( mGeoEnd );?
	mpParts->setStart( mpLbm->getGeoStart() );
	mpParts->setEnd(   mpLbm->getGeoEnd()   );
	mpParts->setCastShadows( false );
	mpParts->setReceiveShadows( false );
	mpParts->searchMaterial( glob->getMaterials() );

	// this has to be inited here - before, the values might be unknown
	IsoSurface *surf = mpLbm->getSurfaceGeoObj();
	if(surf) {
		surf->setName( "final" ); // final surface mesh 
		// warning - this might cause overwriting effects for multiple sims and geom dump...
		surf->setCastShadows( true );
		surf->setReceiveShadows( false );
		surf->searchMaterial( glob->getMaterials() );
		if(mShowSurface) mObjects.push_back( surf );
	}
	
#ifdef ELBEEM_PLUGIN
	mShowParticles=1; // for e.g. dumping
#endif // ELBEEM_PLUGIN
	if((mpLbm->getGenerateParticles()>0.0)||(mpParts->getNumInitialParticles()>0)) {
		mShowParticles=1;
		mpParts->setDumpParts(true);
	}
		//debMsgStd("SimulationObject::init",DM_NOTIFY,"Using envvar ELBEEM_DUMPPARTICLE to set mShowParticles, DEBUG!",1);
	//}  // DEBUG ENABLE!!!!!!!!!!
	if(mShowParticles) {
		mObjects.push_back(mpParts);
	}

	// add objects to display for debugging (e.g. levelset particles)
	vector<ntlGeometryObject *> debugObjs = mpLbm->getDebugObjects();
	for(size_t i=0;i<debugObjs.size(); i++) {
		debugObjs[i]->setCastShadows( false );
		debugObjs[i]->setReceiveShadows( false );
		debugObjs[i]->searchMaterial( glob->getMaterials() );
		mObjects.push_back( debugObjs[i] );
		debMsgStd("SimulationObject::init",DM_NOTIFY,"Added debug obj "<<debugObjs[i]->getName(), 10 );
	}
	return 0;
}
コード例 #5
0
ファイル: marchcubes.cpp プロジェクト: bssrdf/melt
/*
 * March through the grid, creating the tesselation of an isosurface.
 * The somewhat convoluted logic is necessary to prevent any single cube
 * edge from being examined more than once. This allows for a compact
 * mesh representation, with each vertex stored only once and each face
 * stored simply as three integer indices into the vertex array.
 */
void MarchCube::march (IsoSurface& surface)
{
	surface.clear();
	ImpSurface* function = surface.getFunction();

	/*
	 *
	 */
	initVertices(0, vtxGrid[0], function);
	initVertices(1, vtxGrid[1], function);
	setCubeFlags();

	 
	/*
	 * Fill in the back of the grid first (where "forward" is the +z 
	 * direction. This is done by checking the left- and bottom-edges 
	 * of each square at the very back of the grid, then all the edges 
	 * along the top of the back, then all those along the right.
	 */
	for (int i = 0; i < resx; ++i)
	{
		for (int j = 0; j < resy; ++j)
		{
			if (edgeFlags[i][j] & LEFTBACK)
				edgeGrid[0][i][j][0] = 
				  surface.addVertex(vtxGrid[0][i][j].findSurface(
				                        vtxGrid[0][i][j + 1], threshold));
			if (edgeFlags[i][j] & BOTBACK)
				edgeGrid[0][i][j][2] =
				  surface.addVertex(vtxGrid[0][i][j].findSurface(
				                        vtxGrid[0][i + 1][j], threshold));

		}
		if (edgeFlags[i][resy - 1] & TOPBACK)
			edgeGrid[0][i][resy][2] =
				  surface.addVertex(vtxGrid[0][i][resy].findSurface(
				                        vtxGrid[0][i + 1][resy], threshold));
	}

	for (int i = 0; i < resy; ++i)
	{
		if (edgeFlags[resx - 1][i] & RIGHTBACK)
			edgeGrid[0][resx][i][0] =
				  surface.addVertex(vtxGrid[0][resx][i].findSurface(
				                        vtxGrid[0][resx][i + 1], threshold));
	}

	/*
	 * Step forward (in the +z direction) through the grid. We first
	 * consider the bottom-left, front-left, and bottom-front edges from
	 * each cube. The top edges from the top row of cubes are then
	 * examined, followed by those on the right edge of the grid.
	 */

	for (int layer = 1; layer <= resz; ++layer)
	{
//		cerr << "filling in layer " << layer << endl;
		if (layer > 1)
		{
			initVertices(layer, vtxGrid[1], function);
			setCubeFlags();
		}

		for (int i = 0; i < resx; ++i)
		{
			for (int j = 0; j < resy; ++j)
			{
				if (edgeFlags[i][j] & BOTLEFT)
					edgeGrid[0][i][j][1] = 
					    surface.addVertex(vtxGrid[0][i][j].findSurface(
							                       vtxGrid[1][i][j], 
												   threshold));
				if (edgeFlags[i][j] & LEFTFRONT)
					edgeGrid[1][i][j][0] = 
					    surface.addVertex(vtxGrid[1][i][j].findSurface(
							                       vtxGrid[1][i][j + 1], 
												   threshold));
				if (edgeFlags[i][j] & BOTFRONT)
					edgeGrid[1][i][j][2] = 
					    surface.addVertex(vtxGrid[1][i][j].findSurface(
							                       vtxGrid[1][i + 1][j], 
												   threshold));

			}
			if (edgeFlags[i][resy - 1] & TOPLEFT)
				edgeGrid[0][i][resy][1] = 
				    surface.addVertex(vtxGrid[0][i][resy].findSurface(
						                       vtxGrid[1][i][resy], 
											   threshold));
			if (edgeFlags[i][resy - 1] & TOPFRONT)
				edgeGrid[1][i][resy][2] = 
				    surface.addVertex(vtxGrid[1][i][resy].findSurface(
						                       vtxGrid[1][i + 1][resy], 
											   threshold));
		}

		for (int i = 0; i < resy; ++i)
		{
			if (edgeFlags[resx - 1][i] & RIGHTFRONT)
				edgeGrid[1][resx][i][0] = 
				    surface.addVertex(vtxGrid[1][resx][i].findSurface(
						                       vtxGrid[1][resx][i + 1], 
											   threshold));
			if (edgeFlags[resx - 1][i] & BOTRIGHT)
				edgeGrid[0][resx][i][1] = 
				    surface.addVertex(vtxGrid[0][resx][i].findSurface(
						                       vtxGrid[1][resx][i], 
											   threshold));
		}
		if (edgeFlags[resx - 1][resy - 1] & TOPRIGHT)
			edgeGrid[0][resx][resy][1] =
			    surface.addVertex(vtxGrid[0][resx][resy].findSurface(
					                       vtxGrid[1][resx][resy], 
										   threshold));

		/*
		 * Now that we've found all the vertices on the edges of the cubes
		 * in the layer, extract the set of triangles defined.
		 */
		int* indices;
		int e0, e1, e2;
		int v0, v1, v2;
		static int badV = 0;
		for (int i = 0; i < resx; ++i)
		{
			for (int j = 0; j < resy; ++j)
			{
				indices = triTable[vtxFlags[i][j]];
				while(*indices != -1)
				{
					e0 = *indices++;
					e1 = *indices++;
					e2 = *indices++;
					v0 = getVertex(i, j, e0);
					v1 = getVertex(i, j, e1);
					v2 = getVertex(i, j, e2);
					surface.addFace(v0, v1, v2);
				}
			}
		}

		/*
		 * Move the vertex/edge-index grids one step forward
		 */
		CubeVtx** vTemp = vtxGrid[0];
		vtxGrid[0] = vtxGrid[1];
		vtxGrid[1] = vTemp;

		int*** eTemp = edgeGrid[0];
		edgeGrid[0] = edgeGrid[1];
		edgeGrid[1] = eTemp;
	}
	surface.calcVNorms();
}