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 
}
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;
  }
}
Exemple #3
0
/*
 * 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();
}