Fade2D Documentation pages v2.16.3
Delaunay Features
FadeExport.h
Go to the documentation of this file.
1 // Copyright (C) Geom Software e.U, Bernhard Kornberger, Graz/Austria
2 //
3 // This file is part of the Fade2D library. The student license is free
4 // of charge and covers personal non-commercial research. Licensees
5 // holding a commercial license may use this file in accordance with
6 // the Commercial License Agreement.
7 //
8 // This software is provided AS IS with NO WARRANTY OF ANY KIND,
9 // INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
10 // FOR A PARTICULAR PURPOSE.
11 //
12 // Please contact the author if any conditions of this licensing are
13 // not clear to you.
14 //
15 // Author: Bernhard Kornberger, bkorn (at) geom.at
16 // http://www.geom.at
17 
19 #pragma once
20 
21 #include <vector>
22 #include <algorithm>
23 #include "common.h"
24 
25 #if GEOM_PSEUDO3D==GEOM_TRUE
26  namespace GEOM_FADE25D {
27 #elif GEOM_PSEUDO3D==GEOM_FALSE
28  namespace GEOM_FADE2D {
29 #else
30  #error GEOM_PSEUDO3D is not defined
31 #endif
32 
33 #ifdef _WIN32
34 #pragma warning(push)
35 #pragma warning(disable : 4996)
36 #endif
37 
47 struct CLASS_DECLSPEC FadeExport
48 {
49  FadeExport():
50  numCustomIndices(0),numTriangles(0),numPoints(0),
51  aCoords(NULL),aCustomIndices(NULL),aTriangles(NULL)
52  {
53 #if GEOM_PSEUDO3D==GEOM_TRUE
54  dim=3;
55 #else
56  dim=2;
57 #endif
58  }
59  ~FadeExport();
60 
61 
62  FadeExport(const FadeExport& other)
63  {
64  copy(other);
65  }
66 
67  FadeExport& operator=(const FadeExport& other)
68  {
69  copy(other);
70  return *this;
71  }
72 
73  void copy(const FadeExport& other)
74  {
75  numCustomIndices=other.numCustomIndices;
76  numTriangles=other.numTriangles;
77  numPoints=other.numPoints;
78  aCoords=NULL;
79  aCustomIndices=NULL;
80  aTriangles=NULL;
81  dim=other.dim;
82  if(other.aTriangles!=NULL)
83  {
84  size_t siz(3*numTriangles);
85  aTriangles=new int[siz];
86  std::copy(other.aTriangles,other.aTriangles+siz,aTriangles);
87  }
88  if(other.aCoords!=NULL)
89  {
90  size_t siz(dim*numPoints);
91  aCoords=new double[siz];
92  std::copy(other.aCoords,other.aCoords+siz,aCoords);
93  }
94  if(other.aCustomIndices!=NULL)
95  {
96  aCustomIndices=new int[numCustomIndices];
97  std::copy(other.aCustomIndices,other.aCustomIndices+numCustomIndices,aCustomIndices);
98  }
99  }
100 
105  void reset()
106  {
107  if(aCoords!=NULL) delete [] aCoords;
108  if(aCustomIndices!=NULL) delete [] aCustomIndices;
109  if(aTriangles!=NULL) delete [] aTriangles;
110 
111  aCoords=NULL;
112  aCustomIndices=NULL;
113  aTriangles=NULL;
114 
115  numCustomIndices=0;
116  numTriangles=0;
117  numPoints=0;
118  }
119 
124  void lexiSort();
125 
127  void print() const;
128 
130  bool writeObj(const char* filename) const;
131 
133  void extractTriangleNeighborships(std::vector<std::pair<int,int> >& vNeigs) const;
134 
140  void getCornerIndices(int triIdx,int& vtxIdx0,int& vtxIdx1,int& vtxIdx2) const;
141 
148  int getCustomIndex(int vtxIdx) const;
149 
150 #if GEOM_PSEUDO3D==GEOM_TRUE
152  void getNormal(int triIdx,double& x,double& y,double& z) const;
153 #endif
154 
155 #if GEOM_PSEUDO3D==GEOM_TRUE
161  void getCoordinates(int vtxIdx,double& x,double& y,double& z) const;
162 #else
168  void getCoordinates(int vtxIdx,double& x,double& y) const;
169 #endif
170  bool operator==(const FadeExport& other) const;
171  // DATA
174  int numPoints;
175  double* aCoords;
177  int* aTriangles;
178  int dim;
179 };
180 
181 inline FadeExport::~FadeExport()
182 {
183  if(aCoords!=NULL) delete [] aCoords;
184  if(aCustomIndices!=NULL) delete [] aCustomIndices;
185  if(aTriangles!=NULL) delete [] aTriangles;
186  numCustomIndices=0;
187  numTriangles=0;
188  numPoints=0;
189 }
190 
191 inline bool FadeExport::operator==(const FadeExport& other) const
192 {
193  if(numTriangles != other.numTriangles) return false;
194  if(numPoints != other.numPoints) return false;
195 
196  for(int vtxIdx=0;vtxIdx<numPoints;++vtxIdx)
197  {
198  for(int component=0;component<dim;++component)
199  {
200  size_t addr(dim*vtxIdx+component);
201  if(aCoords[addr]!=other.aCoords[addr]) return false;
202  }
203  }
204 
205  for(int triIdx=0;triIdx<numTriangles;++triIdx)
206  {
207  int v0,v1,v2;
208  getCornerIndices(int(triIdx),v0,v1,v2);
209  int va,vb,vc;
210  other.getCornerIndices(int(triIdx),va,vb,vc);
211  if(v0!=va || v1!=vb || v2!=vc) return false;
212  }
213  return true;
214 }
215 
216 
217 // For a triangle return the vertex indices
218 inline void FadeExport::getCornerIndices(int triIdx,int& vtxIdx0,int& vtxIdx1,int& vtxIdx2) const
219 {
220  int base(3*triIdx);
221  vtxIdx0=aTriangles[base];
222  vtxIdx1=aTriangles[base+1];
223  vtxIdx2=aTriangles[base+2];
224 }
225 
226 // Print, just for demo purposes
227 inline void FadeExport::print() const
228 {
229  for(int vtxIdx=0;vtxIdx<numPoints;++vtxIdx)
230  {
231  int customIndex(-1); // Optional custom index
232  if(numCustomIndices>0) customIndex=aCustomIndices[vtxIdx];
233  std::cout<<"\nVertex "<<vtxIdx<<" (customIndex="<<customIndex<<"):";
234  for(int component=0;component<dim;++component) std::cout<<" "<<aCoords[dim*vtxIdx+component];
235  }
236 
237  for(int triIdx=0;triIdx<numTriangles;++triIdx)
238  {
239  int v0,v1,v2;
240  getCornerIndices(int(triIdx),v0,v1,v2);
241  std::cout<<"\nTriangle "<<triIdx<<": "<<v0<<" "<<v1<<" "<<v2;
242  }
243 
244  std::vector<std::pair<int,int> > vNeighbors;
245  this->extractTriangleNeighborships(vNeighbors);
246  for(size_t i=0;i<vNeighbors.size();++i)
247  {
248  std::cout<<"\nTriangle "<<vNeighbors[i].first<<" <-> Triangle "<<vNeighbors[i].second;
249  }
250  std::cout<<std::endl;
251 }
252 
253 // Write an *.obj file
254 inline bool FadeExport::writeObj(const char* filename) const
255 {
256  std::ofstream outFile(filename);
257  if(!outFile.is_open())
258  {
259  std::cout<<"Can't write "<<filename<<std::endl;
260  return false;
261  }
262  std::cout<<"writing "<<filename<<std::endl;
263 
264  outFile<<"# Written by Fade2D";
265  for(int vtxIdx=0;vtxIdx<numPoints;++vtxIdx)
266  {
267  outFile<<"\nv";
268  for(int component=0;component<dim;++component) outFile<<" "<<aCoords[dim*vtxIdx+component];
269  if(dim==2) outFile<<" 0"; // *.obj needs always 3 components, so add z=0
270  }
271  for(int triIdx=0;triIdx<numTriangles;++triIdx)
272  {
273  outFile<<"\nf";
274  for(int corner=0;corner<3;++corner)
275  {
276  outFile<<" "<<aTriangles[3*triIdx+corner]+1; // +1 because in *.obj format indices start at 1, not 0.
277  }
278  }
279  outFile<<std::endl;
280  outFile.close();
281  return true;
282 }
283 
284 
285 inline void FadeExport::extractTriangleNeighborships(std::vector<std::pair<int,int> >& vNeigs) const
286 {
287  vNeigs.reserve(numTriangles*3/2);
288  std::vector<std::pair<std::pair<int,int>,int> > vVtxPair2Tri;
289  vVtxPair2Tri.reserve(numTriangles*3);
290 
291  for(int tri=0;tri<numTriangles;++tri)
292  {
293  size_t vtxIdx(3*tri);
294  int vtx0(aTriangles[vtxIdx]);
295  int vtx1(aTriangles[vtxIdx+1]);
296  int vtx2(aTriangles[vtxIdx+2]);
297  if(vtx0>vtx1) std::swap(vtx0,vtx1);
298  if(vtx1>vtx2)
299  {
300  std::swap(vtx1,vtx2);
301  if(vtx0>vtx1) std::swap(vtx0,vtx1);
302  }
303  vVtxPair2Tri.push_back(std::make_pair(std::make_pair(vtx0,vtx1),tri));
304  vVtxPair2Tri.push_back(std::make_pair(std::make_pair(vtx1,vtx2),tri));
305  vVtxPair2Tri.push_back(std::make_pair(std::make_pair(vtx0,vtx2),tri));
306  }
307  std::sort(vVtxPair2Tri.begin(),vVtxPair2Tri.end());
308  for(size_t i=0;i<vVtxPair2Tri.size();++i)
309  {
310  int vtx0(vVtxPair2Tri[i].first.first);
311  int vtx1(vVtxPair2Tri[i].first.second);
312  int tri0(vVtxPair2Tri[i].second);
313 
314  if( ++i<vVtxPair2Tri.size() &&
315  vVtxPair2Tri[i].first.first==vtx0 &&
316  vVtxPair2Tri[i].first.second==vtx1)
317  {
318  int tri1(vVtxPair2Tri[i].second);
319  vNeigs.push_back(std::pair<int,int>(tri0,tri1));
320  }
321  --i;
322  }
323 }
324 
325 
326 #if GEOM_PSEUDO3D==GEOM_TRUE
327 inline void FadeExport::getCoordinates(int vtxIdx,double& x,double& y,double& z) const
328 {
329  int base(dim*vtxIdx);
330  x=aCoords[base];
331  y=aCoords[base+1];
332  z=aCoords[base+2];
333 }
334 #else
335 inline void FadeExport::getCoordinates(int vtxIdx,double& x,double& y) const
336 {
337  int base(dim*vtxIdx);
338  x=aCoords[base];
339  y=aCoords[base+1];
340 }
341 #endif
342 
343 inline int FadeExport::getCustomIndex(int vtxIdx) const
344 {
345  if(vtxIdx<numCustomIndices)
346  {
347  return aCustomIndices[vtxIdx];
348  }
349  return -1;
350 }
351 #ifdef _WIN32
352 #pragma warning(pop)
353 #endif
354 } // (namespace)
355 
356 
357 
358 
359 
FadeExport is a simple struct to export triangulation data.
Definition: FadeExport.h:48
void reset()
Reset the object.
Definition: FadeExport.h:105
void lexiSort()
Sort the points lexicographically.
double * aCoords
Cartesian coordinates (dim*numPoints)
Definition: FadeExport.h:175
int * aCustomIndices
Custom indices of the points (only when exported)
Definition: FadeExport.h:176
int numTriangles
number of triangles
Definition: FadeExport.h:173
int * aTriangles
3 counterclockwise oriented vertex-indices per triangle (3*numTriangles)
Definition: FadeExport.h:177
int dim
Dimension.
Definition: FadeExport.h:178
int numCustomIndices
number of custom indices (same as numPoints when exported, otherwise 0)
Definition: FadeExport.h:172
int numPoints
number of points
Definition: FadeExport.h:174