Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
MarchingCubes.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef MarchingCubes_INCLUDE_ONCE
33 #define MarchingCubes_INCLUDE_ONCE
34 
35 #include <vlVolume/link_config.hpp>
36 #include <vlGraphics/Geometry.hpp>
37 
38 namespace vl
39 {
40  //------------------------------------------------------------------------------
41  // Volume
42  //------------------------------------------------------------------------------
47  {
49 
50 
53  struct Cube
54  {
55  Cube(): mMin(0), mMax(0) {}
56  float mMin, mMax;
57  bool includes(float v) const { return v >= mMin && v <= mMax; }
58  };
59  public:
60  Volume();
61 
67  void setup(float* data, bool use_directly, bool copy_data, const fvec3& bottom_left, const fvec3& top_right, const ivec3& slices);
68 
69  void setup(const Volume&);
70 
74  ref<Volume> downsample() const;
75 
76  const float* values() const { return mValues; }
77 
78  float* values() { return mValues; }
79 
80  const float& value(int i) const { return mValues[i]; }
81 
82  float& value(int i) { return mValues[i]; }
83 
84  const float& value(int x, int y, int z) const { return mValues[x + mSlices.x()*y + mSlices.x()*mSlices.y()*z]; }
85 
86  float& value(int x, int y, int z) { return mValues[x + mSlices.x()*y + mSlices.x()*mSlices.y()*z]; }
87 
89  void normalHQ(fvec3& normal, const fvec3& v, float dx, float dy, float dz);
90 
92  void normalLQ(fvec3& normal, const fvec3& v, float dx, float dy, float dz);
93 
95  float sampleSmooth(float x, float y, float z) const;
96 
98  float sampleNearest(float x, float y, float z) const;
99 
100  fvec3 coordinate(int x, int y, int z) const { return mBottomLeft + fvec3(float(mCellSize.x()*x), float(mCellSize.y()*y), float(mCellSize.z()*z)); }
101 
102  const fvec3& bottomLeft() const { return mBottomLeft; }
103 
104  const fvec3& topRight() const { return mTopRight; }
105 
106  const ivec3& slices() const { return mSlices; }
107 
108  fvec3 size() const { return mSize; }
109 
110  float computeMinimum() const;
111 
112  float computeMaximum() const;
113 
114  float computeAverage() const;
115 
116  float minimum() const { return mMinimum; }
117 
118  float maximum() const { return mMaximum; }
119 
120  float average() const { return mAverage; }
121 
122  const Volume::Cube& cube(int x, int y, int z) const
123  {
124  VL_CHECK(x<slices().x()-1)
125  VL_CHECK(y<slices().y()-1)
126  VL_CHECK(z<slices().z()-1)
127  return mCubes[ x + y*(slices().x()-1) + z*(slices().x()-1)*(slices().y()-1) ];
128  }
129 
131  const fvec3& cellSize() const { return mCellSize; }
132 
134  bool dataIsDirty() const { return mDataIsDirty; }
135 
137  void setDataDirty() { mDataIsDirty = true; }
138 
139  void setupInternalData();
140 
141  protected:
142  std::vector<float> mInternalValues;
143  float* mValues;
149  float mMinimum;
150  float mMaximum;
151  float mAverage;
153 
154  std::vector<Cube> mCubes;
155  };
156  //------------------------------------------------------------------------------
157  // VolumeInfo
158  //------------------------------------------------------------------------------
162  class VolumeInfo: public Object
163  {
165 
166  public:
168  {
169  VL_DEBUG_SET_OBJECT_NAME()
170  mThreshold = 0;
171  mVolume = NULL;
172  mVert0 = -1;
173  mVertC = -1;
174  }
175 
176  VolumeInfo(Volume* vol, float threshold)
177  {
178  VL_DEBUG_SET_OBJECT_NAME()
179  mThreshold = threshold;
180  mVolume = vol;
181  mVert0 = -1;
182  mVertC = -1;
183  }
184 
185  VolumeInfo(Volume* vol, float threshold, const fvec4& color)
186  {
187  VL_DEBUG_SET_OBJECT_NAME()
188  mColor = color;
189  mThreshold = threshold;
190  mVolume = vol;
191  mVert0 = -1;
192  mVertC = -1;
193  }
194 
195  void setColor(const fvec4& col) { mColor = col; }
196  const fvec4& color() const { return mColor; }
197 
198  void setThreshold(float t) { mThreshold = t; }
199  float threshold() const { return mThreshold; }
200 
201  void setVolume(Volume* vol) { mVolume = vol; }
202  const Volume* volume() const { return mVolume.get(); }
203  Volume* volume() { return mVolume.get(); }
204 
205  void setVert0(int index) { mVert0 = index; }
206  int vert0() const { return mVert0; }
207 
208  void setVertC(int count) { mVertC = count; }
209  int vertC() const { return mVertC; }
210 
211  protected:
213  float mThreshold;
215  int mVert0, mVertC;
216  };
217  //------------------------------------------------------------------------------
218  // MarchingCubes
219  //------------------------------------------------------------------------------
224  {
225  public:
226  MarchingCubes();
227 
228  void run(bool generate_colors);
229 
230  void reset();
231 
232  const Collection<VolumeInfo>* volumeInfo() const { return &mVolumeInfo; }
233  Collection<VolumeInfo>* volumeInfo() { return &mVolumeInfo; }
234 
235  void updateColor(const fvec3& color, int volume_index);
236  void updateColor(const fvec4& color, int volume_index);
237  void updateAlpha(float alpha, int volume_index);
238 
240  void setHighQualityNormals(bool hq) { mHighQualityNormals = hq; }
242  bool highQualityNormals() const { return mHighQualityNormals; }
243 
244  public:
248 
249  // OpenGL ES does not support DrawElementsUInt
250 #if defined(VL_OPENGL)
251  ref<DrawElementsUInt> mDrawElements;
252 #else
254 #endif
255 
256  protected:
257  void computeEdges(Volume*, float threshold);
258  void processCube(int x, int y, int z, Volume* vol, float threshold);
259 
260  private:
261  std::vector<fvec3> mVerts;
262  std::vector<fvec3> mNorms;
263  std::vector<fvec4> mColors;
264 
265 #if defined(VL_OPENGL)
266  typedef unsigned int IndexType;
267 #else
268  typedef unsigned short IndexType;
269 #endif
270  std::vector<IndexType> mIndices;
271 
272  struct Edge
273  {
274  Edge(): mX(-1), mY(-1), mZ(-1) {}
275  int mX, mY, mZ;
276  };
277  std::vector<Edge> mEdges;
278  std::vector<usvec3> mCubes;
279  Collection<VolumeInfo> mVolumeInfo;
280  bool mHighQualityNormals;
281 
282  protected:
283  static const int mTriangleConnectionTable[256][16];
284  static const int mCubeEdgeFlags[256];
285  };
286  //------------------------------------------------------------------------------
287 }
288 
289 #endif
Defines the volume data to be used with a MarchingCube object.
ref< DrawElementsUShort > mDrawElements
Vector3< float > fvec3
A 3 components vector with float precision.
Definition: Vector3.hpp:252
fvec3 coordinate(int x, int y, int z) const
const float & value(int x, int y, int z) const
void setVolume(Volume *vol)
const Volume::Cube & cube(int x, int y, int z) const
void setDataDirty()
Notifies that the data of a Volume has changed and that the internal acceleration structures should b...
int vert0() const
float average() const
Collection< VolumeInfo > * volumeInfo()
Defines the volume parameters to be used with a MarchingCube and Volume object.
std::vector< float > mInternalValues
ref< ArrayFloat4 > mColorArray
Volume * volume()
const Collection< VolumeInfo > * volumeInfo() const
float & value(int x, int y, int z)
#define VL_INSTRUMENT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:122
const float & value(int i) const
bool dataIsDirty() const
Returns true if the internal data hasn&#39;t been updated since the last call to setDataDirty() or setup(...
An efficient implementation of the Marching Cubes algorithm.
Visualization Library main namespace.
ref< ArrayFloat3 > mVertsArray
float minimum() const
int vertC() const
const ivec3 & slices() const
ref< ArrayFloat3 > mNormsArray
const float * values() const
The base class for all the reference counted objects.
Definition: Object.hpp:158
void setColor(const fvec4 &col)
float & value(int i)
void setThreshold(float t)
const T_Scalar & y() const
Definition: Vector3.hpp:90
#define NULL
Definition: OpenGLDefs.hpp:81
bool highQualityNormals() const
Select hight quality normals for best rendering quality, select low quality normals for best performa...
const Volume * volume() const
const fvec3 & cellSize() const
Returns the x/y/z size of a cell.
VolumeInfo(Volume *vol, float threshold, const fvec4 &color)
ref< Volume > mVolume
float maximum() const
void setVert0(int index)
It&#39;s basically an std::vector for Objects that is itself an Object so it can be reference counted and...
Definition: Collection.hpp:49
void setVertC(int count)
float * values()
void setHighQualityNormals(bool hq)
Select hight quality normals for best rendering quality, select low quality normals for best performa...
const fvec4 & color() const
const fvec3 & topRight() const
const T_Scalar & x() const
Definition: Vector3.hpp:89
VolumeInfo(Volume *vol, float threshold)
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
#define VL_CHECK(expr)
Definition: checks.hpp:73
fvec3 size() const
std::vector< Cube > mCubes
const fvec3 & bottomLeft() const
float * mValues
float threshold() const