Developer documentation | Axl-2.5.1

axlShapeBSpline.cpp
Go to the documentation of this file.
1 #include "axlShapeBSpline.h"
2 
3 #include <axlCore/axlShape.h>
4 #include <axlCore/axlMesh.h>
5 
6 #include <axlCore/axlPoint.h>
7 
8 #include <dtkLog/dtkLog.h>
9 #include <dtkCoreSupport/dtkAbstractDataFactory.h>
10 
11 
12 class axlShapeBSplinePrivate
13 {
14 public :
15  QVector<axlShapeBSpline::ControlPoint *> points;
16  QVector<axlShapeBSpline::Edge *> edges;
17  QVector<axlShapeBSpline::Face *> faces;
18 
19  int sample;
20 
21  QMap<QPair<double, double>, double> scalar_values;
22  QHash<int, QList<int> > connect;
23 };
24 
25 axlShapeBSpline::axlShapeBSpline() : axlAbstractData(), d(new axlShapeBSplinePrivate)
26 {
27  d->sample = 40;
28 }
29 
31 {
32 }
33 
34 
35 // /**
36 // * @brief Emit a signal edgesSeleted
37 // * @param numEdge : the identifier of the Edge selected.
38 // */
39 // void axlShapeBSpline::emitEdgeSelected(int numEdge){
40 
41 // if(numEdge < 0 || numEdge >= d->edges.size()){
42 // emit edgeSelected(-1, 0,0);
43 // }else{
44 
45 // int previous = 0;
46 // for(int i = 0; i < numEdge;i++){
47 // previous = d->edges.at(i)->support->numSamples()-1 + previous;
48 // }
49 // int n = d->edges.at(numEdge)->support->numSamples();
50 // emit edgeSelected(numEdge, previous,n);
51 // }
52 // }
53 
54 
56 
60  return dtkAbstractDataFactory::instance()->registerDataType("axlShapeBSpline", createaxlShapeBSpline);
61 }
62 
63 
65 
68 QString axlShapeBSpline::identifier(void) const{
69  return "axlShapeBSpline";
70 }
71 
73 
76 QString axlShapeBSpline::description(void) const{
77  QString description;
78  description.append(identifier());
79  description.append( "has ");
80  description.append(QString::number(countControlPoints()));
81  description.append("control points;");
82  description.append(QString::number(countBoundaryEdges()));
83  description.append("boundary edges and ");
84  description.append(QString::number(d->faces.size()));
85  description.append("faces");
86 
87  return description;
88 }
89 
91 
95  if(d->faces.isEmpty())
96  return -1;
97  else
98  return d->faces.first()->support->order_u();
99 }
100 
102 
106  if(d->faces.isEmpty())
107  return -1;
108  else
109  return d->faces.first()->support->order_v();
110 }
111 
112 
117 void axlShapeBSpline::createSurfaceFromBSplineDataSet(QList<axlAbstractSurfaceBSpline *> dataSet){
118 
119  //We suppose all bspline surfaces of dataSet have same orders.
120  int order_u = dataSet.first()->order_u();
121  int order_v = dataSet.first()->order_v();
122  int nbEdges = 0;
123  int nbFaces = dataSet.size();
124 
125  QVector< QVector<int> >pe;
126  QVector< QVector<int> >pf;
127  QVector< QPair<int,int> > npf;
128 
129  QList<axlPoint > p;
130  for(int i = 0; i < dataSet.size(); i++){
131  QPair<int, int> pair = QPair<int,int>(dataSet.at(i)->countControlPoints_u(),dataSet.at(i)->countControlPoints_v() );
132  QVector<int> pf0;
133  for(int j = 1; j <= dataSet.at(i)->countControlPoints();j++){
134  const axlPoint& pointa = dataSet.at(i)->getCoef(j);
135  if(!isContained(p, pointa, pf0)){
136  p.append(pointa);
137  }
138  }
139  pf.append(pf0);
140  npf.append(pair);
141  }
142 
143  int nbpoints = p.size();
144  double *points = new double[3*nbpoints];
145 
146  for(int i = 0;i < p.size();i++){
147  points[3*i] = p.at(i).x();
148  points[3*i+1] = p.at(i).y();
149  points[3*i+2] = p.at(i).z();
150  }
151 
152  this->setSurface( order_u, order_v, nbpoints, nbEdges, nbFaces, points, pe, pf, npf );
153 }
154 
167 void axlShapeBSpline::setSurface(int order_u, int order_v,int nbpoints,int nbEdges, int nbFaces, double *points, QVector< QVector<int> > pe, QVector< QVector<int> >pf, QVector< QPair<int,int> > npf ){
168 
169  setControlPoints(nbpoints,points);
170 
171  for (int i = 0; i < nbEdges; i++) {
172  setEdge(i, pe.at(i),order_u);
173  }
174 
175  for(int j = 0; j < nbFaces; j++) {
176  setFace(j, pf.at(j), order_u, order_v, npf.at(j).first, npf.at(j).second);
177  }
178 }
179 
184 void axlShapeBSpline::setControlPoints(int nbpoints, double *points)
185 {
186  for(int i = 0; i < nbpoints;i++){
187  //d->points.append(new ControlPoint(i,points[3*i], points[3*i+1], points[3*i+2]));
188  d->points.append(new ControlPoint(i,points[3*i], points[3*i+1], 0));// same plane z = 0;
189  }
190 }
191 
200 void axlShapeBSpline::setFace(int i, QVector<int> p, int order_u, int order_v, int nu, int nv)
201 {
202  axlAbstractSurfaceBSpline *surf = dynamic_cast<axlAbstractSurfaceBSpline *>(dtkAbstractDataFactory::instance()->create("goSurfaceBSpline"));
203  double *points = fillCoordinates(p);
204  double *knots_u = knots(nu,order_u);
205  double *knots_v = knots(nv,order_v);
206  surf->setSurface(nu,nv, order_u, order_v,3,knots_u, knots_v, points, false);
207  surf->setNumSamples_u(d->sample);
208  surf->setNumSamples_v(d->sample);
209  d->faces.append(new Face(i,nu,nv,p,surf));
210  updateFaceEdges(i);
211 }
212 
218 void axlShapeBSpline::setEdge(int i,QVector<int> p, int order)
219 {
220  axlAbstractCurveBSpline *curv = dynamic_cast<axlAbstractCurveBSpline *>(dtkAbstractDataFactory::instance()->create("goCurveBSpline"));
221  double *points = fillCoordinates(p);
222  double *knot = knots(p.size(),order);
223  curv->setCurve(p.size(),order,3,knot, points, false);//rational=false, it is a bspline curve (non-rational one)
224  curv->setNumSamples(d->sample);
225  d->edges.append(new Edge(i,p,curv));
226  for(int pts =0; pts < p.size(); pts++ ){
227  d->points.at(p.at(pts))->addEdge(i);
228  }
229 }
230 
236 void axlShapeBSpline::setFace(int i, QVector<int> p, axlAbstractSurfaceBSpline *surf)
237 {
238  surf->setNumSamples_u(d->sample);
239  surf->setNumSamples_v(d->sample);
240  d->faces.append(new Face(i,surf->countControlPoints_u(), surf->countControlPoints_v(),p,surf));
241  updateFaceEdges(i);
242  for(int pts =0; pts < p.size(); pts++ ){
243  d->points.at(p.at(pts))->addFace(i);
244  }
245 }
246 
247 
253 void axlShapeBSpline::setEdge(int i, QVector<int> p, axlAbstractCurveBSpline *curv)
254 {
255  curv->setNumSamples(d->sample);
256  d->edges.append(new Edge(i,p,curv));
257  for(int pts =0; pts < p.size(); pts++ ){
258  d->points.at(p.at(pts))->addEdge(i);
259  }
260 }
261 
266 {
267  for(int j = 0; j < d->edges.at(i)->controlPointsIndices.size();j++){
268  int index = getPoint(d->edges.at(i)->controlPointsIndices.at(j))->edges.indexOf(i);
269  getPoint(d->edges.at(i)->controlPointsIndices.at(j))->edges.remove(index);
270  }
271 
272  delete d->edges.at(i);
273  //d->edges.at(i) = NULL;
274  d->edges.remove(i);
275 }
276 
277 
282 //coefficients relatifs aux points de controle.
284 {
285  QVector<double> coord = d->points.at(index-1)->coordinates;
286  return axlPoint(coord.first(), coord.at(1),coord.last());
287 }
288 
293 bool axlShapeBSpline::setCoef(int index, double *newCoordinate)
294 {
295  QVector<bool> interRes;
296 
297  d->points.at(index-1)->setCoord(newCoordinate);
298 
299  for(int i = 0; i < d->edges.size(); i++){
300  if(d->edges.at(i)->containsControlPoint(index-1)){
301  int ind = d->edges.at(i)->controlPointsIndices.indexOf(index-1);
302  interRes.append(d->edges.at(i)->support->setCoef(ind+1, newCoordinate));
303  }
304  }
305 
306  for(int i = 0; i < d->faces.size(); i++){
307  if(d->faces.at(i)->containsControlPoint(index-1)){
308  int ind = d->faces.at(i)->controlPointsIndices.indexOf(index-1);
309  interRes.append(d->faces.at(i)->support->setCoef(ind+1, newCoordinate));
310  }
311  }
312  return !interRes.contains(false);
313 }
314 
320 {
321  return d->points.size();
322 }
323 
324 //double axlShapeBSpline::startParam_u(void)
325 //{
326 // DTK_DEFAULT_IMPLEMENTATION;
327 
328 // return 0.;
329 //}
330 //double axlShapeBSpline::startParam_v(void)
331 //{
332 // DTK_DEFAULT_IMPLEMENTATION;
333 
334 // return 0.;
335 //}
336 
337 //double axlShapeBSpline::endParam_u(void)
338 //{
339 // DTK_DEFAULT_IMPLEMENTATION;
340 // return 1.;
341 //}
342 //double axlShapeBSpline::endParam_v(void)
343 //{
344 // DTK_DEFAULT_IMPLEMENTATION;
345 // return 1.;
346 //}
347 //int axlShapeBSpline::numSamples_u(void)
348 //{
349 // DTK_DEFAULT_IMPLEMENTATION;
350 
351 // return 0;
352 //}
353 //int axlShapeBSpline::numSamples_v(void)
354 //{
355 // DTK_DEFAULT_IMPLEMENTATION;
356 
357 // return 0;
358 //}
359 
360 void axlShapeBSpline::eval(axlPoint *point, double u, double v) {
361  DTK_DEFAULT_IMPLEMENTATION;
362  DTK_UNUSED(point);
363  DTK_UNUSED(u);
364  DTK_UNUSED(v);
365 }
366 
367 void axlShapeBSpline::normal(axlPoint *normal, double u, double v)
368 {
369  DTK_DEFAULT_IMPLEMENTATION;
370  DTK_UNUSED(normal);
371  DTK_UNUSED(u);
372  DTK_UNUSED(v);
373 }
374 double axlShapeBSpline::scalarValue(double u, double v)
375 {
376  return d->scalar_values.value(qMakePair<double, double>(u, v));
377 }
378 
379 void axlShapeBSpline::setScalarValue(double u, double v, double value)
380 {
381  d->scalar_values.insert(qMakePair<double, double>(u, v), value);
382 }
383 
385 {
386  DTK_DEFAULT_IMPLEMENTATION;
387 
388  return 0;
389 }
390 
392 {
393  DTK_DEFAULT_IMPLEMENTATION;
394  DTK_UNUSED(stripes);
395 }
396 
398 {
399  DTK_DEFAULT_IMPLEMENTATION;
400  return 0;
401 }
402 
404 {
405  DTK_DEFAULT_IMPLEMENTATION;
406  return 0;
407 }
408 
410 {
411  return d->connect.value(i);
412 }
413 
415 
419  return !d->connect.isEmpty();
420 }
421 
427  return d->faces.at(i)->support->startParam_u();
428 }
429 
435  return d->faces.at(i)->support->startParam_v();
436 }
437 
443  return d->faces.at(i)->support->endParam_u();
444 }
445 
451  return d->faces.at(i)->support->endParam_v();
452 }
453 
460 void axlShapeBSpline::eval(axlPoint *point, double u, double v,int i){
461  d->faces.at(i)->support->eval(point, u,v);
462  point->setCoordinates(point->x(), point->y(), point->z());
463 }
464 
466 
470  return (d->faces.size()>0);
471 }
472 
474 
478  return d->faces.size();
479 }
480 
482 
486  return d->edges.size();
487 }
488 
494  return d->edges.at(i);
495 }
496 
502  return d->faces.at(i);
503 }
504 
510  return d->points.at(i);
511 }
512 
518  return d->faces.at(i)->support->numSamples_u();
519 }
520 
521 
527  return d->faces.at(i)->support->numSamples_v();
528 }
529 
530 
534 void axlShapeBSpline::setNumSamples_u(int numSamples){
535  // axlAbstractSurfaceBSpline::setNumSamples_u(numSamples);
536 
537  for(int i = 0;i < d->edges.size();i++){
538  d->edges.at(i)->support->setNumSamples(numSamples);
539  }
540 
541  for(int i = 0;i < d->faces.size();i++){
542  d->faces.at(i)->support->setNumSamples_u(numSamples);
543  }
544 }
545 
549 void axlShapeBSpline::setNumSamples_v(int numSamples) {
550  for(int i = 0; i < d->faces.size(); i++){
551  d->faces.at(i)->support->setNumSamples_v(numSamples);
552  }
553 }
554 
561 void axlShapeBSpline::normal(axlPoint *currentNormal ,double paramCourant_u, double paramCourant_v,int indice){
562  d->faces.at(indice)->support->normal(currentNormal,paramCourant_u,paramCourant_v);
563 }
564 
565 
570 
571  if(!d->faces.at(numFace)->edgesIndices.isEmpty())
572  d->faces.at(numFace)->edgesIndices.clear();
573 
574  QVector<int>e;
575  QVector<int> p = d->faces.at(numFace)->controlPointsIndices;
576 
577  for(int ip =0; ip < p.size(); ip++){
578  if(d->points.at(p.at(ip))->edges.size() == 1 ){
579  if(!e.contains(d->points.at(p.at(ip))->edges.first())){
580  e.push_back(d->points.at(p.at(ip))->edges.first());
581  }
582  }
583  }
584  d->faces.at(numFace)->edgesIndices = e;
585 
586 }
587 
588 // PRIVATE
589 
594 double *axlShapeBSpline::fillCoordinates(QVector<int> p){
595  double *point = new double[3*p.size()];
596  int ind = 0;
597 
598  for(int i= 0; i < p.size();i++){
599  point[3*ind] = d->points.at(p.at(i))->coordinates.first();
600  point[3*ind+1] = d->points.at(p.at(i))->coordinates.at(1);
601  point[3*ind+2] = d->points.at(p.at(i))->coordinates.last();
602 
603  ind++;
604  }
605 
606  return point;
607 }
608 
609 
615 double *axlShapeBSpline::knots(int pointsCount, int order)
616 {
617  double *knots = new double[pointsCount + order];
618  int knot_number = 1 ;
619 
620 
621 
622  for(int i = 0 ; i < order ; i++ )
623  knots[i] = 0.0 ;
624 
625  for(int i = order ; i < pointsCount ; i++)
626  knots[i] = knot_number++ ;
627 
628  for(int i = pointsCount ; i < pointsCount + order ; i++)
629  knots[i] = knot_number ;
630 
631 
632 
633  // for(int i = 0 ; i < pointsCount + order ; i++)
634  // knots[i] = i ;
635 
636 
637  return knots;
638 }
639 
646 bool axlShapeBSpline::isContained(QList<axlPoint > list, axlPoint p, QVector<int>& pf){
647  bool res = false;
648 
649  for(int i = 0;i <list.size(); i++){
650  axlPoint listP = list.at(i);
651  if(listP.x() == p.x() && listP.y()==p.y() && listP.z()==p.z()){
652  pf.append(i);
653  res = true;
654  }
655  }
656 
657  if(!res){
658  int s = pf.size();
659  pf.append(s);
660  }
661 
662 
663  return res;
664 }
665 
666 
671  ControlPoint *control = new ControlPoint(d->points.size(),point->x(),point->y(),point->z());
672  d->points.append(control);
673 }
674 
675 
681 void axlShapeBSpline::insert_point(double x, double y, double z){
682  ControlPoint *control = new ControlPoint(d->points.size(),x,y,z);
683  d->points.append(control);
684 }
685 
686 
691  d->edges.append(edge);
692 }
693 
694 
699  d->faces.append(face);
700 }
701 
702 dtkAbstractData *createaxlShapeBSpline(void){
703  return new axlShapeBSpline;
704 }
705 
706 // /////////////////////////////////////////////////////////////////
707 // axlDataDynamic documentation
708 // /////////////////////////////////////////////////////////////////
709 
void createSurfaceFromBSplineDataSet(QList< axlAbstractSurfaceBSpline * > dataSet)
Create an axlShapeBSpline from a set of axlAbstractSurfaceBSpline.
Class axlPoint defines 3D points.
Definition: axlPoint.h:34
double scalarValue(double u, double v)
axlPoint getCoef(int index) const
Get a coefficient of the surface.
int order_u() const
Return the order of the surface for the u parameter.
Edge * getEdge(int i)
Return edge.
double endParam_u(int i)
Return the last u parameter value of a face.
QList< int > getControlPointConnection(int i)
int countFaces(void)
Return how many faces.
int countControlPoints_v(void) const
void insert_point(double x, double y, double z)
Add a point to the control point set of the surface.
int order_v() const
Return the order of the surface for the v parameter.
void setEdge(int i, QVector< int > p, int order)
Add or modify an edge to the Surface.
int countControlPoints_u(void) const
virtual void setNumSamples_v(int numSamples)
bool setCoef(int index, double *newCoordinate)
Modified a coefficient of the surface.
double startParam_u(int i)
Return the first u parameter value of a face.
int numSamples_u(int numCell)
Mesh subdision on the u-direction.
void setNumSamples_u(int numSamples)
Modify mesh subdision on the v-direction. Same for all faces.
Face * getFace(int i)
Return face.
double endParam_v(int i)
Return the last v parameter value of a face.
static bool registered(void)
Emit a signal edgesSeleted.
virtual void setSurface(int pointsCount_u, int pointsCount_v, int order_u, int order_v, int dimension, double *knots_u, double *knots_v, double *points, bool rational)
axlAbstractSurfaceBSpline::setSurface
void setStripes(int stripes)
dtkAbstractData * createaxlShapeBSpline(void)
void eval(axlPoint *point, double u, double v)
virtual void setNumSamples(int numSamples)
void removeEdge(int i)
Remove an edge.
virtual int countControlPoints_u(void) const
virtual int countControlPoints_v(void) const
void insert_edge(Edge *edge)
Add an edge to the surface.
virtual void setCurve(int pointsCount, int order, int dimension, double *knots, double *points, bool rational)
int countBoundaryEdges() const
Return how many edges.
ControlPoint * getPoint(int i)
Return control point.
double startParam_v(int i)
Return the first u parameter value of a face.
void setSurface(int order_u, int order_v, int nbpoints, int nbEdges, int nbFaces, double *points, QVector< QVector< int > > pe, QVector< QVector< int > >pf, QVector< QPair< int, int > >npf)
Create a surface.
bool hasFaces(void)
Return whether the surface have several faces.
double y
Definition: axlPoint.h:37
QString description(void) const
Return a description of the surface.
void setNumSamples_v(int numSamples)
Modify mesh subdision on the v-direction. Same for all faces.
int countControlPoints() const
Modified a coefficient of the surface.
double z
Definition: axlPoint.h:38
Class axlShapeBSpline defines a set of boundary curves (Edges) and bspline surface patches (Face)...
void setFace(int i, QVector< int > p, int order_u, int order_v, int nu, int nv)
Add or modify a face to the Surface.
void setControlPoints(int nbpoints, double *points)
Add control points to the Surface. All points should be on the plane z =0;.
int numSamples_v(int numCell)
Mesh subdision on the v-direction.
double x
Definition: axlPoint.h:37
bool connectionsAreDefined(void)
Return true if control points connections were defined by developers. False if there are default conn...
void setCoordinates(double x, double y, double z)
Change coordinates of this point.
Definition: axlPoint.cpp:370
void normal(axlPoint *normal, double u, double v)
void insert_face(Face *face)
Add a face to the surface.
virtual void setNumSamples_u(int numSamples)
void updateFaceEdges(int numFace)
Update indices list of the face edges.
Class axlAbstractData defines an API for all type of axel data.
void setScalarValue(double u, double v, double value)
QString identifier(void) const
Return the "axlShapeBSpline" identifier.Useful for data factory.