Fade2.5D Documentation pages v2.15
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 
42 struct CLASS_DECLSPEC FadeExport
43 {
44  FadeExport():
45  numCustomIndices(0),numTriangles(0),numPoints(0),
46  aCoords(NULL),aCustomIndices(NULL),aTriangles(NULL)
47  {
48 #if GEOM_PSEUDO3D==GEOM_TRUE
49  dim=3;
50 #else
51  dim=2;
52 #endif
53  }
54  ~FadeExport();
55 
56 
57  FadeExport(const FadeExport& other)
58  {
59  copy(other);
60  }
61 
62  FadeExport& operator=(const FadeExport& other)
63  {
64  copy(other);
65  return *this;
66  }
67 
68  void copy(const FadeExport& other)
69  {
70  numCustomIndices=other.numCustomIndices;
71  numTriangles=other.numTriangles;
72  numPoints=other.numPoints;
73  aCoords=NULL;
74  aCustomIndices=NULL;
75  aTriangles=NULL;
76  dim=other.dim;
77  if(other.aTriangles!=NULL)
78  {
79  size_t siz(3*numTriangles);
80  aTriangles=new int[siz];
81  std::copy(other.aTriangles,other.aTriangles+siz,aTriangles);
82  }
83  if(other.aCoords!=NULL)
84  {
85  size_t siz(dim*numPoints);
86  aCoords=new double[siz];
87  std::copy(other.aCoords,other.aCoords+siz,aCoords);
88  }
89  if(other.aCustomIndices!=NULL)
90  {
91  aCustomIndices=new int[numCustomIndices];
92  std::copy(other.aCustomIndices,other.aCustomIndices+numCustomIndices,aCustomIndices);
93  }
94  }
95 
100  void reset()
101  {
102  if(aCoords!=NULL) delete [] aCoords;
103  if(aCustomIndices!=NULL) delete [] aCustomIndices;
104  if(aTriangles!=NULL) delete [] aTriangles;
105 
106  aCoords=NULL;
107  aCustomIndices=NULL;
108  aTriangles=NULL;
109 
110  numCustomIndices=0;
111  numTriangles=0;
112  numPoints=0;
113  }
114 
119  void lexiSort();
120 
122  void print() const;
123 
125  bool writeObj(const char* filename) const;
126 
128  void extractTriangleNeighborships(std::vector<std::pair<int,int> >& vNeigs) const;
129 
135  void getCornerIndices(int triIdx,int& vtxIdx0,int& vtxIdx1,int& vtxIdx2) const;
136 
143  int getCustomIndex(int vtxIdx) const;
144 
145 #if GEOM_PSEUDO3D==GEOM_TRUE
147  void getNormal(int triIdx,double& x,double& y,double& z) const;
148 #endif
149 
150 #if GEOM_PSEUDO3D==GEOM_TRUE
156  void getCoordinates(int vtxIdx,double& x,double& y,double& z) const;
157 #else
163  void getCoordinates(int vtxIdx,double& x,double& y) const;
164 #endif
165  bool operator==(const FadeExport& other) const;
166  // DATA
169  int numPoints;
170  double* aCoords;
172  int* aTriangles;
173  int dim;
174 };
175 
176 inline FadeExport::~FadeExport()
177 {
178  if(aCoords!=NULL) delete [] aCoords;
179  if(aCustomIndices!=NULL) delete [] aCustomIndices;
180  if(aTriangles!=NULL) delete [] aTriangles;
181  numCustomIndices=0;
182  numTriangles=0;
183  numPoints=0;
184 }
185 
186 inline bool FadeExport::operator==(const FadeExport& other) const
187 {
188  if(numTriangles != other.numTriangles) return false;
189  if(numPoints != other.numPoints) return false;
190 
191  for(int vtxIdx=0;vtxIdx<numPoints;++vtxIdx)
192  {
193  for(int component=0;component<dim;++component)
194  {
195  size_t addr(dim*vtxIdx+component);
196  if(aCoords[addr]!=other.aCoords[addr]) return false;
197  }
198  }
199 
200  for(int triIdx=0;triIdx<numTriangles;++triIdx)
201  {
202  int v0,v1,v2;
203  getCornerIndices(int(triIdx),v0,v1,v2);
204  int va,vb,vc;
205  other.getCornerIndices(int(triIdx),va,vb,vc);
206  if(v0!=va || v1!=vb || v2!=vc) return false;
207  }
208  return true;
209 }
210 
211 
212 // For a triangle return the vertex indices
213 inline void FadeExport::getCornerIndices(int triIdx,int& vtxIdx0,int& vtxIdx1,int& vtxIdx2) const
214 {
215  int base(3*triIdx);
216  vtxIdx0=aTriangles[base];
217  vtxIdx1=aTriangles[base+1];
218  vtxIdx2=aTriangles[base+2];
219 }
220 
221 // Print, just for demo purposes
222 inline void FadeExport::print() const
223 {
224  for(int vtxIdx=0;vtxIdx<numPoints;++vtxIdx)
225  {
226  int customIndex(-1); // Optional custom index
227  if(numCustomIndices>0) customIndex=aCustomIndices[vtxIdx];
228  std::cout<<"\nVertex "<<vtxIdx<<" (customIndex="<<customIndex<<"):";
229  for(int component=0;component<dim;++component) std::cout<<" "<<aCoords[dim*vtxIdx+component];
230  }
231 
232  for(int triIdx=0;triIdx<numTriangles;++triIdx)
233  {
234  int v0,v1,v2;
235  getCornerIndices(int(triIdx),v0,v1,v2);
236  std::cout<<"\nTriangle "<<triIdx<<": "<<v0<<" "<<v1<<" "<<v2;
237  }
238 
239  std::vector<std::pair<int,int> > vNeighbors;
240  this->extractTriangleNeighborships(vNeighbors);
241  for(size_t i=0;i<vNeighbors.size();++i)
242  {
243  std::cout<<"\nTriangle "<<vNeighbors[i].first<<" <-> Triangle "<<vNeighbors[i].second;
244  }
245  std::cout<<std::endl;
246 }
247 
248 // Write an *.obj file
249 inline bool FadeExport::writeObj(const char* filename) const
250 {
251  std::ofstream outFile(filename);
252  if(!outFile.is_open())
253  {
254  std::cout<<"Can't write "<<filename<<std::endl;
255  return false;
256  }
257  std::cout<<"writing "<<filename<<std::endl;
258 
259  outFile<<"# Written by Fade2D";
260  for(int vtxIdx=0;vtxIdx<numPoints;++vtxIdx)
261  {
262  outFile<<"\nv";
263  for(int component=0;component<dim;++component) outFile<<" "<<aCoords[dim*vtxIdx+component];
264  if(dim==2) outFile<<" 0"; // *.obj needs always 3 components, so add z=0
265  }
266  for(int triIdx=0;triIdx<numTriangles;++triIdx)
267  {
268  outFile<<"\nf";
269  for(int corner=0;corner<3;++corner)
270  {
271  outFile<<" "<<aTriangles[3*triIdx+corner]+1; // +1 because in *.obj format indices start at 1, not 0.
272  }
273  }
274  outFile<<std::endl;
275  outFile.close();
276  return true;
277 }
278 
279 
280 inline void FadeExport::extractTriangleNeighborships(std::vector<std::pair<int,int> >& vNeigs) const
281 {
282  vNeigs.reserve(numTriangles*3/2);
283  std::vector<std::pair<std::pair<int,int>,int> > vVtxPair2Tri;
284  vVtxPair2Tri.reserve(numTriangles*3);
285 
286  for(int tri=0;tri<numTriangles;++tri)
287  {
288  size_t vtxIdx(3*tri);
289  int vtx0(aTriangles[vtxIdx]);
290  int vtx1(aTriangles[vtxIdx+1]);
291  int vtx2(aTriangles[vtxIdx+2]);
292  if(vtx0>vtx1) std::swap(vtx0,vtx1);
293  if(vtx1>vtx2)
294  {
295  std::swap(vtx1,vtx2);
296  if(vtx0>vtx1) std::swap(vtx0,vtx1);
297  }
298  vVtxPair2Tri.push_back(std::make_pair(std::make_pair(vtx0,vtx1),tri));
299  vVtxPair2Tri.push_back(std::make_pair(std::make_pair(vtx1,vtx2),tri));
300  vVtxPair2Tri.push_back(std::make_pair(std::make_pair(vtx0,vtx2),tri));
301  }
302  std::sort(vVtxPair2Tri.begin(),vVtxPair2Tri.end());
303  for(size_t i=0;i<vVtxPair2Tri.size();++i)
304  {
305  int vtx0(vVtxPair2Tri[i].first.first);
306  int vtx1(vVtxPair2Tri[i].first.second);
307  int tri0(vVtxPair2Tri[i].second);
308 
309  if( ++i<vVtxPair2Tri.size() &&
310  vVtxPair2Tri[i].first.first==vtx0 &&
311  vVtxPair2Tri[i].first.second==vtx1)
312  {
313  int tri1(vVtxPair2Tri[i].second);
314  vNeigs.push_back(std::pair<int,int>(tri0,tri1));
315  }
316  --i;
317  }
318 }
319 
320 
321 #if GEOM_PSEUDO3D==GEOM_TRUE
322 inline void FadeExport::getCoordinates(int vtxIdx,double& x,double& y,double& z) const
323 {
324  int base(dim*vtxIdx);
325  x=aCoords[base];
326  y=aCoords[base+1];
327  z=aCoords[base+2];
328 }
329 #else
330 inline void FadeExport::getCoordinates(int vtxIdx,double& x,double& y) const
331 {
332  int base(dim*vtxIdx);
333  x=aCoords[base];
334  y=aCoords[base+1];
335 }
336 #endif
337 
338 inline int FadeExport::getCustomIndex(int vtxIdx) const
339 {
340  if(vtxIdx<numCustomIndices)
341  {
342  return aCustomIndices[vtxIdx];
343  }
344  return -1;
345 }
346 
347 } // (namespace)
348 
349 
350 
351 
352 
FadeExport is a simple struct to export triangulation data.
Definition: FadeExport.h:43
void reset()
Reset the object.
Definition: FadeExport.h:100
void getNormal(int triIdx, double &x, double &y, double &z) const
Get the normal vector of a triangle.
int numTriangles
number of triangles
Definition: FadeExport.h:168
void print() const
Print data for demonstration purposes.
Definition: FadeExport.h:222
void lexiSort()
Sort the points lexicographically.
int * aCustomIndices
Custom indices of the points (only when exported)
Definition: FadeExport.h:171
void getCornerIndices(int triIdx, int &vtxIdx0, int &vtxIdx1, int &vtxIdx2) const
Get the corner indices of a certain triangle.
Definition: FadeExport.h:213
int getCustomIndex(int vtxIdx) const
Get the custom vertex index.
Definition: FadeExport.h:338
int dim
Dimension.
Definition: FadeExport.h:173
void extractTriangleNeighborships(std::vector< std::pair< int, int > > &vNeigs) const
Determine index-pairs of adjacent triangles.
Definition: FadeExport.h:280
int numPoints
number of points
Definition: FadeExport.h:169
int numCustomIndices
number of custom indices (same as numPoints when exported, otherwise 0)
Definition: FadeExport.h:167
bool writeObj(const char *filename) const
Write an *.obj file (supported by virtually any 3D viewer)
Definition: FadeExport.h:249
double * aCoords
Cartesian coordinates (dim*numPoints)
Definition: FadeExport.h:170
void getCoordinates(int vtxIdx, double &x, double &y, double &z) const
Get the coorinates for a certain vertex index.
Definition: FadeExport.h:322
int * aTriangles
3 counterclockwise oriented vertex-indices per triangle (3*numTriangles)
Definition: FadeExport.h:172