Marching Cubes初探——Marching Cubes构建体素圆

Marching Cubes初探——Marching Cubes构建体素圆

标签(空格分隔): MarchingCubes OpenGL


Marching Cubes根据三维规则数据生成等值面,从而构成三维体数据。
我们的需求是自己生成三维球的点云数据,并通过Marching Cubes可视化体素球。


整个流程可分为三步:

  1. 点云数据向体数据转换
  2. 求六面体体素棱边与等值面的交点,构成等值面
  3. 等值面的三角形表示

笔记

Marching Cubes初探——Marching Cubes构建体素圆_第1张图片
Marching Cubes初探——Marching Cubes构建体素圆_第2张图片
Marching Cubes初探——Marching Cubes构建体素圆_第3张图片
Marching Cubes初探——Marching Cubes构建体素圆_第4张图片
Marching Cubes初探——Marching Cubes构建体素圆_第5张图片
Marching Cubes初探——Marching Cubes构建体素圆_第6张图片
Marching Cubes初探——Marching Cubes构建体素圆_第7张图片
Marching Cubes初探——Marching Cubes构建体素圆_第8张图片
Marching Cubes初探——Marching Cubes构建体素圆_第9张图片
Marching Cubes初探——Marching Cubes构建体素圆_第10张图片
Marching Cubes初探——Marching Cubes构建体素圆_第11张图片
Marching Cubes初探——Marching Cubes构建体素圆_第12张图片
image_1ctsqd5ae1j0h1hih157hokb10lk62.png-56.8kB


效果


代码

PointF.h
#pragma once
#include
#include
#include
#include

using namespace std;
#pragma  comment(lib, "glew32.lib")

class PointF{
private :
	float x, y, z;				//三维点坐标
	bool isInsideSphere;		//该点是否在球内的标记

public:
	PointF();
	~PointF();

	PointF(float x, float y, float z);
	float GetX();
	float GetY();
	float GetZ();
	bool GetIsInsideSphere();
	void SetIsInsideSphere(PointF cSphere, float R);

};

PointF.cpp

#include "PointF.h"

PointF::PointF() {
	x = 0.0f;
	y = 0.0f;
	z = 0.0f;
	isInsideSphere = false;
}

PointF::~PointF() {}

PointF::PointF(float x, float y, float z) {
	this->x = x;
	this->y = y;
	this->z = z;
}

float PointF::GetX() {
	return x;
}

float PointF::GetY() {
	return y;
}

float PointF::GetZ() {
	return z;
}

bool PointF::GetIsInsideSphere() {
	return isInsideSphere;
}

void PointF::SetIsInsideSphere(PointF cSphere, float R) {
	float xx = cSphere.GetX() - x;
	float yy = cSphere.GetY() - y;
	float zz = cSphere.GetZ() - z;

	float dis = xx * xx + yy * yy + zz * zz;
	float RR = R * R;
	if (RR > dis)
		isInsideSphere = true;
	else
		isInsideSphere = false;
}

VData.h

    #pragma once
    #include"PointF.h"
    
    class Voxel {
    private :
    	PointF iVertex[8];						//六面体体素的8个顶点
    	int iIndex;								//六面体根据顶点数据生成的EdgeTable和TriTable的下标
    	PointF iIntersectVertex[12];			//六面体12条棱边与等值面的交点
    
    public:
    	Voxel();
    	~Voxel();
    	void SetVertex(PointF p, int index);
    	PointF GetVertex(int index);
    	void CalculateiIndex();
    	void CalculateIntersectVertex();
    
    	void DrawWireCubes();
    	void DrawISOSurface();
    
    };

VData.cpp

#include "VData.h"
#include "PointF.h"

//点与边的关系
int vertexTable[12][15] = {
	{ 0,1 },
	{ 1,2 },
	{ 2,3 },
	{ 3,0 },
	{ 4,5 },
	{ 5,6 },
	{ 6,7 },
	{ 7,4 },
	{ 0,4 },
	{ 1,5 },
	{ 2,6 },
	{ 3,7 } };

