Developer documentation | Axl-2.5.1

axlSurfaceRevolutionConverter.cpp
Go to the documentation of this file.
1 //Author: Hung NGUYEN 9:17 AM 20/05/2014
2 
3 
4 
5 #include <axlCore/axlMesh.h>
6 #include "axlSurfaceRevolution.h"
8 
10 #include "axlCircleArc.h"
11 #include <dtkCoreSupport/dtkAbstractDataFactory.h>
12 
13 
14 class axlSurfaceRevolutionConverterPrivate
15 {
16 public:
18 };
19 
20 axlSurfaceRevolutionConverter::axlSurfaceRevolutionConverter(void) : axlAbstractDataConverter(), d(new axlSurfaceRevolutionConverterPrivate)
21 {
22 
23  d->data = NULL;
24 }
25 
27 {
28  delete d;
29 
30  d = NULL;
31 }
32 
34 {
35  return "Converter from axlSurfaceRevolution to axlMesh";
36 }
37 
39 {
40  return "axlSurfaceRevolutionConverter";
41 }
42 
44 {
45  return QStringList() << "axlSurfaceRevolutionConverter" << "axlSurfaceRevolution";
46 }
48 {
49  return "axlMesh";
50 }
51 
53 {
54  return dtkAbstractDataFactory::instance()->registerDataConverterType("axlSurfaceRevolutionConverter", QStringList(), "axlMesh", createaxlSurfaceRevolutionConverter);
55 }
56 
57 axlPoint *axlSurfaceRevolutionConverter::rotatePoint(double a, double b, double c, double x, double y,double z, double u, double v, double w, double alpha)
58 {
59  axlPoint *res = new axlPoint();
60  qreal a1 = (a*(qPow(v,2)+qPow(w,2))-u*(b*v+c*w-u*x-v*y-w*z))*(1-qCos(alpha))+x*qCos(alpha)+(-c*v+b*w-w*y+v*z)*qSin(alpha);
61  qreal a2 = (b*(qPow(u,2)+qPow(w,2))-v*(a*u+c*w-u*x-v*y-w*z))*(1-qCos(alpha))+y*qCos(alpha)+(c*u-a*w+w*x-u*z)*qSin(alpha);
62  qreal a3 = (c*(qPow(u,2)+qPow(v,2))-w*(a*u+b*v-u*x-v*y-w*z))*(1-qCos(alpha))+z*qCos(alpha)+(-b*u+a*v-v*x+u*y)*qSin(alpha);
63  res->setCoordinates(a1,a2,a3);
64  return res;
65 };
66 
67 axlPoint* axlSurfaceRevolutionConverter::RotatePoint(axlPoint a,axlPoint x,axlPoint u, double alpha)
68 {
69  return rotatePoint(a.x(),a.y(),a.z(),x.x(),x.y(),x.z(),u.x(),u.y(),u.z(),alpha);
70 };
71 
72 axlPoint* axlSurfaceRevolutionConverter::RotatePoint(axlLine *line,axlPoint *x, double alpha)
73 {
74  axlPoint dir = line->secondPoint()->operator-(line->firstPoint());
75  dir.normalize();//use better function
76  return RotatePoint(*(line->firstPoint()),*x,dir,alpha);
77 }
78 //computing the angle of vector vCompute if you choose the vRef is origin (where the angle = 0) and the result will be between [-PI, PI].
79 //Vector normal here is very important, because, the angle is computing by the counter-clockwise with the direction of vector go out of plane.
80 //For more details, see the atan2() of c++ references or google "c++ atan2".
81 double axlSurfaceRevolutionConverter::angle(axlPoint vCompute, axlPoint vRef, axlPoint normal)
82 {
83  axlPoint y = axlPoint::crossProduct(normal,vRef);
84  return std::atan2(axlPoint::dotProduct(vCompute,y),axlPoint::dotProduct(vCompute,vRef));
85 }
86 
87 //conputing the angle of arc with base on the function angle().
88 double axlSurfaceRevolutionConverter::angleOfArc(const axlCircleArc *arc)
89 {
90  if(std::abs(axlPoint::crossProduct(arc->point1()-arc->center(),arc->point2()-arc->center()).norm())<1e-5)
91  {
92  if(arc->isDirect())
93  return M_PI;
94  else
95  return -M_PI;
96  }
97 
98  double ang = angle(arc->point2()-arc->center(),arc->point1()-arc->center(),/*arc->normal()*/arc->calculateNormal());
99  //
100  //if(ang>0 && !arc->isDirect())
101  // ang = ang - 2*M_PI;
102  //else if(ang<0&&!arc->isDirect())
103  // //ang = ang + 2*M_PI;
104  if(ang<0)
105  return ang+ 2*M_PI;
106  /*if(axlPoint::dotProduct(axlPoint::crossProduct(arc->point1()-arc->center(),arc->point2()-arc->center()),arc->normal())<0&&arc->isDirect())
107  return ang + 2*M_PI;
108  if(axlPoint::dotProduct(axlPoint::crossProduct(arc->point1()-arc->center(),arc->point2()-arc->center()),arc->normal())>0&&!arc->isDirect())
109  return ang - 2*M_PI;*/
110  return ang;
111 }
112 axlPoint axlSurfaceRevolutionConverter::normalCCWArc(const axlCircleArc& arc)
113 {
114  if(std::abs(axlPoint::crossProduct(arc.point1()-arc.center(),arc.point2()-arc.center()).norm())<1e-5)
115  {
116  if(arc.isDirect())
117  return arc.normal();
118  else
119  return arc.normal()*(-1);
120  }
121  else
122  return arc.calculateNormal();
123 
124 }
125 QList<axlPoint *> axlSurfaceRevolutionConverter::Sampling(axlAbstractCurve *curve)
126 {
127  QList<axlPoint *> result;
128 
129  if(axlLine *line = dynamic_cast<axlLine *>(curve))
130  {
131  result.append(line->firstPoint());
132  result.append(line->secondPoint());
133  }
134  else if(axlCircleArc *ca = dynamic_cast<axlCircleArc *>(curve))
135  {
136  double step = angleOfArc(ca)/40;
137  /*if((axlPoint::dotProduct(ca->normal(),axlPoint::crossProduct(ca->point1()-ca->center(),ca->point2()-ca->center()))>0&&ca->isDirect())||(axlPoint::dotProduct(ca->normal(),axlPoint::crossProduct(ca->point1()-ca->center(),ca->point2()-ca->center()))<0&&!ca->isDirect()))
138  {
139  step = qAcos(axlPoint::dotProduct(ca->point1()-ca->center(),ca->point2()-ca->center())/(ca->point1()-ca->center()).norm()*(ca->point1()-ca->center()).norm())/40;
140  }
141  else
142  {
143  step = 2*M_PI - qAcos(axlPoint::dotProduct(ca->point1()-ca->center(),ca->point2()-ca->center())/(ca->point1()-ca->center()).norm()*(ca->point1()-ca->center()).norm())/40;
144  }*/
145  for(int i = 0; i<=40;i++)
146  {
147  axlPoint *inter = new axlPoint(ca->point1());
148  result.append(RotatePoint(new axlLine(ca->center(),ca->center()+normalCCWArc(*ca)),inter,i*step));
149  }
150  }
151  else if(axlAbstractCurveBSpline *curvepara = dynamic_cast<axlAbstractCurveBSpline *>(curve))
152  {
153  double step = (curvepara->endParam()-curvepara->startParam())/40;
154  for(int i = 0;i<41;i++)
155  {
156  result.append(new axlPoint(curvepara->eval(curvepara->startParam()+i*step)));
157  }
158 
159  }
160  return result;
161 }
163 {
164 
165  if(!d->data)
166  return NULL;
167 
168  axlMesh *output = new axlMesh();
169  int NoS = 40;
170  double step = (d->data->getEndAngle()-d->data->getStartAngle())/NoS;
171  QList<QList<axlPoint *> > samples;
172  for(int i = 0; i<d->data->countCurve(); i++)
173  {
174  QList<axlPoint *> temp = Sampling(d->data->getCurve(i));
175  samples.append(temp);
176  }
177  int lastID = 0;
178  for(int k = 0; k<samples.size(); k++)
179  {
180  for(int i = 0;i<samples.at(k).size();i++)
181  {
182  for(int j = 0;j<NoS+1;j++)
183  {
184  output->push_back_vertex(RotatePoint(d->data->getAxe(),samples.at(k).value(i),d->data->getStartAngle()+j*step));
185  }
186  }
187  int i1, i2;
188  for(int i = 0; i < samples.at(k).size()-1; i++)
189  {
190  for(int j= 0; j <NoS; j++)
191  {
192  i1 = lastID + i * (NoS+1) + j;
193  i2 = i1 + NoS+1;
194 
195  QVector<int> firstTriangle;
196  QVector<int> secondTriamgle;
197 
198  firstTriangle.push_back(i1);
199  firstTriangle.push_back(i1 + 1);
200  firstTriangle.push_back(i2);
201 
202  secondTriamgle.push_back(i2);
203  secondTriamgle.push_back(i1 + 1);
204  secondTriamgle.push_back(i2 + 1);
205 
206  output->push_back_face(firstTriangle);
207  output->push_back_face(secondTriamgle);
208 
209  }
210 
211  }
212 
213  axlMesh::Edge ed0,ed1,ed2,ed3;
214  for(int i = 0; i < NoS+1 ; i++)
215  {
216  ed0<<lastID + i;
217  }
218  output->push_back_edge(ed0);
219 
220  for(int j = 0; j < samples.at(k).size() ; j++)
221  {
222  ed1<<lastID + (NoS+j*(NoS+1));
223  }
224  output->push_back_edge(ed1);
225 
226 
227  for(int i = 0; i < NoS+1 ; i++)
228  {
229  ed2<<lastID + (samples.at(k).size()-2)*(NoS+1) + (NoS-i);
230  }
231  output->push_back_edge(ed2);
232 
233  for(int j = 0; j < samples.at(k).size() ; j++)
234  {
235  ed3<<lastID + (samples.at(k).size()-1-j)*(NoS+1);
236  }
237  output->push_back_edge(ed3);
238 
239  lastID+=samples.at(k).size()*(NoS+1);
240  }
241 
242  output->vertex_show() = true;
243  output->face_show() = true;
244  output->vertex_show() = true;
245  return output;
246 }
247 
248 void axlSurfaceRevolutionConverter::setData(dtkAbstractData *data)
249 {
250  if(axlSurfaceRevolution *Data = dynamic_cast<axlSurfaceRevolution *>(data))
251  d->data = Data;
252 }
253 
254 dtkAbstractDataConverter *createaxlSurfaceRevolutionConverter(void)
255 {
257 }
bool isDirect(void) const
Class axlPoint defines 3D points.
Definition: axlPoint.h:34
Class axlLine defines 3D lines.
Definition: axlLine.h:35
bool vertex_show(void) const
Definition: axlMesh.cpp:159
axlPoint point1(void) const
void push_back_edge(int, int)
Definition: axlMesh.cpp:669
axlPoint * secondPoint(void) const
Returns second point of the line.
Definition: axlLine.cpp:137
#define M_PI
QVector< int > Edge
An edge is represented by a sequence of vertices.
Definition: axlMesh.h:55
axlPoint center(void) const
dtkAbstractDataConverter * createaxlSurfaceRevolutionConverter(void)
axlPoint * firstPoint(void) const
Returns first point of the line.
Definition: axlLine.cpp:128
void normalize(void)
Definition: axlPoint.cpp:410
axlPoint point2(void) const
static double dotProduct(const axlPoint &lhs, const axlPoint &rhs)
Definition: axlPoint.cpp:508
bool face_show(void) const
Definition: axlMesh.cpp:200
double y
Definition: axlPoint.h:37
axlPoint calculateNormal(void) const
void push_back_face(const Face &face)
Definition: axlMesh.cpp:735
axlPoint normal(void) const
double z
Definition: axlPoint.h:38
static axlPoint crossProduct(const axlPoint &lhs, const axlPoint &rhs)
Returns the cross product between lhs (coords) and rhs (coords).
Definition: axlPoint.cpp:485
double x
Definition: axlPoint.h:37
void setCoordinates(double x, double y, double z)
Change coordinates of this point.
Definition: axlPoint.cpp:370
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