8 #include <dtkLog/dtkLog.h>
9 #include <dtkCoreSupport/dtkAbstractDataFactory.h>
12 class axlShapeBSplinePrivate
15 QVector<axlShapeBSpline::ControlPoint *> points;
16 QVector<axlShapeBSpline::Edge *> edges;
17 QVector<axlShapeBSpline::Face *> faces;
21 QMap<QPair<double, double>,
double> scalar_values;
22 QHash<int, QList<int> > connect;
60 return dtkAbstractDataFactory::instance()->registerDataType(
"axlShapeBSpline",
createaxlShapeBSpline);
69 return "axlShapeBSpline";
79 description.append(
"has ");
81 description.append(
"control points;");
83 description.append(
"boundary edges and ");
84 description.append(QString::number(d->faces.size()));
85 description.append(
"faces");
95 if(d->faces.isEmpty())
98 return d->faces.first()->support->order_u();
106 if(d->faces.isEmpty())
109 return d->faces.first()->support->order_v();
120 int order_u = dataSet.first()->order_u();
121 int order_v = dataSet.first()->order_v();
123 int nbFaces = dataSet.size();
125 QVector< QVector<int> >pe;
126 QVector< QVector<int> >pf;
127 QVector< QPair<int,int> > npf;
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() );
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)){
143 int nbpoints = p.
size();
144 double *points =
new double[3*nbpoints];
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();
152 this->
setSurface( order_u, order_v, nbpoints, nbEdges, nbFaces, points, pe, pf, npf );
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 ){
171 for (
int i = 0; i < nbEdges; i++) {
175 for(
int j = 0; j < nbFaces; j++) {
186 for(
int i = 0; i < nbpoints;i++){
188 d->points.append(
new ControlPoint(i,points[3*i], points[3*i+1], 0));
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);
209 d->faces.append(
new Face(i,nu,nv,p,surf));
221 double *points = fillCoordinates(p);
222 double *knot = knots(p.size(),order);
223 curv->
setCurve(p.size(),order,3,knot, points,
false);
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);
242 for(
int pts =0; pts < p.size(); pts++ ){
243 d->points.at(p.at(pts))->addFace(i);
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);
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);
272 delete d->edges.at(i);
285 QVector<double> coord = d->points.at(index-1)->coordinates;
286 return axlPoint(coord.first(), coord.at(1),coord.last());
295 QVector<bool> interRes;
297 d->points.at(index-1)->setCoord(newCoordinate);
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));
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));
312 return !interRes.contains(
false);
321 return d->points.size();
361 DTK_DEFAULT_IMPLEMENTATION;
369 DTK_DEFAULT_IMPLEMENTATION;
376 return d->scalar_values.value(qMakePair<double, double>(u, v));
381 d->scalar_values.insert(qMakePair<double, double>(u, v), value);
386 DTK_DEFAULT_IMPLEMENTATION;
393 DTK_DEFAULT_IMPLEMENTATION;
399 DTK_DEFAULT_IMPLEMENTATION;
405 DTK_DEFAULT_IMPLEMENTATION;
411 return d->connect.value(i);
419 return !d->connect.isEmpty();
427 return d->faces.at(i)->support->startParam_u();
435 return d->faces.at(i)->support->startParam_v();
443 return d->faces.at(i)->support->endParam_u();
451 return d->faces.at(i)->support->endParam_v();
461 d->faces.at(i)->support->eval(point, u,v);
470 return (d->faces.size()>0);
478 return d->faces.size();
486 return d->edges.size();
494 return d->edges.at(i);
502 return d->faces.at(i);
510 return d->points.at(i);
518 return d->faces.at(i)->support->numSamples_u();
527 return d->faces.at(i)->support->numSamples_v();
537 for(
int i = 0;i < d->edges.size();i++){
538 d->edges.at(i)->support->setNumSamples(numSamples);
541 for(
int i = 0;i < d->faces.size();i++){
542 d->faces.at(i)->support->setNumSamples_u(numSamples);
550 for(
int i = 0; i < d->faces.size(); i++){
551 d->faces.at(i)->support->setNumSamples_v(numSamples);
562 d->faces.at(indice)->support->normal(currentNormal,paramCourant_u,paramCourant_v);
571 if(!d->faces.at(numFace)->edgesIndices.isEmpty())
572 d->faces.at(numFace)->edgesIndices.clear();
575 QVector<int> p = d->faces.at(numFace)->controlPointsIndices;
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());
584 d->faces.at(numFace)->edgesIndices = e;
594 double *axlShapeBSpline::fillCoordinates(QVector<int> p){
595 double *point =
new double[3*p.size()];
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();
615 double *axlShapeBSpline::knots(
int pointsCount,
int order)
617 double *knots =
new double[pointsCount + order];
618 int knot_number = 1 ;
622 for(
int i = 0 ; i < order ; i++ )
625 for(
int i = order ; i < pointsCount ; i++)
626 knots[i] = knot_number++ ;
628 for(
int i = pointsCount ; i < pointsCount + order ; i++)
629 knots[i] = knot_number ;
646 bool axlShapeBSpline::isContained(QList<axlPoint > list,
axlPoint p, QVector<int>& pf){
649 for(
int i = 0;i <list.size(); i++){
651 if(listP.
x() == p.
x() && listP.
y()==p.
y() && listP.
z()==p.
z()){
672 d->points.append(control);
683 d->points.append(control);
691 d->edges.append(edge);
699 d->faces.append(face);
void createSurfaceFromBSplineDataSet(QList< axlAbstractSurfaceBSpline * > dataSet)
Create an axlShapeBSpline from a set of axlAbstractSurfaceBSpline.
Class axlPoint defines 3D points.
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.
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.
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.
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.
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.