Fade2D Documentation pages v2.01
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 
61  void lexiSort();
62 
64  void print() const;
65 
67  bool writeObj(const char* filename) const;
68 
70  void extractTriangleNeighborships(std::vector<std::pair<int,int> >& vNeigs) const;
71 
77  void getCornerIndices(int triIdx,int& vtxIdx0,int& vtxIdx1,int& vtxIdx2) const;
78 
85  int getCustomIndex(int vtxIdx) const;
86 
87 #if GEOM_PSEUDO3D==GEOM_TRUE
89  void getNormal(int triIdx,double& x,double& y,double& z) const;
90 #endif
91 
92 #if GEOM_PSEUDO3D==GEOM_TRUE
98  void getCoordinates(int vtxIdx,double& x,double& y,double& z) const;
99 #else
105  void getCoordinates(int vtxIdx,double& x,double& y) const;
106 #endif
107  bool operator==(const FadeExport& other) const;
108  // DATA
111  int numPoints;
112  double* aCoords;
114  int* aTriangles;
115  int dim;
116 };
117 
118 inline FadeExport::~FadeExport()
119 {
120  if(aCoords!=NULL) delete [] aCoords;
121  if(aCustomIndices!=NULL) delete [] aCustomIndices;
122  if(aTriangles!=NULL) delete [] aTriangles;
123  numCustomIndices=0;
124  numTriangles=0;
125  numPoints=0;
126 }
127 
128 inline bool FadeExport::operator==(const FadeExport& other) const
129 {
130  if(numTriangles != other.numTriangles) return false;
131  if(numPoints != other.numPoints) return false;
132 
133  for(int vtxIdx=0;vtxIdx<numPoints;++vtxIdx)
134  {
135  for(int component=0;component<dim;++component)
136  {
137  size_t addr(dim*vtxIdx+component);
138  if(aCoords[addr]!=other.aCoords[addr]) return false;
139  }
140  }
141 
142  for(int triIdx=0;triIdx<numTriangles;++triIdx)
143  {
144  int v0,v1,v2;
145  getCornerIndices(int(triIdx),v0,v1,v2);
146  int va,vb,vc;
147  other.getCornerIndices(int(triIdx),va,vb,vc);
148  if(v0!=va || v1!=vb || v2!=vc) return false;
149  }
150  return true;
151 }
152 
153 
154 // For a triangle return the vertex indices
155 inline void FadeExport::getCornerIndices(int triIdx,int& vtxIdx0,int& vtxIdx1,int& vtxIdx2) const
156 {
157  int base(3*triIdx);
158  vtxIdx0=aTriangles[base];
159  vtxIdx1=aTriangles[base+1];
160  vtxIdx2=aTriangles[base+2];
161 }
162 
163 // Print, just for demo purposes
164 inline void FadeExport::print() const
165 {
166  for(int vtxIdx=0;vtxIdx<numPoints;++vtxIdx)
167  {
168  int customIndex(-1); // Optional custom index
169  if(numCustomIndices>0) customIndex=aCustomIndices[vtxIdx];
170  std::cout<<"\nVertex "<<vtxIdx<<" (customIndex="<<customIndex<<"):";
171  for(int component=0;component<dim;++component) std::cout<<" "<<aCoords[dim*vtxIdx+component];
172  }
173 
174  for(int triIdx=0;triIdx<numTriangles;++triIdx)
175  {
176  int v0,v1,v2;
177  getCornerIndices(int(triIdx),v0,v1,v2);
178  std::cout<<"\nTriangle "<<triIdx<<": "<<v0<<" "<<v1<<" "<<v2;
179  }
180 
181  std::vector<std::pair<int,int> > vNeighbors;
182  this->extractTriangleNeighborships(vNeighbors);
183  for(size_t i=0;i<vNeighbors.size();++i)
184  {
185  std::cout<<"\nTriangle "<<vNeighbors[i].first<<" <-> Triangle "<<vNeighbors[i].second;
186  }
187  std::cout<<std::endl;
188 }
189 
190 // Write an *.obj file
191 inline bool FadeExport::writeObj(const char* filename) const
192 {
193  std::ofstream outFile(filename);
194  if(!outFile.is_open())
195  {
196  std::cout<<"Can't write "<<filename<<std::endl;
197  return false;
198  }
199  std::cout<<"writing "<<filename<<std::endl;
200 
201  outFile<<"# Written by Fade2D";
202  for(int vtxIdx=0;vtxIdx<numPoints;++vtxIdx)
203  {
204  outFile<<"\nv";
205  for(int component=0;component<dim;++component) outFile<<" "<<aCoords[dim*vtxIdx+component];
206  if(dim==2) outFile<<" 0"; // *.obj needs always 3 components, so add z=0
207  }
208  for(int triIdx=0;triIdx<numTriangles;++triIdx)
209  {
210  outFile<<"\nf";
211  for(int corner=0;corner<3;++corner)
212  {
213  outFile<<" "<<aTriangles[3*triIdx+corner]+1; // +1 because in *.obj format indices start at 1, not 0.
214  }
215  }
216  outFile<<std::endl;
217  outFile.close();
218  return true;
219 }
220 
221 
222 inline void FadeExport::extractTriangleNeighborships(std::vector<std::pair<int,int> >& vNeigs) const
223 {
224  vNeigs.reserve(numTriangles*3/2);
225  std::vector<std::pair<std::pair<int,int>,int> > vVtxPair2Tri;
226  vVtxPair2Tri.reserve(numTriangles*3);
227 
228  for(int tri=0;tri<numTriangles;++tri)
229  {
230  size_t vtxIdx(3*tri);
231  int vtx0(aTriangles[vtxIdx]);
232  int vtx1(aTriangles[vtxIdx+1]);
233  int vtx2(aTriangles[vtxIdx+2]);
234  if(vtx0>vtx1) std::swap(vtx0,vtx1);
235  if(vtx1>vtx2)
236  {
237  std::swap(vtx1,vtx2);
238  if(vtx0>vtx1) std::swap(vtx0,vtx1);
239  }
240  vVtxPair2Tri.push_back(std::make_pair(std::make_pair(vtx0,vtx1),tri));
241  vVtxPair2Tri.push_back(std::make_pair(std::make_pair(vtx1,vtx2),tri));
242  vVtxPair2Tri.push_back(std::make_pair(std::make_pair(vtx0,vtx2),tri));
243  }
244  std::sort(vVtxPair2Tri.begin(),vVtxPair2Tri.end());
245  for(size_t i=0;i<vVtxPair2Tri.size();++i)
246  {
247  int vtx0(vVtxPair2Tri[i].first.first);
248  int vtx1(vVtxPair2Tri[i].first.second);
249  int tri(vVtxPair2Tri[i].second);
250  if( ++i<vVtxPair2Tri.size() &&
251  vVtxPair2Tri[i].first.first==vtx0 &&
252  vVtxPair2Tri[i].first.second==vtx1)
253  {
254  vNeigs.push_back(std::pair<int,int>(tri,vVtxPair2Tri[i].second));
255  }
256  --i;
257  }
258 }
259 
260 
261 #if GEOM_PSEUDO3D==GEOM_TRUE
262 inline void FadeExport::getCoordinates(int vtxIdx,double& x,double& y,double& z) const
263 {
264  int base(dim*vtxIdx);
265  x=aCoords[base];
266  y=aCoords[base+1];
267  z=aCoords[base+2];
268 }
269 #else
270 inline void FadeExport::getCoordinates(int vtxIdx,double& x,double& y) const
271 {
272  int base(dim*vtxIdx);
273  x=aCoords[base];
274  y=aCoords[base+1];
275 }
276 #endif
277 
278 inline int FadeExport::getCustomIndex(int vtxIdx) const
279 {
280  if(vtxIdx<numCustomIndices)
281  {
282  return aCustomIndices[vtxIdx];
283  }
284  return -1;
285 }
286 
287 } // (namespace)
288 
289 
290 
291 
292 
FadeExport is a simple struct to export triangulation data.
Definition: FadeExport.h:43
void lexiSort()
Sort the points lexicographically.
double * aCoords
Cartesian coordinates (dim*numPoints)
Definition: FadeExport.h:112
int * aCustomIndices
Custom indices of the points (only when exported)
Definition: FadeExport.h:113
int numTriangles
number of triangles
Definition: FadeExport.h:110
int * aTriangles
3 counterclockwise oriented vertex-indices per triangle (3*numTriangles)
Definition: FadeExport.h:114
int dim
Dimension.
Definition: FadeExport.h:115
int numCustomIndices
number of custom indices (same as numPoints when exported, otherwise 0)
Definition: FadeExport.h:109
int numPoints
number of points
Definition: FadeExport.h:111