OMToolkit 1.0 The polygonal mesh processing tool.

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
OMTriIterator.h
Go to the documentation of this file.
1 //==============================================================================
16 #ifndef _OM_TRI_ITERATOR_H_
17 #define _OM_TRI_ITERATOR_H_
18
19 // MDSTk
20 #include <MDSTk/Base/mdsMemory.h>
21 #include <MDSTk/Base/mdsIterator.h>
22 #include <MDSTk/Math/mdsBase.h>
23
24 #include <OpenMesh\Core\Geometry\VectorT.hh>
25
26 namespace OpenMesh
27 {
28 //==============================================================================
32 template <class VectorT>
33 class OMTriIterator : public mds::base::CIteratorBase<OMTriIterator<VectorT>>
34 {
35 public:
40 OMTriIterator(VectorT *vertices)
41 {
42 init(vertices);
43 }
44
48 ~OMTriIterator() {}
49
54 mds::tSize getX() const
55 {
56 return m_Impl.m_X;
57 }
58
63 mds::tSize getY() const
64 {
65 return m_Impl.m_Y;
66 }
67
72 bool isEnd() const
73 {
74 return (m_Impl.m_Y > m_Impl.m_iMaxY);
75 }
76
77 protected:
81 struct SDataMembers
82 {
86 int m_iMinX, m_iMaxX, m_iMinY, m_iMaxY;
87
91 int m_iFDX1, m_iFDX2, m_iFDX3;
92 int m_iFDY1, m_iFDY2, m_iFDY3;
93
97 int m_iCY1, m_iCY2, m_iCY3;
98 int m_iCX1, m_iCX2, m_iCX3;
99
103 mds::tSize m_X, m_Y;
104 };
105
109 SDataMembers m_Impl;
110
111 public:
115 void advance()
116 {
117 do {
118 if( isEnd() )
119 {
120 break;
121 }
122 else
123 {
124 next();
125 }
126 } while( !isInner() );
127 }
128
129 protected:
133 bool isInner()
134 {
135 return (m_Impl.m_iCX1 <= 0 && m_Impl.m_iCX2 <= 0 && m_Impl.m_iCX3 <= 0);
136 }
137
141 void init(VectorT *vertices)
142 {
143 // Fixed-point coordinates
144 int iY1 = mds::math::round2Int(16.0 * vertices[0][1]);
145 int iY2 = mds::math::round2Int(16.0 * vertices[1][1]);
146 int iY3 = mds::math::round2Int(16.0 * vertices[2][1]);
147
148 int iX1 = mds::math::round2Int(16.0 * vertices[0][0]);
149 int iX2 = mds::math::round2Int(16.0 * vertices[1][0]);
150 int iX3 = mds::math::round2Int(16.0 * vertices[2][0]);
151
152 // Deltas
153 int iDX1 = iX2 - iX1;
154 int iDX2 = iX3 - iX2;
155 int iDX3 = iX1 - iX3;
156
157 int iDY1 = iY2 - iY1;
158 int iDY2 = iY3 - iY2;
159 int iDY3 = iY1 - iY3;
160
161 // Fixed-point deltas
162 m_Impl.m_iFDX1 = iDX1 << 4;
163 m_Impl.m_iFDX2 = iDX2 << 4;
164 m_Impl.m_iFDX3 = iDX3 << 4;
165
166 m_Impl.m_iFDY1 = iDY1 << 4;
167 m_Impl.m_iFDY2 = iDY2 << 4;
168 m_Impl.m_iFDY3 = iDY3 << 4;
169
170 // Bounding rectangle
171 m_Impl.m_iMinX = mds::math::getMin(iX1, iX2, iX3) >> 4;
172 m_Impl.m_iMaxX = mds::math::getMax(iX1, iX2, iX3) >> 4;
173 m_Impl.m_iMinY = mds::math::getMin(iY1, iY2, iY3) >> 4;
174 m_Impl.m_iMaxY = mds::math::getMax(iY1, iY2, iY3) >> 4;
175
176 // Half-edge constants
177 int iC1 = iDX1 * iY1 - iDY1 * iX1;
178 int iC2 = iDX2 * iY2 - iDY2 * iX2;
179 int iC3 = iDX3 * iY3 - iDY3 * iX3;
180
181 // Initialization
182 m_Impl.m_iCY1 = iC1 - iDX1 * (m_Impl.m_iMinY << 4) + iDY1 * (m_Impl.m_iMinX << 4);
183 m_Impl.m_iCY2 = iC2 - iDX2 * (m_Impl.m_iMinY << 4) + iDY2 * (m_Impl.m_iMinX << 4);
184 m_Impl.m_iCY3 = iC3 - iDX3 * (m_Impl.m_iMinY << 4) + iDY3 * (m_Impl.m_iMinX << 4);
185
186 m_Impl.m_iCX1 = m_Impl.m_iCY1;
187 m_Impl.m_iCX2 = m_Impl.m_iCY2;
188 m_Impl.m_iCX3 = m_Impl.m_iCY3;
189
190 m_Impl.m_X = m_Impl.m_iMinX;
191 m_Impl.m_Y = m_Impl.m_iMinY;
192
193 // Find the first pixel
194 if( !isInner() )
195 {
196 advance();
197 }
198 }
199
203 void next()
204 {
205 if( ++m_Impl.m_X > m_Impl.m_iMaxX )
206 {
207 m_Impl.m_X = m_Impl.m_iMinX;
208 ++m_Impl.m_Y;
209 m_Impl.m_iCY1 -= m_Impl.m_iFDX1;
210 m_Impl.m_iCY2 -= m_Impl.m_iFDX2;
211 m_Impl.m_iCY3 -= m_Impl.m_iFDX3;
212 m_Impl.m_iCX1 = m_Impl.m_iCY1;
213 m_Impl.m_iCX2 = m_Impl.m_iCY2;
214 m_Impl.m_iCX3 = m_Impl.m_iCY3;
215 }
216 else
217 {
218 m_Impl.m_iCX1 += m_Impl.m_iFDY1;
219 m_Impl.m_iCX2 += m_Impl.m_iFDY2;
220 m_Impl.m_iCX3 += m_Impl.m_iFDY3;
221 }
222 }
223 };
224
225 } // namespace OMToolkit
226
227 #endif // _OM_TRI_ITERATOR_H_
228