//哪些边会与等值面相交
int edgeTable[256] = {
	0x0  , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
	0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
	0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
	0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
	0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
	0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
	0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
	0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
	0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
	0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
	0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
	0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
	0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
	0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
	0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
	0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
	0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
	0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
	0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
	0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
	0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
	0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
	0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
	0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
	0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
	0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
	0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
	0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
	0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
	0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
	0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
	0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 };

//等值面由哪些三角面片组成
int triTable[256][16] =
{ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
{ 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 },
{ 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 },
{ 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
{ 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 },
{ 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 },
{ 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 },
{ 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
{ 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 },
{ 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 },
{ 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
{ 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 },
{ 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 },
{ 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 },
{ 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 },
{ 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 },
{ 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 },
{ 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
{ 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 },
{ 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
{ 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 },
{ 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 },
{ 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 },
{ 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
{ 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 },
{ 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 },
{ 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
{ 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 },
{ 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 },
{ 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 },
{ 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
{ 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 },
{ 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 },
{ 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
{ 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 },
{ 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 },
{ 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 },
{ 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 },
{ 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 },
{ 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
{ 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 },
{ 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
{ 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 },
{ 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 },
{ 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 },
{ 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 },
{ 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 },
{ 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 },
{ 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 },
{ 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 },
{ 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 },
{ 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 },
{ 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 },
{ 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 },
{ 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 },
{ 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 },
{ 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 },
{ 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 },
{ 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 },
{ 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 },
{ 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 },
{ 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 },
{ 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 },
{ 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 },
{ 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 },
{ 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 },
{ 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 },
{ 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 },
{ 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 },
{ 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 },
{ 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 },
{ 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 },
{ 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 },
{ 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 },
{ 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 },
{ 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 },
{ 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 },
{ 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 },
{ 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 },
{ 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 },
{ 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 },
{ 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 },
{ 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 },
{ 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 },
{ 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 },
{ 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 },
{ 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 },
{ 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 },
{ 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 },
{ 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 },
{ 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 },
{ 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 },
{ 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 },
{ 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 },
{ 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 },
{ 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 },
{ 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 },
{ 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 },
{ 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 },
{ 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 },
{ 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 },
{ 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 },
{ 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 },
{ 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 },
{ 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 },
{ 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 },
{ 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 },
{ 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 },
{ 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } };

//////////////////////////////////////////
Voxel::Voxel() {
	for (int i = 0; i < 8; i++) {
		iVertex[i] = PointF(0.0f, 0.0f, 0.0f);
	}
	iIndex = 0;
	for (int i = 0; i < 12; i++) {
		iIntersectVertex[i] = PointF(0.0f, 0.0f, 0.0f);
	}
}

Voxel::~Voxel() {
	
}


void Voxel::SetVertex(PointF p, int index) {
	iVertex[index] = p;
}

PointF Voxel::GetVertex(int index) {
	return iVertex[index];
}

void Voxel::CalculateiIndex() {
	iIndex = 0;
	int mul = 1;
	for (int i = 0; i < 8; i++) {
		if (iVertex[i].GetIsInsideSphere())
			iIndex |= mul;
		mul *= 2;
	}
}

void Voxel::CalculateIntersectVertex() {
	
	//与等值面相交的边Index存到edgeIndex中
	int edgeResult = edgeTable[iIndex];
	vectoredgeIndex = vector();
	int mul = 1;
	for (int i = 0; i < 12; i++) {
		int temp = edgeResult & mul;
		if (temp == mul)
			edgeIndex.push_back(i);
		mul *= 2;
	}

	for (int i = 0; i < edgeIndex.size(); i++) {
		int edge_value = edgeIndex[i];
		int point_1 = vertexTable[edge_value][0];
		int point_2 = vertexTable[edge_value][16];

		//为了简化步骤,将求交点化简为求中点
		float xx = (iVertex[point_1].GetX() + iVertex[point_2].GetX()) / 2.0f;
		float yy = (iVertex[point_1].GetY() + iVertex[point_2].GetY()) / 2.0f;
		float zz = (iVertex[point_1].GetZ() + iVertex[point_2].GetZ()) / 2.0f;
		PointF intersection_point = PointF(xx, yy, zz);

		iIntersectVertex[edge_value] = intersection_point;
	}
}

void Voxel::DrawWireCubes() {
	glColor4f(0.3984375f, 0.80078125f, 0.6640625f, 0.1f);
	glBegin(GL_LINE_LOOP);
	glVertex3f(iVertex[0].GetX(), iVertex[0].GetY(), iVertex[0].GetZ());
	glVertex3f(iVertex[1].GetX(), iVertex[1].GetY(), iVertex[1].GetZ());
	glVertex3f(iVertex[2].GetX(), iVertex[2].GetY(), iVertex[2].GetZ());
	glVertex3f(iVertex[3].GetX(), iVertex[3].GetY(), iVertex[3].GetZ());
	glEnd();
	glBegin(GL_LINE_LOOP);
	glVertex3f(iVertex[4].GetX(), iVertex[4].GetY(), iVertex[4].GetZ());
	glVertex3f(iVertex[5].GetX(), iVertex[5].GetY(), iVertex[5].GetZ());
	glVertex3f(iVertex[6].GetX(), iVertex[6].GetY(), iVertex[6].GetZ());
	glVertex3f(iVertex[7].GetX(), iVertex[7].GetY(), iVertex[7].GetZ());
	glEnd();
	glBegin(GL_LINE_LOOP);
	glVertex3f(iVertex[7].GetX(), iVertex[7].GetY(), iVertex[7].GetZ());
	glVertex3f(iVertex[6].GetX(), iVertex[6].GetY(), iVertex[6].GetZ());
	glVertex3f(iVertex[2].GetX(), iVertex[2].GetY(), iVertex[2].GetZ());
	glVertex3f(iVertex[3].GetX(), iVertex[3].GetY(), iVertex[3].GetZ());
	glEnd();
	glBegin(GL_LINE_LOOP);
	glVertex3f(iVertex[4].GetX(), iVertex[4].GetY(), iVertex[4].GetZ());
	glVertex3f(iVertex[5].GetX(), iVertex[5].GetY(), iVertex[5].GetZ());
	glVertex3f(iVertex[1].GetX(), iVertex[1].GetY(), iVertex[1].GetZ());
	glVertex3f(iVertex[0].GetX(), iVertex[0].GetY(), iVertex[0].GetZ());
	glEnd();
	glBegin(GL_LINE_LOOP);
	glVertex3f(iVertex[4].GetX(), iVertex[4].GetY(), iVertex[4].GetZ());
	glVertex3f(iVertex[7].GetX(), iVertex[7].GetY(), iVertex[7].GetZ());
	glVertex3f(iVertex[3].GetX(), iVertex[3].GetY(), iVertex[3].GetZ());
	glVertex3f(iVertex[0].GetX(), iVertex[0].GetY(), iVertex[0].GetZ());
	glEnd();
	glBegin(GL_LINE_LOOP);
	glVertex3f(iVertex[5].GetX(), iVertex[5].GetY(), iVertex[5].GetZ());
	glVertex3f(iVertex[6].GetX(), iVertex[6].GetY(), iVertex[6].GetZ());
	glVertex3f(iVertex[2].GetX(), iVertex[2].GetY(), iVertex[2].GetZ());
	glVertex3f(iVertex[1].GetX(), iVertex[1].GetY(), iVertex[1].GetZ());
	glEnd();
}

void Voxel::DrawISOSurface() {
	int* surface = triTable[iIndex];
	for (int i = 0; i < 16; i += 3) {
		if (surface[i] == -1)
			break;
		PointF p1 = iIntersectVertex[surface[i]];
		PointF p2 = iIntersectVertex[surface[i + 1]];
		PointF p3 = iIntersectVertex[surface[i + 2]];

		glColor4f(0.9296875f, 0.79296875f, 0.67578125f, 1.0f);
		
		glBegin(GL_LINE_LOOP);	//GL_TRIANGLES
		glVertex3f(p1.GetX(), p1.GetY(), p1.GetZ());
		glVertex3f(p2.GetX(), p2.GetY(), p2.GetZ());
		glVertex3f(p3.GetX(), p3.GetY(), p3.GetZ());
		glEnd();
	}
}

Main.cpp

#include"PointF.h"
#include "VData.h"

#pragma  comment(lib, "glew32.lib")

float SPACE_SIZE = 512.0f;						//三维空间大小为512 * 512 * 512		为了划分均匀,取空间大小为2的N次幂
PointF cSphere =  PointF(0.0f, 0.0f, 0.0f);		//球心坐标在原点处
float cSphereR = 200.0f;						//球的半径为200
int cResolution = 2;							//划分三维空间的“分辨率”,为了划分均匀,取“分辨率”为2的N次幂
vectorpointCloud;
vectorvoxelData;
float xrot = 0.0f;
float yrot = 0.0f;
float zrot = 0.0f;
bool wirecubes = true;


void InitializeGlutCallbacks();			//OpenGL中回调函数
void RenderSceneCB();					//渲染主体
void myReshape(GLsizei w, GLsizei h);
void myKeyboard(unsigned char key, int x, int y);

void CalculatePointFCloud(vector& pointCloud);			//根据空间、球、分辨率等信息,得到点云数据
vector ConvertToVoxelData(vector pointCloud);	//Marching Cubes 步骤一:转化为体元数据
void CalculateIntersectPoint(vector& voxelData);			//Marching Cubes 步骤二:求与等值面相交的边上的交点

/**********************/
/*      程序入口      */
/**********************/
int main(int argc, char* argv[]) {

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowSize(1200, 768);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("Marching Cubes Simulate Sphere");

	GLenum res = glewInit();
	if (res != GLEW_OK) {
		fprintf(stderr, "Error:'%s'\n", glewGetErrorString(res));
		return 1;
	}
	
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	//设定窗口大小变化的回调函数
	glutReshapeFunc(myReshape);

	//键盘控制Resolution
	glutKeyboardFunc(myKeyboard);

	pointCloud = vector();
	//得到点云数据
	CalculatePointFCloud(pointCloud);
	//Marching Cubes 步骤一:转化为体元数据
	voxelData = ConvertToVoxelData(pointCloud);
	//Marching Cubes 步骤二:求与等值面相交的边上的交点
	CalculateIntersectPoint(voxelData);
	//Marching Cubes 步骤三:绘制构成等值面的三角形集合
	InitializeGlutCallbacks();

	glutMainLoop();

	return 0;
}

/**********************/
/* OpenGL中回调函数   */
/* @para    null      */
/* @result  null      */
/**********************/
void InitializeGlutCallbacks() {
	glutDisplayFunc(RenderSceneCB);
	glutIdleFunc(RenderSceneCB);
}

void myReshape(GLsizei w, GLsizei h)
{
	//设定视区
	glViewport(0, 0, w, h);

	//设定透视方式
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0, 1.0*(GLfloat)w / (GLfloat)h, 0.1, 10000.0);
}

/**********************/
/* 渲染主体           */
/* @para    voxelData      */
/* @result  null      */
/**********************/
void RenderSceneCB() {
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	
	glTranslatef(0.0, 0.0f, -1000.0f);
	glRotatef(xrot, 1, 0, 0);
	glRotatef(yrot, 0, 1, 0);
	glRotatef(zrot, 0, 0, 1);

	for (int i = 0; i < voxelData.size(); i++) {
		if(wirecubes)
			voxelData[i].DrawWireCubes();
		voxelData[i].DrawISOSurface();
	}
	xrot += 0.05f;
	yrot += 0.05f;
	zrot += 0.05f;
	
	//glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
	//glutSolidTeapot(1.0);

	//交换缓冲区
	glutSwapBuffers();
}

void myKeyboard(unsigned char key, int x, int y) {
	switch (key)
	{
	case 49:	//1
		cResolution *= 2;
		break;
	case 50:	//2c
		cResolution /= 2;
		if (cResolution <= 2)
			cResolution = 2;
		break;
	case 48:
		wirecubes = !wirecubes;
		break;
	default:
		
		break;
	}
	//得到点云数据
	CalculatePointFCloud(pointCloud);
	//Marching Cubes 步骤一:转化为体元数据
	voxelData = ConvertToVoxelData(pointCloud);
	//Marching Cubes 步骤二:求与等值面相交的边上的交点
	CalculateIntersectPoint(voxelData);
	glutSwapBuffers();
}

/*************************/
/* 计算点数据            */
/* @para    pointCloud   */
/* @result  null         */
/*************************/
void CalculatePointFCloud(vector& pointCloud) {
	if (pointCloud.size() != 0)
		pointCloud.clear();

	float spaceBegin = -SPACE_SIZE / 2.0f;
	float step = SPACE_SIZE / cResolution;
	float x, y, z;
	for (int zz = 0; zz <= cResolution; zz++) {
		for (int yy = 0; yy <= cResolution; yy++) {
			for (int xx = 0; xx <= cResolution; xx++) {
				x = spaceBegin + xx * step;
				y = spaceBegin + yy * step;
				z = spaceBegin + zz * step;
				
				PointF tempPoint = PointF(x, y, z);
				tempPoint.SetIsInsideSphere(cSphere, cSphereR);
				pointCloud.push_back(tempPoint);
			}
		}
	}
}

/*************************************************/
/* Marching Cubes 步骤一:点数据向体数据转换     */
/* @para    pointCloud                           */
/* @result  voxelData                            */
/*************************************************/
vector ConvertToVoxelData(vector pointCloud) {
	vector voxelData = vector();
	int voxelIndex;
	int layer, row, colum;			//层、行、列
	int R = cResolution;
	int RR = cResolution * cResolution;
	int RRR = RR * cResolution;
	int v3 = 0;
	int v0, v1, v2, v4, v5, v6, v7;
	for (int i = 0; i < RRR; i++) {
		voxelIndex = i;
		//层数
		layer = voxelIndex / (cResolution * cResolution);
		voxelIndex = voxelIndex % RR;
		//行数
		row = voxelIndex / R;
		//列数
		colum = voxelIndex % R;

		//V3
		v3 = layer * (R + 1) * (R + 1) + row * (R + 1) + colum;

		Voxel tempVoxel = Voxel();

		v0 = v3 + R + 1;
		v1 = v0 + 1;
		v2 = v3 + 1;
		v7 = v3 + (R + 1) * (R + 1);
		v6 = v7 + 1;
		v4 = v7 + (R + 1);
		v5 = v4 + 1;

		tempVoxel.SetVertex(pointCloud[v0], 0);
		tempVoxel.SetVertex(pointCloud[v1], 1);
		tempVoxel.SetVertex(pointCloud[v2], 2);
		tempVoxel.SetVertex(pointCloud[v3], 3);
		tempVoxel.SetVertex(pointCloud[v4], 4);
		tempVoxel.SetVertex(pointCloud[v5], 5);
		tempVoxel.SetVertex(pointCloud[v6], 6);
		tempVoxel.SetVertex(pointCloud[v7], 7);

		tempVoxel.CalculateiIndex();
		voxelData.push_back(tempVoxel);
	}
	return voxelData;
}

/******************************************************/
/* Marching Cubes 步骤二:求与等值面相交的边上的交点  */
/* @para    voxelData                                 */
/* @result  null                                      */
/******************************************************/
void CalculateIntersectPoint(vector& voxelData) {
	if (voxelData.size() == 0)
		return;

	for (int i = 0; i < voxelData.size(); i++) {
		voxelData[i].CalculateIntersectVertex();
	}
}

你可能感兴趣的:(OPENGL,数据可视化)