1 |
|
5 |
//---------------------------------------------------------------------------
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
//---------------------------------------------------------------------------
|
5 |
|
|
// include MAGIC Headers
|
6 |
|
|
#include "gestionversion.h"
|
7 |
|
|
#include "mg_geometrie.h"
|
8 |
|
|
#include "mg_gestionnaire.h"
|
9 |
|
|
#include "mg_arete.h"
|
10 |
|
|
#include "lc_point.h"
|
11 |
|
|
#include "tpl_fonction.h"
|
12 |
|
|
#include "ot_algorithme_geometrique.h"
|
13 |
|
|
|
14 |
|
|
//---------------------------------------------------------------------------
|
15 |
|
|
// include STL headers
|
16 |
|
|
//---------------------------------------------------------------------------
|
17 |
|
|
#include <map>
|
18 |
|
|
#include <ostream>
|
19 |
|
|
#include <string>
|
20 |
|
|
#include <vector>
|
21 |
|
|
#include <sstream>
|
22 |
|
|
//---------------------------------------------------------------------------
|
23 |
|
|
|
24 |
|
|
|
25 |
|
|
#pragma hdrstop
|
26 |
|
|
|
27 |
|
|
#include "CAD4FE_PolyCurve.h"
|
28 |
|
|
|
29 |
|
|
//---------------------------------------------------------------------------
|
30 |
|
|
|
31 |
|
|
#pragma package(smart_init)
|
32 |
|
|
|
33 |
|
|
#include <math.h>
|
34 |
|
|
|
35 |
|
|
#ifdef __BORLANDC__
|
36 |
|
|
#pragma warn -8012
|
37 |
|
|
#pragma warn -8037
|
38 |
|
|
#endif
|
39 |
|
|
|
40 |
|
|
using namespace CAD4FE;
|
41 |
|
|
|
42 |
|
|
PolyCurve::PolyCurve()
|
43 |
|
|
{
|
44 |
|
|
|
45 |
|
|
}
|
46 |
|
|
|
47 |
|
|
PolyCurve::PolyCurve(MG_ARETE * __edge)
|
48 |
|
|
{
|
49 |
|
|
t_min = (0);
|
50 |
|
|
t_max = (-1);
|
51 |
|
|
InsertCurve( __edge );
|
52 |
|
|
}
|
53 |
|
|
|
54 |
|
|
double
|
55 |
|
|
PolyCurve::GetLength(MG_ARETE * __edge)
|
56 |
|
|
{
|
57 |
|
|
return __edge->get_longueur(__edge->get_tmin(), __edge->get_tmax());
|
58 |
|
|
}
|
59 |
|
|
|
60 |
|
|
double
|
61 |
|
|
PolyCurve::GetLength(unsigned __index)
|
62 |
|
|
{
|
63 |
|
|
return lst_length[__index];
|
64 |
|
|
}
|
65 |
|
|
|
66 |
|
|
double equation_longueur(MG_ARETE & __edge,double t)
|
67 |
|
|
{
|
68 |
|
|
PolyCurve::VerifyRefEdgeT(&__edge, t);
|
69 |
|
|
double dxyz[3];
|
70 |
|
|
__edge.deriver(t,dxyz);
|
71 |
|
|
return sqrt(dxyz[0]*dxyz[0]+dxyz[1]*dxyz[1]+dxyz[2]*dxyz[2]);
|
72 |
|
|
}
|
73 |
|
|
|
74 |
|
|
|
75 |
|
|
MG_ARETE * PolyCurve::GetRefEdge(unsigned int __index)
|
76 |
|
|
{
|
77 |
|
|
return lst_ref_edges[__index];
|
78 |
|
|
}
|
79 |
|
|
|
80 |
|
|
MG_SOMMET * PolyCurve::GetRefVertex(unsigned int __index)
|
81 |
|
|
{
|
82 |
|
|
return lst_vertices[__index];
|
83 |
|
|
}
|
84 |
|
|
|
85 |
|
|
unsigned PolyCurve::GetRefEdgeCount()
|
86 |
|
|
{
|
87 |
|
|
return lst_ref_edges.size();
|
88 |
|
|
}
|
89 |
|
|
|
90 |
|
|
unsigned PolyCurve::GetRefVertexCount()
|
91 |
|
|
{
|
92 |
|
|
return lst_vertices.size();
|
93 |
|
|
}
|
94 |
|
|
|
95 |
|
|
|
96 |
|
|
bool PolyCurve::ContainsRefEdge(MG_ARETE * __refEdge)
|
97 |
|
|
{
|
98 |
|
|
return ( std::find(lst_ref_edges.begin(),lst_ref_edges.end(),__refEdge) != lst_ref_edges.end());
|
99 |
|
|
}
|
100 |
|
|
|
101 |
|
|
void
|
102 |
|
|
PolyCurve::VerifyRefEdgeT(MG_ARETE * __edge, double & __t)
|
103 |
|
|
{
|
104 |
|
|
if ( __edge->get_courbe()->est_periodique() )
|
105 |
|
|
{
|
106 |
|
|
if (__t> __edge->get_tmax() )
|
107 |
|
|
__t -= __edge->get_courbe()->get_periode();
|
108 |
|
|
if (__t < __edge->get_tmin() )
|
109 |
|
|
__t += __edge->get_courbe()->get_periode();
|
110 |
|
|
}
|
111 |
|
|
else
|
112 |
|
|
{
|
113 |
|
|
if (__t > __edge->get_tmax() )
|
114 |
|
|
__t = __edge->get_tmax();
|
115 |
|
|
if (__t < __edge->get_tmin() )
|
116 |
|
|
__t = __edge->get_tmin();
|
117 |
|
|
}
|
118 |
|
|
}
|
119 |
|
|
|
120 |
|
|
void
|
121 |
|
|
PolyCurve::VerifyS(double & __s)
|
122 |
|
|
{
|
123 |
|
|
if ( est_periodique() )
|
124 |
|
|
{
|
125 |
|
|
if (__s > get_tmax() )
|
126 |
|
|
__s -= get_periode();
|
127 |
|
|
// if (__s < get_tmin() )
|
128 |
|
|
// __s += get_periode();
|
129 |
|
|
}
|
130 |
|
|
else
|
131 |
|
|
{
|
132 |
|
|
if (__s > get_tmax() )
|
133 |
|
|
__s = get_tmax();
|
134 |
|
|
// if (__s < get_tmin() )
|
135 |
|
|
// __s = get_tmin();
|
136 |
|
|
}
|
137 |
|
|
}
|
138 |
|
|
|
139 |
|
|
void
|
140 |
|
|
PolyCurve::RefEdge_GetT(unsigned __iEdge,
|
141 |
|
|
double __s,
|
142 |
|
|
double *__t, double *__dt, bool __curvilinearLength
|
143 |
|
|
)
|
144 |
|
|
{
|
145 |
|
|
double t[2];
|
146 |
|
|
MG_SOMMET * vertex = lst_vertices[ __iEdge ];
|
147 |
|
|
MG_ARETE * edge = lst_ref_edges[ __iEdge ];
|
148 |
|
|
|
149 |
|
|
// If the curve 1st covertex == last covertex
|
150 |
|
|
if (fabs(edge->get_cosommet1()->get_t() - edge->get_cosommet2()->get_t()) < 1E-6*(edge->get_tmax()-edge->get_tmin()))
|
151 |
|
|
{
|
152 |
|
|
t[0] = edge->get_tmin();
|
153 |
|
|
t[1] = edge->get_tmax();
|
154 |
|
|
}
|
155 |
|
|
else
|
156 |
|
|
{
|
157 |
|
|
if ( edge->get_cosommet1()->get_sommet() == vertex )
|
158 |
|
|
{
|
159 |
|
|
t [0] = edge->get_cosommet1()->get_t();
|
160 |
|
|
t [1] = edge->get_cosommet2()->get_t();
|
161 |
|
|
}
|
162 |
|
|
else if ( edge->get_cosommet2()->get_sommet() == vertex )
|
163 |
|
|
{
|
164 |
|
|
t [0] = edge->get_cosommet2()->get_t();
|
165 |
|
|
t [1] = edge->get_cosommet1()->get_t();
|
166 |
|
|
}
|
167 |
|
|
}
|
168 |
|
|
|
169 |
|
|
|
170 |
|
|
|
171 |
|
|
|
172 |
|
|
for (int i=0; i<2; i++)
|
173 |
|
|
{
|
174 |
|
|
VerifyRefEdgeT (edge, t[i]);
|
175 |
|
|
}
|
176 |
|
|
|
177 |
|
|
if ( __curvilinearLength == false || (__s)/GetLength( __iEdge ) < 1E-100 || fabs((__s)/GetLength( __iEdge )-1) < 1E-100 )
|
178 |
|
|
{
|
179 |
|
|
*__dt = (t [1] - t [0] ) / GetLength( __iEdge );
|
180 |
|
|
*__t = t [0] + __s * (*__dt);
|
181 |
|
|
}
|
182 |
|
|
else
|
183 |
|
|
{
|
184 |
|
|
TPL_FONCTION1<double,MG_ARETE,double> longueur_bsp(*edge, equation_longueur);
|
185 |
|
|
double s = (t[1] - t[0] < 0) ? -__s : __s;
|
186 |
|
|
longueur_bsp.integrer_jusqua_gauss_2(t[0], (t[1] - t[0] )/40, s, __t);
|
187 |
|
|
*__dt = (*__t - t[0]) / s;
|
188 |
|
|
}
|
189 |
|
|
}
|
190 |
|
|
|
191 |
|
|
void
|
192 |
|
|
PolyCurve::RefEdge_GetS(unsigned __iEdge,
|
193 |
|
|
double __t,
|
194 |
|
|
double *__s, bool __curvilinearLength
|
195 |
|
|
)
|
196 |
|
|
{
|
197 |
|
|
double t1;
|
198 |
|
|
MG_SOMMET * vertex = lst_vertices[ __iEdge ];
|
199 |
|
|
MG_ARETE * edge = lst_ref_edges[ __iEdge ];
|
200 |
|
|
|
201 |
|
|
if ( edge->get_cosommet1()->get_sommet() == vertex )
|
202 |
|
|
{
|
203 |
|
|
t1 = edge->get_cosommet1()->get_t();
|
204 |
|
|
}
|
205 |
|
|
else if ( edge->get_cosommet2()->get_sommet() == vertex )
|
206 |
|
|
{
|
207 |
|
|
t1 = edge->get_cosommet2()->get_t();
|
208 |
|
|
}
|
209 |
|
|
|
210 |
|
|
|
211 |
|
|
if ( __curvilinearLength == false)
|
212 |
|
|
*__s = lst_length[__iEdge] * fabs(t1 - __t)/(edge->get_tmax()-edge->get_tmin());
|
213 |
|
|
else
|
214 |
|
|
*__s = edge->get_longueur(t1, __t);
|
215 |
|
|
}
|
216 |
|
|
|
217 |
|
|
void
|
218 |
|
|
PolyCurve::InsertCurve(MG_ARETE *__edge)
|
219 |
|
|
{
|
220 |
|
|
if (lst_ref_edges.size() == 0)
|
221 |
|
|
{
|
222 |
|
|
lst_ref_edges.push_back ( __edge );
|
223 |
|
|
lst_length.push_back ( GetLength(__edge) );
|
224 |
|
|
lst_vertices.push_back ( __edge->get_cosommet1()->get_sommet());
|
225 |
|
|
lst_vertices.push_back ( __edge->get_cosommet2()->get_sommet());
|
226 |
|
|
t_min = 0;
|
227 |
|
|
t_max = lst_length[0];
|
228 |
|
|
return;
|
229 |
|
|
}
|
230 |
|
|
|
231 |
|
|
// Get the two vertices of this edge
|
232 |
|
|
MG_SOMMET * V[2];
|
233 |
|
|
int iV[2], // index of V[i] in lst_vertices[] ie. V [ i ] == lst_vertices[ iV[ i ] ]
|
234 |
|
|
iiVc=-1, // index < 2 of the common vertex in V[0,1] ie. if (iVc != -1) V [ iiVc ] == lst_vertices[ iV[ iiVc ] ]
|
235 |
|
|
iiVo=-1; // index < 2 of the other vertex in V[0,1] ie. if (iVo != -1) V [ iiVo ] == lst_vertices[ iV[ iiVo ] ]
|
236 |
|
|
V[0] = __edge->get_cosommet1()->get_sommet();
|
237 |
|
|
V[1] = __edge->get_cosommet2()->get_sommet();
|
238 |
|
|
|
239 |
|
|
// Verify wether the vertices are already referenced in
|
240 |
|
|
// the polycurve
|
241 |
|
|
std::vector<MG_SOMMET*>::iterator itV[2];
|
242 |
|
|
for (int i=0; i<2; i++)
|
243 |
|
|
{
|
244 |
|
|
itV[i] = std::find (lst_vertices.begin(), lst_vertices.end(), V[i]);
|
245 |
|
|
if (itV[i] != lst_vertices.end())
|
246 |
|
|
{ // V[i] is already in a curve of the polycurve
|
247 |
|
|
iV[i] = std::distance(lst_vertices.begin(), itV[i]);
|
248 |
|
|
if (iiVc == -1)
|
249 |
|
|
iiVc = i;
|
250 |
|
|
else
|
251 |
|
|
iiVo = i;
|
252 |
|
|
|
253 |
|
|
if ( iV[i] != 0 && iV[i]+1 != (int)lst_vertices.size() )
|
254 |
|
|
{
|
255 |
|
|
printf (" Error in PolyCurve::InsertCurve : can't insert a MG_ARETE (extremities = %d, %d) not adjacent to the extremities of this PolyCurve (extremities = %d, %d)\n", __edge->get_cosommet1()->get_sommet()->get_id(), __edge->get_cosommet2()->get_sommet()->get_id(), get_sommet1()->get_id(), get_sommet2()->get_id());
|
256 |
|
|
return;
|
257 |
|
|
}
|
258 |
|
|
}
|
259 |
|
|
else // vertex V[i] not found
|
260 |
|
|
{
|
261 |
|
|
iV[i] = -1;
|
262 |
|
|
iiVo = i;
|
263 |
|
|
}
|
264 |
|
|
}
|
265 |
|
|
|
266 |
|
|
|
267 |
|
|
if (iiVc == -1)
|
268 |
|
|
{
|
269 |
|
|
printf (" Error in PolyCurve::InsertCurve : the curve requested to append is not connected to the existing polycurve\n");
|
270 |
|
|
return;
|
271 |
|
|
}
|
272 |
|
|
|
273 |
|
|
if ( iV [iiVc] == 0 ) // the inserted curve is adjacent to the first vertex of the polycurve
|
274 |
|
|
{
|
275 |
|
|
lst_vertices.insert ( lst_vertices.begin(), V [ iiVo ] );
|
276 |
|
|
lst_ref_edges.insert ( lst_ref_edges.begin(), __edge );
|
277 |
|
|
lst_length.insert ( lst_length.begin(), GetLength(__edge) );
|
278 |
|
|
}
|
279 |
|
|
else if ( iV [iiVc]+1 == lst_vertices.size() ) // the inserted curve is adjacent to the last vertex of the polycurve
|
280 |
|
|
{
|
281 |
|
|
lst_vertices.push_back ( V [ iiVo ] );
|
282 |
|
|
lst_ref_edges.push_back ( __edge );
|
283 |
|
|
lst_length.push_back ( GetLength(__edge) );
|
284 |
|
|
}
|
285 |
|
|
else
|
286 |
|
|
{
|
287 |
|
|
printf("PolyCurve::InsertCurve Error : the edge %d is neither adjacent to end vertex nor to start vertex of polycurve %d\n", __edge->get_id(), get_id());
|
288 |
|
|
printf("Polycurve Start vertex = %d, End vertex = %d\n", get_sommet1()->get_id(),get_sommet2()->get_id());
|
289 |
|
|
printf("Edge Start vertex = %d, End vertex = %d\n", V[0]->get_id(), V[1]->get_id());
|
290 |
|
|
return;
|
291 |
|
|
}
|
292 |
|
|
|
293 |
|
|
// update t_max
|
294 |
|
|
t_max = 0;
|
295 |
|
|
for (std::vector<double>::const_iterator it_length = lst_length.begin();
|
296 |
|
|
it_length != lst_length.end();
|
297 |
|
|
it_length++)
|
298 |
|
|
t_max += (*it_length);
|
299 |
|
|
|
300 |
|
|
}
|
301 |
|
|
|
302 |
|
|
void
|
303 |
|
|
PolyCurve::Parameter_SToRefEdgeT (double __s, unsigned * __iEdge, double *__t, double *__dt, bool __curvilinearLength)
|
304 |
|
|
{
|
305 |
|
|
double s;
|
306 |
|
|
unsigned i;
|
307 |
|
|
|
308 |
|
|
i=0;
|
309 |
|
|
s=0;
|
310 |
|
|
while (s + GetLength(i) < __s && i+1 < lst_ref_edges.size() )
|
311 |
|
|
{
|
312 |
|
|
s += GetLength(i);
|
313 |
|
|
i++;
|
314 |
|
|
}
|
315 |
|
|
|
316 |
|
|
RefEdge_GetT(i, __s - s, __t, __dt, __curvilinearLength);
|
317 |
|
|
*__iEdge = i;
|
318 |
|
|
}
|
319 |
|
|
|
320 |
|
|
void
|
321 |
|
|
PolyCurve::Parameter_SToRefEdgeT (double __s, MG_ARETE ** __edge, double *__t, double *__dt, bool __curvilinearLength)
|
322 |
|
|
{
|
323 |
|
|
unsigned iEdge;
|
324 |
|
|
Parameter_SToRefEdgeT(__s, &iEdge, __t, __dt, __curvilinearLength);
|
325 |
|
|
*__edge = GetRefEdge(iEdge);
|
326 |
|
|
}
|
327 |
|
|
|
328 |
|
|
void
|
329 |
|
|
PolyCurve::Parameter_RefEdgeTToS (double __t, MG_ARETE * __edge, double *__s, bool __curvilinearLength)
|
330 |
|
|
{
|
331 |
|
|
double s, ds;
|
332 |
|
|
unsigned i;
|
333 |
|
|
|
334 |
|
|
i = std::distance ( lst_ref_edges.begin(), std::find ( lst_ref_edges.begin(), lst_ref_edges.end(), __edge) );
|
335 |
|
|
|
336 |
|
|
s=0;
|
337 |
|
|
for ( unsigned k = 0; k < i; k++)
|
338 |
|
|
{
|
339 |
|
|
s += GetLength(k);
|
340 |
|
|
}
|
341 |
|
|
RefEdge_GetS(i, __t, &ds, __curvilinearLength);
|
342 |
|
|
s += ds;
|
343 |
|
|
|
344 |
|
|
*__s = s;
|
345 |
|
|
}
|
346 |
|
|
|
347 |
|
|
void
|
348 |
|
|
PolyCurve::evaluer (double __s, double __X[3])
|
349 |
|
|
{
|
350 |
|
|
bool curvilinearLength = false;
|
351 |
|
|
evaluer(__s, __X, curvilinearLength);
|
352 |
|
|
}
|
353 |
|
|
|
354 |
|
|
void
|
355 |
|
|
PolyCurve::evaluer (double __s, double __X[3], bool __curvilinearLength) // curvilinear abcissa
|
356 |
|
|
{
|
357 |
|
|
VerifyS (__s);
|
358 |
|
|
|
359 |
|
|
unsigned iEdge;
|
360 |
|
|
MG_ARETE * edge;
|
361 |
|
|
double t, dt;
|
362 |
|
|
Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
|
363 |
|
|
edge = lst_ref_edges [ iEdge ];
|
364 |
|
|
if (t < edge->get_tmin())
|
365 |
|
|
Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
|
366 |
|
|
|
367 |
|
|
edge->evaluer ( t, __X );
|
368 |
|
|
}
|
369 |
|
|
|
370 |
|
|
void
|
371 |
|
|
PolyCurve::deriver (double __s, double __X[3]) // curvilinear abcissa
|
372 |
|
|
{
|
373 |
|
|
bool curvilinearLength = false;
|
374 |
|
|
deriver(__s, __X, curvilinearLength);
|
375 |
|
|
}
|
376 |
|
|
|
377 |
|
|
void
|
378 |
|
|
PolyCurve::deriver (double __s, double __X[3], bool __curvilinearLength) // curvilinear abcissa
|
379 |
|
|
{
|
380 |
|
|
VerifyS (__s);
|
381 |
|
|
|
382 |
|
|
unsigned iEdge;
|
383 |
|
|
MG_ARETE * edge;
|
384 |
|
|
double t, dt;
|
385 |
|
|
Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
|
386 |
|
|
edge = lst_ref_edges [ iEdge ];
|
387 |
|
|
edge->deriver ( t, __X );
|
388 |
|
|
|
389 |
|
|
// dC/ds = dC/dt * dt/ds
|
390 |
|
|
for (int i = 0; i<3; i++)
|
391 |
|
|
__X[i] *= dt;
|
392 |
|
|
}
|
393 |
|
|
|
394 |
|
|
|
395 |
|
|
void
|
396 |
|
|
PolyCurve::deriver_seconde (double __s, double __ddxyz[3], double *__dxyz, double *__xyz) // curvilinear abcissa
|
397 |
|
|
{
|
398 |
|
|
bool curvilinearLength = false;
|
399 |
|
|
deriver_seconde(__s, __ddxyz, __dxyz, __xyz, curvilinearLength);
|
400 |
|
|
|
401 |
|
|
}
|
402 |
|
|
void
|
403 |
|
|
PolyCurve::deriver_seconde (double __s, double __ddxyz[3], double *__dxyz, double *__xyz, bool __curvilinearLength) // curvilinear abcissa
|
404 |
|
|
{
|
405 |
|
|
unsigned iEdge;
|
406 |
|
|
MG_ARETE * edge;
|
407 |
|
|
double t, dt;
|
408 |
|
|
|
409 |
|
|
VerifyS (__s);
|
410 |
|
|
|
411 |
|
|
Parameter_SToRefEdgeT ( __s, & iEdge , &t, &dt, __curvilinearLength );
|
412 |
|
|
edge = lst_ref_edges [ iEdge ];
|
413 |
|
|
|
414 |
|
|
for (int i=0; i<3; i++)
|
415 |
|
|
__ddxyz[i] = 0;
|
416 |
|
|
|
417 |
|
|
if (__dxyz)
|
418 |
|
|
edge->deriver(t, __dxyz);
|
419 |
|
|
// dC/ds = dC/dt * dt/ds
|
420 |
|
|
for (int i = 0; i<3; i++)
|
421 |
|
|
__dxyz[i] *= dt;
|
422 |
|
|
|
423 |
|
|
if (__xyz)
|
424 |
|
|
edge->evaluer(t, __xyz);
|
425 |
|
|
}
|
426 |
|
|
|
427 |
|
|
|
428 |
|
|
|
429 |
|
|
void
|
430 |
|
|
PolyCurve::Merge( PolyCurve & __polycurve)
|
431 |
|
|
{
|
432 |
|
|
if (lst_vertices.size() == 0)
|
433 |
|
|
{
|
434 |
|
|
for (std::vector < MG_ARETE * >::const_iterator it = __polycurve.lst_ref_edges.begin();
|
435 |
|
|
it != __polycurve.lst_ref_edges.end();
|
436 |
|
|
it++ )
|
437 |
|
|
InsertCurve ( *it );
|
438 |
|
|
}
|
439 |
|
|
else if (get_sommet2() == __polycurve.get_sommet2() || get_sommet1() == __polycurve.get_sommet2() )
|
440 |
|
|
{;
|
441 |
|
|
for (std::vector < MG_ARETE * >::reverse_iterator it = __polycurve.lst_ref_edges.rbegin();
|
442 |
|
|
it != __polycurve.lst_ref_edges.rend();
|
443 |
|
|
it++)
|
444 |
|
|
InsertCurve ( *it );
|
445 |
|
|
}
|
446 |
|
|
else if ( get_sommet1() == __polycurve.get_sommet1() || get_sommet2() == __polycurve.get_sommet1() )
|
447 |
|
|
{
|
448 |
|
|
for (std::vector < MG_ARETE * >::const_iterator it = __polycurve.lst_ref_edges.begin();
|
449 |
|
|
it != __polycurve.lst_ref_edges.end();
|
450 |
|
|
it++ )
|
451 |
|
|
InsertCurve ( *it );
|
452 |
|
|
}
|
453 |
|
|
else
|
454 |
|
|
{
|
455 |
|
|
printf("PolyCurve::Merge Error : the polycurve %d is neither adjacent to end vertex nor to start vertex of polycurve %d\n", __polycurve.get_id(), get_id());
|
456 |
|
|
printf("Polycurve Start vertex = %d, End vertex = %d\n", get_sommet1()->get_id(),get_sommet2()->get_id());
|
457 |
|
|
printf("Other __polycurve Start vertex = %d, End vertex = %d\n", __polycurve.get_sommet1()->get_id(), __polycurve.get_sommet2()->get_id());
|
458 |
|
|
return;
|
459 |
|
|
|
460 |
|
|
}
|
461 |
|
|
}
|
462 |
|
|
|
463 |
|
|
double
|
464 |
|
|
PolyCurve::get_longueur (double __s_min, double __s_max, double precision)
|
465 |
|
|
{
|
466 |
|
|
double result;
|
467 |
|
|
if ( __s_min >= 0 && __s_max >= 0 )
|
468 |
|
|
return fabs (__s_min - __s_max);
|
469 |
|
|
else
|
470 |
|
|
{
|
471 |
|
|
return t_max;
|
472 |
|
|
}
|
473 |
|
|
}
|
474 |
|
|
|
475 |
|
|
double PolyCurve::get_tmin()
|
476 |
|
|
{
|
477 |
|
|
return t_min;
|
478 |
|
|
}
|
479 |
|
|
|
480 |
|
|
double PolyCurve::get_tmax()
|
481 |
|
|
{
|
482 |
|
|
return t_max;
|
483 |
|
|
}
|
484 |
|
|
|
485 |
|
|
MG_SOMMET *
|
486 |
|
|
PolyCurve::get_sommet1()
|
487 |
|
|
{
|
488 |
|
|
return lst_vertices[0];
|
489 |
|
|
}
|
490 |
|
|
|
491 |
|
|
|
492 |
|
|
MG_SOMMET *
|
493 |
|
|
PolyCurve::get_sommet2()
|
494 |
|
|
{
|
495 |
|
|
return lst_vertices[lst_vertices.size()-1];
|
496 |
|
|
}
|
497 |
|
|
|
498 |
|
|
double
|
499 |
|
|
PolyCurve::get_sommet1_s()
|
500 |
|
|
{
|
501 |
|
|
return get_tmin();
|
502 |
|
|
}
|
503 |
|
|
|
504 |
|
|
|
505 |
|
|
double
|
506 |
|
|
PolyCurve::get_sommet2_s()
|
507 |
|
|
{
|
508 |
|
|
return get_tmax();
|
509 |
|
|
}
|
510 |
|
|
|
511 |
|
|
void
|
512 |
|
|
PolyCurve::inverser(double & __t, double __point[3], double precision)
|
513 |
|
|
{
|
514 |
|
|
bool curvilinearLength = false;
|
515 |
|
|
|
516 |
|
|
inverser(__t, __point, precision, curvilinearLength);
|
517 |
|
|
}
|
518 |
|
|
|
519 |
|
|
void
|
520 |
|
|
PolyCurve::inverser(double & __t, double __point[3], double precision, bool __curvilinearLength)
|
521 |
|
|
{
|
522 |
|
|
int j;
|
523 |
|
|
double s;
|
524 |
|
|
|
525 |
|
|
// Test wether the requested point is coincident with a vertex of the polyline
|
526 |
|
|
double epsilon = 1E-12;
|
527 |
|
|
|
528 |
|
|
|
529 |
|
|
for (std::vector<MG_SOMMET *>::iterator it_vertex = lst_vertices.begin();
|
530 |
|
|
it_vertex != lst_vertices.end();
|
531 |
|
|
it_vertex++)
|
532 |
|
|
{
|
533 |
|
|
double vertex_point [3];
|
534 |
|
|
MG_SOMMET * vertex = *it_vertex;
|
535 |
|
|
vertex->get_point()->evaluer(vertex_point);
|
536 |
|
|
|
537 |
|
|
for (j = 0; j < 3; j++)
|
538 |
|
|
if (fabs(vertex_point[j] - __point[j]) > epsilon)
|
539 |
|
|
break;
|
540 |
|
|
|
541 |
|
|
if ( j == 3 )
|
542 |
|
|
{
|
543 |
|
|
unsigned iVertex = std::distance ( lst_vertices.begin(), it_vertex );
|
544 |
|
|
s = 0;
|
545 |
|
|
for (unsigned k = 0; k < iVertex; k++)
|
546 |
|
|
s += lst_length[k];
|
547 |
|
|
|
548 |
|
|
__t = s;
|
549 |
|
|
|
550 |
|
|
return;
|
551 |
|
|
}
|
552 |
|
|
}
|
553 |
|
|
|
554 |
|
|
// If the requested point is not on a vertex
|
555 |
|
|
// then test the reference edges
|
556 |
|
|
unsigned iClosestEdge;
|
557 |
|
|
double tClosestEdge = 0;
|
558 |
|
|
double min_distance = 1E99;
|
559 |
|
|
MG_ARETE * edge;
|
560 |
|
|
for (std::vector <MG_ARETE *>::iterator it_edge = lst_ref_edges.begin();
|
561 |
|
|
it_edge != lst_ref_edges.end();
|
562 |
|
|
it_edge++)
|
563 |
|
|
{
|
564 |
|
|
edge = *it_edge;
|
565 |
|
|
double t_edge;
|
566 |
|
|
edge->inverser ( t_edge, __point );
|
567 |
|
|
double point[3];
|
568 |
|
|
edge->evaluer (t_edge, point );
|
569 |
|
|
double distance = OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(point, __point);
|
570 |
|
|
if (distance < min_distance)
|
571 |
|
|
{
|
572 |
|
|
min_distance = distance;
|
573 |
|
|
iClosestEdge = std::distance (lst_ref_edges.begin(), it_edge );
|
574 |
|
|
tClosestEdge = t_edge;
|
575 |
|
|
}
|
576 |
|
|
}
|
577 |
|
|
|
578 |
|
|
Parameter_RefEdgeTToS ( tClosestEdge, lst_ref_edges[iClosestEdge], &s, __curvilinearLength);
|
579 |
|
|
|
580 |
|
|
__t = s;
|
581 |
|
|
|
582 |
|
|
printf("get_longueur = %f\n", get_longueur());
|
583 |
|
|
return;
|
584 |
|
|
}
|
585 |
|
|
|
586 |
|
|
|
587 |
|
|
int PolyCurve::est_periodique(void)
|
588 |
|
|
{
|
589 |
|
|
if ( get_sommet1 () == get_sommet2 () )
|
590 |
|
|
return 1;
|
591 |
|
|
else
|
592 |
|
|
return 0;
|
593 |
|
|
}
|
594 |
|
|
|
595 |
|
|
double PolyCurve::get_periode(void)
|
596 |
|
|
{
|
597 |
|
|
return get_longueur();
|
598 |
|
|
}
|
599 |
|
|
|
600 |
|
|
|
601 |
|
|
int PolyCurve::get_type_geometrique(TPL_LISTE_ENTITE<double> ¶m)
|
602 |
|
|
{
|
603 |
|
|
return 4343; // TYPE = Poly curve
|
604 |
|
|
}
|
605 |
|
|
|
606 |
|
|
void PolyCurve::enregistrer(std::ostream& o)
|
607 |
|
|
{
|
608 |
|
|
// %ID=CAD4FE_POLYCURVE(MG_ARETE_1,MG_ARETE_2,...,MG_ARETE_N)
|
609 |
|
|
unsigned int i;
|
610 |
|
|
|
611 |
|
|
o << "%" << get_id()
|
612 |
|
|
<< "=CAD4FE_POLYCURVE(" << GetRefEdgeCount() << ",(";
|
613 |
|
|
|
614 |
|
|
for (i=0; i < GetRefEdgeCount(); i++)
|
615 |
|
|
{
|
616 |
|
|
if ( i ) o <<",";
|
617 |
|
|
o << "$" << GetRefEdge(i)->get_id();
|
618 |
|
|
}
|
619 |
|
|
|
620 |
|
|
o << "));" << std::endl;;
|
621 |
|
|
}
|
622 |
|
|
|
623 |
|
|
std::vector<MG_ARETE*> &
|
624 |
|
|
PolyCurve::GetRefEdges()
|
625 |
|
|
{
|
626 |
|
|
return lst_ref_edges;
|
627 |
|
|
}
|
628 |
|
|
|
629 |
|
|
void
|
630 |
|
|
CAD4FE::SplitRefEdge(MG_ARETE * __refEdge, MG_SOMMET * __refVertex1, MG_SOMMET * __refVertex2, double __xyz[3], MG_VOLUME * __refBody, MG_GEOMETRIE * __geom, MG_ARETE * edges[2], MG_SOMMET ** __splitVertex)
|
631 |
|
|
{
|
632 |
|
|
int i,j;
|
633 |
|
|
|
634 |
|
|
// Create the split vertex at position xyz
|
635 |
|
|
MG_POINT * point = new LC_POINT(__xyz);
|
636 |
|
|
__geom->ajouter_mg_point(point);
|
637 |
|
|
std::ostringstream idoriginal;
|
638 |
|
|
idoriginal << "Split Vertex "<<__xyz[0]<<" "<<__xyz[1]<<" "<<__xyz[2];
|
639 |
|
|
MG_SOMMET * splitVertex = new MG_SOMMET(idoriginal.str(), point);
|
640 |
|
|
*__splitVertex = splitVertex;
|
641 |
|
|
__geom->ajouter_mg_sommet(splitVertex);
|
642 |
|
|
|
643 |
|
|
// split the edge in two edges
|
644 |
|
|
int edgeId[2];
|
645 |
|
|
MG_COURBE * curves[2];
|
646 |
|
|
MG_SOMMET * vertices[2][2];
|
647 |
|
|
MG_COSOMMET * cov[2][2];
|
648 |
|
|
|
649 |
|
|
MG_ARETE * split_edge = __refEdge;// __polyCurve->GetRefEdge(index);
|
650 |
|
|
vertices[0][0] = __refVertex1;//__polyCurve->GetRefVertex(index);
|
651 |
|
|
vertices[0][1] = splitVertex;
|
652 |
|
|
vertices[1][0] = splitVertex;
|
653 |
|
|
vertices[1][1] = __refVertex2;//__polyCurve->GetRefVertex(index+1);
|
654 |
|
|
|
655 |
|
|
curves[0] = curves[1] = split_edge->get_courbe();
|
656 |
|
|
|
657 |
|
|
// create two edges
|
658 |
|
|
for (i=0; i<2; i++)
|
659 |
|
|
{
|
660 |
|
|
// Create an edge using the start vertex and the split vertex
|
661 |
|
|
edges[i] = new MG_ARETE ("", 0, curves[i], 1);
|
662 |
|
|
__geom->ajouter_mg_arete (edges[i]);
|
663 |
|
|
|
664 |
|
|
// create covertices
|
665 |
|
|
for (j=0;j<2;j++)
|
666 |
|
|
{
|
667 |
|
|
cov[i][j] = __geom->ajouter_mg_cosommet (edges[i], vertices[i][j]);
|
668 |
|
|
}
|
669 |
|
|
|
670 |
|
|
edges[i]->changer_cosommet1 (cov[i][0]);
|
671 |
|
|
edges[i]->changer_cosommet2 (cov[i][1]);
|
672 |
|
|
}
|
673 |
|
|
|
674 |
|
|
MG_BOUCLE * split_edge_loops[10];
|
675 |
|
|
int nb_split_edge_loops = 0;
|
676 |
|
|
MG_COARETE * split_edge_coedges[10], * coedges[20];
|
677 |
|
|
int nb_split_edge_coedges = 0, nb_coedges = 0;
|
678 |
|
|
// create four coedges (in manifold body case)
|
679 |
|
|
// replace each coedges belong to initial edge in both loops of the ref faces
|
680 |
|
|
//
|
681 |
|
|
// for each shell of the ref body
|
682 |
|
|
unsigned nb_shells = __refBody->get_nb_mg_coquille ();
|
683 |
|
|
for (unsigned it_shells = 0; it_shells < nb_shells; it_shells++)
|
684 |
|
|
{
|
685 |
|
|
MG_COQUILLE * shell = __refBody->get_mg_coquille(it_shells);
|
686 |
|
|
// for each coface->face F of the shell
|
687 |
|
|
unsigned nb_coface = shell->get_nb_mg_coface();
|
688 |
|
|
for (unsigned it_coface = 0; it_coface < nb_coface; it_coface++)
|
689 |
|
|
{
|
690 |
|
|
MG_FACE * face = shell->get_mg_coface(it_coface)->get_face();
|
691 |
|
|
|
692 |
|
|
// for each loop L of this face
|
693 |
|
|
unsigned nb_loop = face->get_nb_mg_boucle();
|
694 |
|
|
for (unsigned it_loop = 0; it_loop < nb_loop; it_loop++)
|
695 |
|
|
{
|
696 |
|
|
MG_BOUCLE * loop = face->get_mg_boucle(it_loop);
|
697 |
|
|
// for each coedge coe of L
|
698 |
|
|
unsigned nb_edge = loop->get_nb_mg_coarete();
|
699 |
|
|
for (unsigned it_edge = 0; it_edge < nb_edge; it_edge++)
|
700 |
|
|
{
|
701 |
|
|
MG_COARETE * coedge = loop->get_mg_coarete(it_edge);
|
702 |
|
|
MG_ARETE * edge = coedge->get_arete();
|
703 |
|
|
|
704 |
|
|
// if coe contains split_edge
|
705 |
|
|
if (edge == split_edge)
|
706 |
|
|
{
|
707 |
|
|
split_edge_loops[ nb_split_edge_loops++ ] = loop;
|
708 |
|
|
split_edge_coedges[ nb_split_edge_coedges++ ] = coedge;
|
709 |
|
|
// create coe[0] ( edges[0], F, coe->sense )
|
710 |
|
|
// create coe[1] ( edges[1], F, coe->sense )
|
711 |
|
|
// delete coe in L
|
712 |
|
|
// add coe[0] in L
|
713 |
|
|
// add coe[1] in L
|
714 |
|
|
for (i=0; i<2; i++)
|
715 |
|
|
{
|
716 |
|
|
coedges[nb_coedges++] = __geom->ajouter_mg_coarete (edges[i], loop, coedge->get_orientation());
|
717 |
|
|
loop->ajouter_mg_coarete(coedges[nb_coedges-1]);
|
718 |
|
|
}
|
719 |
|
|
|
720 |
|
|
loop->supprimer_mg_coarete(coedge);
|
721 |
|
|
__geom->supprimer_mg_coarete(coedge);
|
722 |
|
|
}
|
723 |
|
|
// fi
|
724 |
|
|
}
|
725 |
|
|
}
|
726 |
|
|
}
|
727 |
|
|
}
|
728 |
|
|
|
729 |
|
|
}
|
730 |
|
|
|
731 |
|
|
void
|
732 |
|
|
CAD4FE::SplitPolyCurve(PolyCurve * __polyCurve, double __xyz[3], MG_VOLUME * __refBody, MG_GEOMETRIE * __geom, PolyCurve * __result[2], MG_ARETE **__origRefEdge, MG_SOMMET ** __splitRefVertex, MG_ARETE * __splitRefEdges[2])
|
733 |
|
|
{
|
734 |
|
|
int i,j;
|
735 |
|
|
*__splitRefVertex = NULL;
|
736 |
|
|
__splitRefEdges[0]=__splitRefEdges[1]=NULL;
|
737 |
|
|
|
738 |
|
|
// get the parameter of __splitVertex
|
739 |
|
|
double sSplitVertex;
|
740 |
|
|
__polyCurve->inverser(sSplitVertex,__xyz,1E-6);
|
741 |
|
|
|
742 |
|
|
unsigned index; // index of the reference edge split
|
743 |
|
|
double tEdge, dtEdge; // real parameter of the reference edge split
|
744 |
|
|
__polyCurve->Parameter_SToRefEdgeT(sSplitVertex,&index,&tEdge,&dtEdge, false);
|
745 |
|
|
*__origRefEdge = __polyCurve->GetRefEdge(index);
|
746 |
|
|
MG_SOMMET * v[2];
|
747 |
|
|
v[0] = __polyCurve->GetRefVertex(index);
|
748 |
|
|
v[1] = __polyCurve->GetRefVertex(index+1);
|
749 |
|
|
|
750 |
|
|
// Test wether __xyz is located on one extremity of the ref edge
|
751 |
|
|
for (i=0; i<2; i++)
|
752 |
|
|
{
|
753 |
|
|
double v_xyz[3];
|
754 |
|
|
|
755 |
|
|
v[i]->get_point()->evaluer(v_xyz);
|
756 |
|
|
|
757 |
|
|
if (OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(__xyz, v_xyz) / __polyCurve->GetLength(index) < 1E-6)
|
758 |
|
|
{
|
759 |
|
|
if (index+i == 0 || index+i+1 == __polyCurve->GetRefVertexCount())
|
760 |
|
|
{
|
761 |
|
|
printf("Can't split a polycurve on vertex ID %d because its extremities are vertices : %d and %d\n", v[i]->get_id(), __polyCurve->GetRefVertex(0)->get_id(), __polyCurve->GetRefVertex(__polyCurve->GetRefVertexCount()-1)->get_id());
|
762 |
|
|
return;
|
763 |
|
|
}
|
764 |
|
|
|
765 |
|
|
*__origRefEdge = NULL;
|
766 |
|
|
*__splitRefVertex = v[i];
|
767 |
|
|
__splitRefEdges[0] = __polyCurve->GetRefEdge(index-1+i);
|
768 |
|
|
__splitRefEdges[1] = __polyCurve->GetRefEdge(index+i);
|
769 |
|
|
|
770 |
|
|
// create the two polyCurves
|
771 |
|
|
for (int k=0; k<2; k++)
|
772 |
|
|
{
|
773 |
|
|
// create polycurve
|
774 |
|
|
__result[k] = new PolyCurve ( __splitRefEdges[k] );
|
775 |
|
|
__geom->ajouter_mg_courbe(__result[k]);
|
776 |
|
|
for (j = (k==0)?index-2+i:index+i+1; j >= 0 && j < __polyCurve->GetRefEdgeCount(); j += -1+2*k)
|
777 |
|
|
__result[k]->InsertCurve(__polyCurve->GetRefEdge(j));
|
778 |
|
|
}
|
779 |
|
|
|
780 |
|
|
break;
|
781 |
|
|
}
|
782 |
|
|
}
|
783 |
|
|
if (*__splitRefVertex == NULL)
|
784 |
|
|
{
|
785 |
|
|
CAD4FE::SplitRefEdge(*__origRefEdge, v[0], v[1], __xyz, __refBody, __geom, __splitRefEdges, __splitRefVertex);
|
786 |
|
|
|
787 |
|
|
// create the two polyCurves
|
788 |
|
|
for (i=0; i<2; i++)
|
789 |
|
|
{
|
790 |
|
|
// create polycurve
|
791 |
|
|
__result[i] = new PolyCurve ( __splitRefEdges[i] );
|
792 |
|
|
__geom->ajouter_mg_courbe(__result[i]);
|
793 |
|
|
for (j = index-1+2*i; j >= 0 && j < __polyCurve->GetRefEdgeCount(); j += -1+2*i)
|
794 |
|
|
__result[i]->InsertCurve(__polyCurve->GetRefEdge(j));
|
795 |
|
|
}
|
796 |
|
|
}
|
797 |
|
|
|
798 |
|
|
if (__result[0]->get_sommet1() !=__result[1]->get_sommet1() &&__result[0]->get_sommet1() !=__result[1]->get_sommet2() &&
|
799 |
|
|
__result[0]->get_sommet2() !=__result[1]->get_sommet1() &&__result[0]->get_sommet2() !=__result[1]->get_sommet2())
|
800 |
|
|
printf("Error");
|
801 |
|
|
|
802 |
|
|
}
|
803 |
|
|
|
804 |
|
|
|
805 |
|
|
|
806 |
|
|
void
|
807 |
francois |
19 |
PolyCurve::get_param_NURBS(int& indx_premier_ptctr,TPL_LISTE_ENTITE<double> ¶m)
|
808 |
|
5 |
{
|
809 |
|
|
return;
|
810 |
|
|
}
|
811 |
|
|
|
812 |
|
|
|
813 |
|
|
|