Developer documentation | Axl-2.5.1

axlCircleArcConverter.cpp
Go to the documentation of this file.
1 /* axlCircleArcConverter.cpp ---
2  *
3  * Author: Valentin Michelet
4  * Copyright (C) 2008-2011 - Valentin Michelet, Inria.
5  * Created: Tue Apr 30 11:03:18 2012 (+0100)
6  * Version: $Id$
7  * Update #: 50
8  */
9 
10 /* Commentary:
11  *
12  */
13 
14 /* Change log:
15  *
16  */
17 
18 #include "axlMesh.h"
19 #include "axlCircleArc.h"
20 #include "axlCircleArcConverter.h"
21 
22 #include <dtkCoreSupport/dtkAbstractDataFactory.h>
23 
24 #include "axlPoint.h"
25 
26 #include <cmath>
27 
28 class axlCircleArcConverterPrivate {
29 public:
30  axlCircleArc *data;
31  axlMesh* output;
32  int startIndex;
33  int endIndex;
34  double precision;
35  double angularResolution;
36 };
37 
38 axlCircleArcConverter::axlCircleArcConverter(void) : axlAbstractDataConverter(), d(new axlCircleArcConverterPrivate) {
39  d->data = NULL;
40  d->output = NULL;
41  d->startIndex = -1;
42  d->endIndex = -1;
43  d->precision = 0.1;
44  d->angularResolution = 0.02;
45 }
46 
48  delete d;
49  d = NULL;
50 }
51 
53  return "Converter from axlCircleArcConverter to axlMesh";
54 }
55 
57  return "axlCircleArcConverter";
58 }
59 
60 QStringList axlCircleArcConverter::fromTypes(void) const {
61  return QStringList() << "axlCircleArcConverter" << "axlCircleArc";
62 }
63 
64 QString axlCircleArcConverter::toType (void) const {
65  return "axlMesh";
66 }
67 
69  return dtkAbstractDataFactory::instance()->registerDataConverterType("axlCircleArcConverter", QStringList(), "axlMesh", createaxlCircleArcConverter);
70 }
71 
73  if(!d->data)
74  return NULL;
75 
76  // If output is NULL, create a new one
77  if (!d->output)
78  d->output = new axlMesh;
79 
80  // Normal
81  axlPoint n = d->data->normal();
82  n.normalize();
83 
84  // Center
85  axlPoint c = d->data->center();
86  // First point
87  axlPoint p1 = d->data->point1();
88  // Second point
89  axlPoint p2 = d->data->point2();
90  // Angle (c-p1 ; c-p2)
91  axlPoint cp1 = p1-c;
92  axlPoint cp2 = p2-c;
93  // Second axis in repere (c; p1, pp2, normal)
94  axlPoint cpp2 = axlPoint::crossProduct(n, cp1);
95 
96  // Compute angle between cp1 and cp2
97  double angle = std::atan2(axlPoint::dotProduct(cp2/cp2.norm(), cpp2/cpp2.norm()), (axlPoint::dotProduct(cp1/cp1.norm(), cp2/cp2.norm())));
98  if (angle < 0.)
99  angle += 2*M_PI;
100 
101  // Number of edges within mesh, according to radius, angle and precision
102  int nbEdges = std::ceil(angle/d->angularResolution);
103 
104  // Create new edge to record vertices list
105  int arcIndex = d->output->push_back_new_edge();
106 
107  // If start and end points don't already exist
108  if (d->startIndex == -1 && d->endIndex == -1) {
109  // Add vertices to mesh
110  for (int k = 0; k <= nbEdges; k++) {
111  // Current angle
112  double theta = k*angle / nbEdges;
113  // Current point according to angle
114  axlPoint currPoint = c + cp1*std::cos(theta) + cpp2*std::sin(theta);
115  // Add current point to mesh
116  d->output->push_back_vertex(currPoint);
117  }
118 
119  // Get number of points within mesh
120  int nbPointsInMesh = d->output->vertex_count();
121 
122  // Add edge between first and second points of circle arc
123  d->output->edgePushBack(arcIndex, nbPointsInMesh-nbEdges-1);
124 
125  // Add other edges to mesh
126  for (int k = 0; k < nbPointsInMesh-1; k++) {
127  d->output->edgePushBack(arcIndex, k+1);
128  }
129 
130  // Add edge between last last and last points of circle arc
131  d->output->edgePushBack(arcIndex, nbPointsInMesh-2);
132  // If start and end points already exist
133  } else if (d->startIndex != -1 && d->endIndex != -1) {
134  // Add edge between first and second points of circle arc
135  d->output->edgePushBack(arcIndex, d->startIndex);
136 
137  // Add vertices to mesh
138  for (int k = 1; k <= nbEdges-1; k++) {
139  // Current angle
140  double theta = k*angle / nbEdges;
141  // Current point according to angle
142  axlPoint currPoint = c + cp1*std::cos(theta) + cpp2*std::sin(theta);
143  // Add current edge
144  d->output->edgePushBack(arcIndex, d->output->vertex_count());
145  // Add current point to mesh
146  d->output->push_back_vertex(currPoint);
147  }
148 
149  // Add edge between last last and last points of circle arc
150  d->output->edgePushBack(arcIndex, d->endIndex);
151  } else {
152  dtkError() << "Error within axlCircleArcConverter::toMesh: one point already exists and not the other one.";
153  }
154 
155  // Set mesh parameters
156  d->output->vertex_show() = false;
157  d->output->normal_used() = false;
158  d->output->color_used() = true;
159  d->output->edge_show() = true;
160  d->output->face_show() = false;
161  d->output->isPlanar() = true;
162 
163  d->output->setColor(d->data->color());
164  d->output->setOpacity(d->data->opacity());
165  d->output->setShader(d->data->shader());
166 
167  return d->output;
168 }
169 
170 void axlCircleArcConverter::setData(dtkAbstractData* data) {
171  if(axlCircleArc* circleArc = dynamic_cast<axlCircleArc*>(data))
172  d->data = circleArc;
173 }
174 
175 void axlCircleArcConverter::setParams(int channel, int index) {
176  if (channel == 0)
177  d->startIndex = index;
178  else if (channel == 1)
179  d->endIndex = index;
180  else
181  dtkWarn() << "axlCircleArcConverter::setParams usage: channel must be 0 or 1.";
182 }
183 
185  d->output = static_cast<axlMesh*>(output);
186 }
187 
189  d->precision = eps;
190 }
191 
192 dtkAbstractDataConverter* createaxlCircleArcConverter(void) {
193  return new axlCircleArcConverter;
194 }
Class axlPoint defines 3D points.
Definition: axlPoint.h:34
QString identifier(void) const
virtual void setPrecision(double eps)
#define M_PI
dtkAbstractDataConverter * createaxlCircleArcConverter(void)
QString description(void) const
void setData(dtkAbstractData *data)
void normalize(void)
Definition: axlPoint.cpp:410
double norm(void) const
Definition: axlPoint.cpp:450
virtual void setOutput(axlAbstractData *output)
QStringList fromTypes(void) const
static double dotProduct(const axlPoint &lhs, const axlPoint &rhs)
Definition: axlPoint.cpp:508
static axlPoint crossProduct(const axlPoint &lhs, const axlPoint &rhs)
Returns the cross product between lhs (coords) and rhs (coords).
Definition: axlPoint.cpp:485
virtual void setParams(int channel, int index)
QString toType(void) const
Class axlAbstractData defines an API for all type of axel data.
Class axlMesh defines a piecewise-linear 3D object.
Definition: axlMesh.h:41
double angle(axlPoint vCompute, axlPoint vRef, axlPoint normal)