Developer documentation | Axl-2.5.1

axlShapeBSplineConverter.cpp
Go to the documentation of this file.
2 
4 #include <axlCore/axlMesh.h>
5 
6 #include <dtkLog/dtkLog.h>
7 #include <dtkCoreSupport/dtkAbstractDataFactory.h>
8 
9 
10 class axlShapeBSplineConverterPrivate
11 {
12 public :
13  axlShapeBSpline *shape_spline;
14  axlMesh *output;
15  //QMap<int,QString> labels;//to link labels selection to the geometry and its mesh ?
16 
17  QMap< QPair<int, int>,int> isOnEdge;
18  QMap< QPair<int, int>,int> isOnFace;
19 
20  int nonInteriorEdgeIndices;
21 
22  QList<QString> labelsVertices;
23  QList<QString> labelsLines;
24  QList<QString> labelsTriangles;
25 };
26 
28 {
29  d->shape_spline = NULL;
30  d->output = new axlMesh;
31 }
32 
34 {
35 
36 }
37 
38 void axlShapeBSplineConverter::setData(dtkAbstractData *data){
39  if(axlShapeBSpline *axlData = dynamic_cast<axlShapeBSpline *>(data)){
40  d->shape_spline = axlData;
41  d->nonInteriorEdgeIndices = d->shape_spline->countBoundaryEdges();
42  }
43 }
44 //
45 // dtkAbstractData *axlShapeBSplineConverter::data() const{
46 // return d->output;
47 // }
48 
49 bool axlShapeBSplineConverter::isContained(axlMesh *mesh){
50  return false;
51 }
52 
54 {
55  if (!d->shape_spline)
56  return NULL;
57 
58  if(!d->output)
59  d->output = new axlMesh;
60 
61  axlMesh *mesh = d->output;
62  int s = mesh->vertex_count();
63 
64  int patch_count = d->shape_spline->countFaces();
65  qDebug() << "Number of patches" << d->shape_spline->countFaces();
66 
67  // count the number of points
68  qlonglong point_counter = 0;
69  qlonglong n_u_tot = 0;
70  qlonglong n_v_tot = 0;
71 
72  for (qlonglong p_idx = 0; p_idx < patch_count; ++p_idx) {
73  axlPoint* current_point = new axlPoint(0.,0.,0.);
74 
75  double start_u = d->shape_spline->startParam_u(p_idx);
76  double start_v = d->shape_spline->startParam_v(p_idx);
77  double end_u = d->shape_spline->endParam_u(p_idx);
78  double end_v = d->shape_spline->endParam_v(p_idx);
79 
80  double n_u = d->shape_spline->numSamples_u(p_idx);
81  double n_v = d->shape_spline->numSamples_v(p_idx);
82 
83  double interval_u = (double)(end_u - start_u) / (n_u - 1);
84  double interval_v = (double)(end_v - start_v) / (n_v - 1);
85  double current_param_u = start_u;
86  double current_param_v = start_v;
87 
88  //point_count += n_u*n_v;
89 
90  for (int j = 0; j < n_v; ++j) {
91  for (int i = 0; i < n_u; ++i) {
92 
93  d->shape_spline->eval(current_point, current_param_u, current_param_v, p_idx);
94 
95  // skip interior edges if duplicated
96  if (!( ((j == 0)) && (0 < p_idx) && (p_idx < patch_count) ))
97  mesh->push_back_vertex(current_point);
98 
99  qDebug() << point_counter << current_point;
100  point_counter++;
101 
102  current_param_u += interval_u;
103  }
104  current_param_u = start_u;
105  current_param_v += interval_v;
106  }
107  n_u_tot += n_u;
108  n_v_tot += n_v;
109  }
110 
111  // triangulate the domain
112  qlonglong patch_begin_idx = 0;
113 
114  for (qlonglong p_idx = 0; p_idx < patch_count; ++p_idx) {
115 
116  qDebug() << "Meshing patch" << p_idx;
117  int n_u = d->shape_spline->numSamples_u(p_idx);
118  int n_v = d->shape_spline->numSamples_v(p_idx);
119 
120 // int idx_1 = 0;
121 // int idx_2 = 0;
122 
123  for (int j = 0; j < n_v - 1; ++j) {
124  for (int i = 0; i < n_u - 1; ++i) {
125  int idx_1 = j * n_u + i + patch_begin_idx;
126  int idx_2 = idx_1 + 1;
127  int idx_3 = idx_1 + n_u;
128  int idx_4 = idx_3 + 1;
129 
130  qDebug() << "idx_1" << idx_1;
131 
132  QVector<int> first_triangle;
133  QVector<int> second_triangle;
134 
135  first_triangle.push_back(s + idx_1);
136  first_triangle.push_back(s + idx_2);
137  first_triangle.push_back(s + idx_3);
138 
139  second_triangle.push_back(s + idx_3);
140  second_triangle.push_back(s + idx_2);
141  second_triangle.push_back(s + idx_4);
142 
143  mesh->push_back_face(first_triangle);
144  mesh->push_back_face(second_triangle);
145  }
146  }
147 
148  patch_begin_idx += (n_u)*(n_v) - n_u; // start from the second patch minus the dimension of the linked edge
149  }
150  qDebug() << "Finished meshing";
151 
152  // // mesh blindly knowing the points, not completely working, too much implicit assumptions
153  // for (int i = 0; i < point_counter - (n_u_tot * 2); ++i) {
154  // int n_u = d->shape_spline->numSamples_u(0); // test
155 
156  // int idx_1 = i;
157  // int idx_2 = i + 1;
158  // int idx_3 = i + n_v_tot;
159  // int idx_4 = i + n_v_tot + 1;
160 
161  // QVector<int> first_triangle;
162  // QVector<int> second_triangle;
163 
164  // first_triangle.push_back(s + idx_1);
165  // first_triangle.push_back(s + idx_2);
166  // first_triangle.push_back(s + idx_3);
167 
168  // second_triangle.push_back(s + idx_2);
169  // second_triangle.push_back(s + idx_3);
170  // second_triangle.push_back(s + idx_4);
171 
172  // if ((i % (n_u - 1)) == 0)
173  // qDebug() << "YES";
174 
175  // if ( ((i % ((n_u - 1) * (n_u - 1))) != 0) ) {
176  // mesh->push_back_face(first_triangle);
177  // mesh->push_back_face(second_triangle);
178  // }
179  // }
180 
181  return mesh;
182 }
183 
184 
186  return "axlShapeBSplineConverter";
187 }
188 
189 QStringList axlShapeBSplineConverter::fromTypes(void) const{
190  return QStringList();
191 }
192 
193 QString axlShapeBSplineConverter::toType (void) const{
194  return "axlShapeBSplineConverter";
195 }
196 
198  //return axlMesherPlugin::dataFactSingleton->registerDataConverterType("axlShapeBSplineConverter", QStringList(), "axlMesh", createaxlShapeBSplineConverter);
199  return dtkAbstractDataFactory::instance()->registerDataConverterType("axlShapeBSplineConverter", QStringList(), "axlMesh", createaxlShapeBSplineConverter);
200 }
201 
202 int axlShapeBSplineConverter::isInterior(int i, int n_u, int n_v){
203  bool res = true;
204  if(i < n_u || i%n_u == 0 || i >= (n_v-1)*(n_u) || i%n_u == (n_u-1))
205  res = false;
206 
207  return res;
208 }
209 
210 QPair<int,int > axlShapeBSplineConverter::whatEdge(int numFace, int i, int n_u, int n_v){
211 
212  if (i < n_u) {
213  return QPair<int,int>(d->shape_spline->getFace(numFace)->edgesIndices.first(), i);
214  } else if (i >= (n_v-1)*(n_u)) {
215  return QPair<int,int>(d->shape_spline->getFace(numFace)->edgesIndices.last(), (i%((n_v-1)*(n_u))));
216  } else if (i%n_u == 0 ){
217  return QPair<int,int>(d->shape_spline->getFace(numFace)->edgesIndices.at(1), i/n_u);
218  } else { //if(i%n_u == (n_u-1))
219  return QPair<int,int>(d->shape_spline->getFace(numFace)->edgesIndices.at(2), (i+1)/n_u -1);
220  }
221 }
222 
223 void axlShapeBSplineConverter::insertEdge(axlMesh *mesh,int numEdge){
224 
225  //insert vertices different than first and last point of the mesh of the edge.
226  int count = d->output->vertex_count();
227  int n = d->shape_spline->getEdge(numEdge)->support->numSamples();
228  axlPoint *point = new axlPoint();
229 
230  for (int i = 1; i < (n-1); i++) {
231  d->output->push_back_vertex(mesh->vertex2(i,point));
232  d->labelsVertices.append(d->shape_spline->getEdge(numEdge)->tag);
233  d->isOnEdge.insert(QPair<int,int>(numEdge,i), i-1 + count);
234  }
235 
236  delete point;
237  point = NULL;
238 
239  if (numEdge < d->nonInteriorEdgeIndices) {
240  //insert all edges but with the global indice
241  for (int i = 0; i < mesh->edge_count(); i++) {
242 
243  int f = d->isOnEdge.value(QPair<int,int>(numEdge,mesh->edge(i).first()));
244  int s = d->isOnEdge.value(QPair<int,int>(numEdge,mesh->edge(i).last()));
245 
246  d->output->push_back_edge(f,s);
247  d->labelsLines.append(d->shape_spline->getEdge(numEdge)->tag);
248  }
249  }
250 }
251 
252 void axlShapeBSplineConverter::insertFace(axlMesh *mesh, int numFace){
253 
254  int count = d->output->vertex_count();
255  int nu = d->shape_spline->getFace(numFace)->support->numSamples_u();
256  int nv = d->shape_spline->getFace(numFace)->support->numSamples_v();
257 
258  axlPoint *point = new axlPoint();
259 
260  for (int j = 1; j < nv-1; j++) {
261  for (int i = 1; i < nu-1; i++) {
262  int ind = j*nu+i;
263  d->output->push_back_vertex(mesh->vertex2(ind, point));
264  d->labelsVertices.append("interior");
265  d->isOnFace.insert(QPair<int,int>(numFace,ind), count);
266  count++;
267  }
268  }
269 
270  delete point;
271  point = NULL;
272 
273  //insert all faces
274  for (int i = 0; i < mesh->face_count(); i++) {
275 
276  int formerf = mesh->face(i).first();
277  int formers = mesh->face(i).at(1);
278  int formert = mesh->face(i).last();
279 
280  int f = 0;
281  int s = 0;
282  int t = 0;
283 
284  if (isInterior(formerf,nu,nv)) {
285  f = d->isOnFace.value(QPair<int,int>(numFace, formerf));
286  } else {
287  QPair<int,int > numEdge = whatEdge(numFace, formerf, nu, nv);
288  f = d->isOnEdge.value(numEdge);
289  }
290 
291  if (isInterior(formers,nu,nv)) {
292  s = d->isOnFace.value(QPair<int,int>(numFace, formers));
293  } else {
294  QPair<int,int > numEdge = whatEdge(numFace, formers, nu, nv);
295  s = d->isOnEdge.value(numEdge);
296  }
297 
298  if (isInterior(formert,nu,nv)) {
299  t = d->isOnFace.value(QPair<int,int>(numFace, formert));
300  } else {
301  QPair<int,int > numEdge = whatEdge(numFace, formert, nu, nv);
302  t = d->isOnEdge.value(numEdge);
303  }
304 
305  d->output->push_back_face(f, s, t);
306  d->labelsTriangles.append("interior");
307  }
308 }
309 
311  if(i == 0)
312  return d->labelsVertices;
313  else if(i == 1)
314  return d->labelsLines;
315  else
316  return d->labelsTriangles;
317 }
318 
319 dtkAbstractDataConverter *createaxlShapeBSplineConverter(void){
320  return new axlShapeBSplineConverter;
321 }
Class axlPoint defines 3D points.
Definition: axlPoint.h:34
int face_count(void) const
Definition: axlMesh.cpp:138
QStringList fromTypes(void) const
void setData(dtkAbstractData *data)
int edge_count(void) const
Definition: axlMesh.cpp:143
QList< QString > getLabels(int i)
dtkAbstractDataConverter * createaxlShapeBSplineConverter(void)
axlPoint * vertex2(int ind, axlPoint *point) const
Set vertex values of vertices with index ind and return it.
Definition: axlMesh.cpp:260
void push_back_face(const Face &face)
Definition: axlMesh.cpp:735
Class axlShapeBSpline defines a set of boundary curves (Edges) and bspline surface patches (Face)...
int vertex_count(void) const
Definition: axlMesh.cpp:122
Face face(int ind) const
Definition: axlMesh.cpp:709
Edge edge(int ind) const
Definition: axlMesh.cpp:640
Class axlMesh defines a piecewise-linear 3D object.
Definition: axlMesh.h:41
void push_back_vertex(const double &x, const double &y, const double &z)
Add a new vertex to the mesh.
Definition: axlMesh.cpp:333