PolyVox  0.3.0-dev
Open source voxel management library
CubicSurfaceExtractor.h
Go to the documentation of this file.
1 /*******************************************************************************
2 Copyright (c) 2005-2009 David Williams
3 
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7 
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11 
12  1. The origin of this software must not be misrepresented; you must not
13  claim that you wrote the original software. If you use this software
14  in a product, an acknowledgment in the product documentation would be
15  appreciated but is not required.
16 
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19 
20  3. This notice may not be removed or altered from any source
21  distribution.
22 *******************************************************************************/
23 
24 #ifndef __PolyVox_CubicSurfaceExtractor_H__
25 #define __PolyVox_CubicSurfaceExtractor_H__
26 
27 #include "Impl/TypeDef.h"
28 
30 
31 #include "PolyVoxCore/Array.h"
32 #include "PolyVoxCore/BaseVolume.h" //For wrap modes... should move these?
35 
36 namespace PolyVox
37 {
79  template<typename VolumeType, typename IsQuadNeeded>
81  {
82  struct IndexAndMaterial
83  {
84  int32_t iIndex;
85  int32_t uMaterial; //Should actually use the material type here, but this is ok for now.
86  };
87 
88  enum FaceNames
89  {
90  PositiveX,
91  PositiveY,
92  PositiveZ,
93  NegativeX,
94  NegativeY,
95  NegativeZ,
96  NoOfFaces
97  };
98 
99  struct Quad
100  {
101  Quad(uint32_t v0, uint32_t v1, uint32_t v2, uint32_t v3)
102  {
103  vertices[0] = v0;
104  vertices[1] = v1;
105  vertices[2] = v2;
106  vertices[3] = v3;
107  }
108 
109  uint32_t vertices[4];
110  };
111 
112  public:
113  // This is a bit ugly - it seems that the C++03 syntax is different from the C++11 syntax? See this thread: http://stackoverflow.com/questions/6076015/typename-outside-of-template
114  // Long term we should probably come back to this and if the #ifdef is still needed then maybe it should check for C++11 mode instead of MSVC?
115 #if defined(_MSC_VER)
116  CubicSurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh<PositionMaterial>* result, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = VolumeType::VoxelType(), bool bMergeQuads = true, IsQuadNeeded isQuadNeeded = IsQuadNeeded());
117 #else
118  CubicSurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh<PositionMaterial>* result, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true, IsQuadNeeded isQuadNeeded = IsQuadNeeded());
119 #endif
120 
121 
122  void execute();
123 
124  private:
125  int32_t addVertex(uint32_t uX, uint32_t uY, uint32_t uZ, uint32_t uMaterial, Array<3, IndexAndMaterial>& existingVertices);
126  bool performQuadMerging(std::list<Quad>& quads);
127  bool mergeQuads(Quad& q1, Quad& q2);
128 
129  IsQuadNeeded m_funcIsQuadNeededCallback;
130 
131  //The volume data and a sampler to access it.
132  VolumeType* m_volData;
133 
134  //Information about the region we are currently processing
135  Region m_regSizeInVoxels;
136 
137  //The surface patch we are currently filling.
138  SurfaceMesh<PositionMaterial>* m_meshCurrent;
139 
140  //Used to avoid creating duplicate vertices.
141  Array<3, IndexAndMaterial> m_previousSliceVertices;
142  Array<3, IndexAndMaterial> m_currentSliceVertices;
143 
144  //During extraction we create a number of different lists of quads. All the
145  //quads in a given list are in the same plane and facing in the same direction.
146  std::vector< std::list<Quad> > m_vecQuads[NoOfFaces];
147 
148  //Controls whether quad merging should be performed. This might be undesirable
149  //is the user needs per-vertex attributes, or to perform per vertex lighting.
150  bool m_bMergeQuads;
151 
152  //This constant defines the maximum number of quads which can share a
153  //vertex in a cubic style mesh. See the initialisation for more details.
154  static const uint32_t MaxVerticesPerPosition;
155 
156  //The wrap mode
157  WrapMode m_eWrapMode;
158  typename VolumeType::VoxelType m_tBorderValue;
159  };
160 }
161 
163 
164 #endif