00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef MarchingCubes_INCLUDE_ONCE
00033 #define MarchingCubes_INCLUDE_ONCE
00034
00035 #include <vlVolume/link_config.hpp>
00036 #include <vlGraphics/Geometry.hpp>
00037
00038 namespace vl
00039 {
00040
00041
00042
00046 class VLVOLUME_EXPORT Volume: public Object
00047 {
00048 VL_INSTRUMENT_CLASS(vl::Volume, Object)
00049
00050
00053 struct Cube
00054 {
00055 Cube(): mMin(0), mMax(0) {}
00056 float mMin, mMax;
00057 bool includes(float v) const { return v >= mMin && v <= mMax; }
00058 };
00059 public:
00060 Volume();
00061
00067 void setup(float* data, bool use_directly, bool copy_data, const fvec3& bottom_left, const fvec3& top_right, const ivec3& slices);
00068
00069 void setup(const Volume&);
00070
00074 ref<Volume> downsample() const;
00075
00076 const float* values() const { return mValues; }
00077
00078 float* values() { return mValues; }
00079
00080 const float& value(int i) const { return mValues[i]; }
00081
00082 float& value(int i) { return mValues[i]; }
00083
00084 const float& value(int x, int y, int z) const { return mValues[x + mSlices.x()*y + mSlices.x()*mSlices.y()*z]; }
00085
00086 float& value(int x, int y, int z) { return mValues[x + mSlices.x()*y + mSlices.x()*mSlices.y()*z]; }
00087
00089 void normalHQ(fvec3& normal, const fvec3& v, float dx, float dy, float dz);
00090
00092 void normalLQ(fvec3& normal, const fvec3& v, float dx, float dy, float dz);
00093
00095 float sampleSmooth(float x, float y, float z) const;
00096
00098 float sampleNearest(float x, float y, float z) const;
00099
00100 fvec3 coordinate(int x, int y, int z) const { return mBottomLeft + fvec3(float(mCellSize.x()*x), float(mCellSize.y()*y), float(mCellSize.z()*z)); }
00101
00102 const fvec3& bottomLeft() const { return mBottomLeft; }
00103
00104 const fvec3& topRight() const { return mTopRight; }
00105
00106 const ivec3& slices() const { return mSlices; }
00107
00108 fvec3 size() const { return mSize; }
00109
00110 float computeMinimum() const;
00111
00112 float computeMaximum() const;
00113
00114 float computeAverage() const;
00115
00116 float minimum() const { return mMinimum; }
00117
00118 float maximum() const { return mMaximum; }
00119
00120 float average() const { return mAverage; }
00121
00122 const Volume::Cube& cube(int x, int y, int z) const
00123 {
00124 VL_CHECK(x<slices().x()-1)
00125 VL_CHECK(y<slices().y()-1)
00126 VL_CHECK(z<slices().z()-1)
00127 return mCubes[ x + y*(slices().x()-1) + z*(slices().x()-1)*(slices().y()-1) ];
00128 }
00129
00131 const fvec3& cellSize() const { return mCellSize; }
00132
00134 bool dataIsDirty() const { return mDataIsDirty; }
00135
00137 void setDataDirty() { mDataIsDirty = true; }
00138
00139 void setupInternalData();
00140
00141 protected:
00142 std::vector<float> mInternalValues;
00143 float* mValues;
00144 fvec3 mBottomLeft;
00145 fvec3 mTopRight;
00146 fvec3 mSize;
00147 ivec3 mSlices;
00148 fvec3 mCellSize;
00149 float mMinimum;
00150 float mMaximum;
00151 float mAverage;
00152 bool mDataIsDirty;
00153
00154 std::vector<Cube> mCubes;
00155 };
00156
00157
00158
00162 class VolumeInfo: public Object
00163 {
00164 VL_INSTRUMENT_CLASS(vl::VolumeInfo, Object)
00165
00166 public:
00167 VolumeInfo()
00168 {
00169 VL_DEBUG_SET_OBJECT_NAME()
00170 mThreshold = 0;
00171 mVolume = NULL;
00172 mVert0 = -1;
00173 mVertC = -1;
00174 }
00175
00176 VolumeInfo(Volume* vol, float threshold)
00177 {
00178 VL_DEBUG_SET_OBJECT_NAME()
00179 mThreshold = threshold;
00180 mVolume = vol;
00181 mVert0 = -1;
00182 mVertC = -1;
00183 }
00184
00185 VolumeInfo(Volume* vol, float threshold, const fvec4& color)
00186 {
00187 VL_DEBUG_SET_OBJECT_NAME()
00188 mColor = color;
00189 mThreshold = threshold;
00190 mVolume = vol;
00191 mVert0 = -1;
00192 mVertC = -1;
00193 }
00194
00195 void setColor(const fvec4& col) { mColor = col; }
00196 const fvec4& color() const { return mColor; }
00197
00198 void setThreshold(float t) { mThreshold = t; }
00199 float threshold() const { return mThreshold; }
00200
00201 void setVolume(Volume* vol) { mVolume = vol; }
00202 const Volume* volume() const { return mVolume.get(); }
00203 Volume* volume() { return mVolume.get(); }
00204
00205 void setVert0(int index) { mVert0 = index; }
00206 int vert0() const { return mVert0; }
00207
00208 void setVertC(int count) { mVertC = count; }
00209 int vertC() const { return mVertC; }
00210
00211 protected:
00212 fvec4 mColor;
00213 float mThreshold;
00214 ref<Volume> mVolume;
00215 int mVert0, mVertC;
00216 };
00217
00218
00219
00223 class VLVOLUME_EXPORT MarchingCubes
00224 {
00225 public:
00226 MarchingCubes();
00227
00228 void run(bool generate_colors);
00229
00230 void reset();
00231
00232 const Collection<VolumeInfo>* volumeInfo() const { return &mVolumeInfo; }
00233 Collection<VolumeInfo>* volumeInfo() { return &mVolumeInfo; }
00234
00235 void updateColor(const fvec3& color, int volume_index);
00236 void updateColor(const fvec4& color, int volume_index);
00237 void updateAlpha(float alpha, int volume_index);
00238
00240 void setHighQualityNormals(bool hq) { mHighQualityNormals = hq; }
00242 bool highQualityNormals() const { return mHighQualityNormals; }
00243
00244 public:
00245 ref<ArrayFloat3> mVertsArray;
00246 ref<ArrayFloat3> mNormsArray;
00247 ref<ArrayFloat4> mColorArray;
00248
00249
00250 #if defined(VL_OPENGL)
00251 ref<DrawElementsUInt> mDrawElements;
00252 #else
00253 ref<DrawElementsUShort> mDrawElements;
00254 #endif
00255
00256 protected:
00257 void computeEdges(Volume*, float threshold);
00258 void processCube(int x, int y, int z, Volume* vol, float threshold);
00259
00260 private:
00261 std::vector<fvec3> mVerts;
00262 std::vector<fvec3> mNorms;
00263 std::vector<fvec4> mColors;
00264
00265 #if defined(VL_OPENGL)
00266 typedef unsigned int IndexType;
00267 #else
00268 typedef unsigned short IndexType;
00269 #endif
00270 std::vector<IndexType> mIndices;
00271
00272 struct Edge
00273 {
00274 Edge(): mX(-1), mY(-1), mZ(-1) {}
00275 int mX, mY, mZ;
00276 };
00277 std::vector<Edge> mEdges;
00278 std::vector<usvec3> mCubes;
00279 Collection<VolumeInfo> mVolumeInfo;
00280 bool mHighQualityNormals;
00281
00282 protected:
00283 static const int mTriangleConnectionTable[256][16];
00284 static const int mCubeEdgeFlags[256];
00285 };
00286
00287 }
00288
00289 #endif