ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_MCNodePolyline.cpp
Revision: 64
Committed: Fri Feb 1 18:27:30 2008 UTC (17 years, 3 months ago) by foucault
Original Path: magic/lib/CAD4FE/CAD4FE/src/CAD4FE_MCNodePolyline.cpp
File size: 10767 byte(s)
Log Message:
mise a jour final these Gilles Foucault

File Contents

# User Rev Content
1 foucault 27 //---------------------------------------------------------------------------
2    
3    
4     #pragma hdrstop
5    
6     #include "gestionversion.h"
7    
8     #include "mg_geometrie.h"
9     #include "ot_algorithme_geometrique.h"
10     #include "CAD4FE_MCNode.h"
11     #include "CAD4FE_MCFace.h"
12     #include "CAD4FE_PolySurface.h"
13     #include "CAD4FE_Intersection_Plane_MG_ARETE.h"
14     #include "CAD4FE_geometric_tools.h"
15     #include "CAD4FE_FaceBoundaryPoint.h"
16     #include "OT_DECALAGE_PARAMETRE.h"
17    
18     #include "CAD4FE_MCNodePolyline.h"
19    
20     //---------------------------------------------------------------------------
21    
22     #pragma package(smart_init)
23    
24     using namespace CAD4FE;
25    
26     MCNodePolyline::MCNodePolyline(MG_ELEMENT_TOPOLOGIQUE * __mcTopo)
27     : OT_REFERENCE(), _mcTopo(__mcTopo)
28     {
29    
30     }
31    
32     MCNodePolyline::MCNodePolyline(MG_ELEMENT_TOPOLOGIQUE * __mcTopo, const std::vector <MCNode*> & __polylineNodes, const std::vector <MG_ELEMENT_TOPOLOGIQUE*> & __polylineTopo)
33     : OT_REFERENCE(), _polylineNodes(__polylineNodes), _polylineTopo(__polylineTopo),_mcTopo(__mcTopo)
34     {
35     MCNode *xi=_polylineNodes[0],*xii=_polylineNodes[1];
36     MG_ELEMENT_TOPOLOGIQUE * topo = NULL;
37     for (unsigned i=0; i+1<_polylineNodes.size();i++)
38     {
39     topo = _polylineTopo[i];
40     xi=_polylineNodes[i];
41     xii=_polylineNodes[i+1];
42     lst_length.push_back( Distance(xi,xii,topo) );
43     }
44     for (unsigned i=0; i<_polylineNodes.size(); i++)
45     _polylineNodes[i]->incrementer();
46     }
47     MCNodePolyline::MCNodePolyline(MCNodePolyline &__pl)
48     {
49     _mcTopo = __pl._mcTopo;
50     _polylineNodes = __pl._polylineNodes;
51     _polylineTopo = __pl._polylineTopo;
52     lst_length = __pl.lst_length;
53     for (unsigned i=0; i<_polylineNodes.size(); i++)
54     _polylineNodes[i]->incrementer();
55     }
56     MCNodePolyline::~MCNodePolyline()
57     {
58     for (unsigned i=0; i<_polylineNodes.size(); i++)
59     {
60     _polylineNodes[i]->decrementer();
61     if ( _polylineNodes[i]->get_nb_reference() == 0)
62     delete _polylineNodes[i];
63     }
64     }
65     void MCNodePolyline::Add(MCNode * __mcNode, MG_ELEMENT_TOPOLOGIQUE * __topo)
66     {
67     _polylineNodes.push_back(__mcNode);
68     _polylineTopo.push_back(__topo);
69     __mcNode->incrementer();
70     if (_polylineNodes.size() > 1)
71     {
72     unsigned i = _polylineNodes.size() - 2;
73     MCNode *xi=_polylineNodes[i],*xii=_polylineNodes[i+1];
74     MG_ELEMENT_TOPOLOGIQUE *topo = _polylineTopo[i];
75     lst_length.push_back( Distance(xi,xii,topo) );
76     }
77     }
78     std::vector <MCNode *> & MCNodePolyline::GetPolylineNodes()
79     {
80     return _polylineNodes;
81     }
82     MCNode * MCNodePolyline::GetPolylineNode(unsigned __index)
83     {
84     return _polylineNodes[__index];
85     }
86     std::vector <MG_ELEMENT_TOPOLOGIQUE *> & MCNodePolyline::GetPolylineTopos()
87     {
88     return _polylineTopo;
89     }
90     MG_ELEMENT_TOPOLOGIQUE * MCNodePolyline::GetPolylineTopo(unsigned __index)
91     {
92     return _polylineTopo[__index];
93     }
94     void MCNodePolyline::Inverse(double &__t, MCNode *__mcNode)
95     {
96     double l=0;
97     for (unsigned i=0; i<_polylineNodes.size();i++)
98     {
99     MCNode * mcNode = _polylineNodes[i];
100     if (mcNode == __mcNode)
101     break;
102     l += lst_length[i];
103     }
104     __t = l;
105     }
106    
107     double MCNodePolyline::GetLength()
108     {
109     double l=0;
110     for (unsigned i=0; i<lst_length.size();i++)
111     l+=lst_length[i];
112     return l;
113     }
114    
115     double MCNodePolyline::Distance(MCNode * __a, MCNode * __b, MG_ELEMENT_TOPOLOGIQUE * __c)
116     {
117     MG_ELEMENT_TOPOLOGIQUE * topo = __c;
118     MCNode * mcNode1 = __a;
119     MCNode * mcNode2 = __b;
120    
121     double t1, t2;
122    
123     MG_FACE * face = 0;
124     double distFace=1E300;
125     MG_ARETE * edge = 0;
126     double distEdge=1E300;
127     MG_SOMMET * vertex = 0;
128     double distVertex=1E300;
129    
130     if (topo == NULL)
131     {
132     return OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(__a->get_coord(),__b->get_coord());
133     }
134    
135     switch(topo->get_dimension())
136     {
137     case 2:
138     face = (MG_FACE*)topo;
139     break;
140     case 1:
141     edge = (MG_ARETE*)topo;
142     break;
143     case 0:
144     vertex = (MG_SOMMET*)topo;
145     break;
146     }
147     double dist=1E300;
148    
149     if (face)
150     {
151     distFace = GeometricTools::Segment2dCurvilinearLength(face,mcNode2->UV(face),mcNode1->UV(face),3);
152     }
153     if (edge )
154     {
155     t1=mcNode1->GetEdgeParams(edge);
156     t2=mcNode2->GetEdgeParams(edge);
157     if (edge->get_courbe()->est_periodique())
158     {
159     if (t1 < edge->get_tmin()-1E-6*(edge->get_tmax()-edge->get_tmin()))
160     t1 += edge->get_courbe()->get_periode();
161     if (t2 < edge->get_tmin()-1E-6*(edge->get_tmax()-edge->get_tmin()))
162     t2 += edge->get_courbe()->get_periode();
163 foucault 64 if ((t2-t1)*2 > edge->get_courbe()->get_periode())
164     t1 += edge->get_courbe()->get_periode();
165     if ((t1-t2)*2 > edge->get_courbe()->get_periode())
166     t2 += edge->get_courbe()->get_periode();
167 foucault 27 }
168     if ((t2-t1)*(edge->get_tmax()-edge->get_tmin()) < 0)
169     std::swap(t1,t2);
170     if ((t2-t1) < 1E-6*(edge->get_tmax()-edge->get_tmin()) )
171     distEdge = (t2-t1)/(edge->get_tmax()-edge->get_tmin())*edge->get_longueur(edge->get_tmin(),edge->get_tmax());
172     else
173     distEdge = edge->get_longueur(t1,t2);
174     }
175     if (vertex)
176     {
177     if (mcNode1->IsInVertex(vertex) ||mcNode2->IsInVertex(vertex))
178     distVertex=OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(mcNode1->get_coord(),mcNode2->get_coord());
179     else
180     distVertex=1E300;
181     }
182    
183     dist = distFace;
184     dist = std::min(dist, distEdge);
185     dist = std::min(dist, distVertex);
186    
187     return dist;
188     }
189    
190     MCNode MCNodePolyline::Evaluate(double __s, double * tangent, double * curvature)
191     {
192     //MCNode result(_mcTopo,topo,xyz[0],xyz[1],xyz[2]);
193     MCNode result;
194     double si=0;
195     double xyz[3];
196     MCNode *xi=_polylineNodes[0],*xii=_polylineNodes[1];
197     MG_ELEMENT_TOPOLOGIQUE * topo = NULL;
198     unsigned i=0;
199    
200     double polylineLength = GetLength();
201    
202     if (polylineLength == 0)
203     return *_polylineNodes[_polylineNodes.size()-1];
204    
205     if (1 - (__s / polylineLength) < 1E-6)
206     return *_polylineNodes[_polylineNodes.size()-1];
207    
208     for (i=0; lst_length.size() && __s > si+lst_length[i] && i<lst_length.size(); i++)
209     {
210     si += lst_length[i];
211     }
212    
213     topo = _polylineTopo[i];
214     xi=_polylineNodes[i];
215     xii=_polylineNodes[i+1];
216    
217     if (xi==NULL)
218     printf("Error in MCNodePolyline::Evaluate\n");
219    
220     double L = lst_length[i];
221    
222     double coef = (L > 1E-6*fabs(si-__s) ) ? (__s-si)/L : 0;
223    
224     if (topo != NULL)
225     {
226     if (topo->get_dimension()==2)
227     {
228     MG_FACE * face = (MG_FACE*) topo;
229     MCNode::FMap F;
230    
231     OT_VECTEUR_3D xi_uv = xi->UV(face);
232     OT_VECTEUR_3D xii_uv = xii->UV(face);
233    
234     OT_DECALAGE_PARAMETRE ot_decalage(face->get_surface()->get_periode_u(),face->get_surface()->get_periode_v());
235     double decal_u=ot_decalage.calcul_decalage_parametre_u(xi_uv[0]);
236     double decal_v=ot_decalage.calcul_decalage_parametre_v(xi_uv[1]);
237     OT_VECTEUR_3D decal_xi_uv(0,0,0), decal_xii_uv(0,0,0);
238     decal_xi_uv[0]=ot_decalage.decalage_parametre_u(xi_uv[0],decal_u);
239     decal_xi_uv[1]=ot_decalage.decalage_parametre_v(xi_uv[1],decal_v);
240     decal_xii_uv[0]=ot_decalage.decalage_parametre_u(xii_uv[0],decal_u);
241     decal_xii_uv[1]=ot_decalage.decalage_parametre_v(xii_uv[1],decal_v);
242    
243     OT_VECTEUR_3D Duv = (decal_xii_uv-decal_xi_uv);
244     Duv[2]=0;
245     OT_VECTEUR_3D decal_uv = decal_xi_uv + coef*Duv;
246     OT_VECTEUR_3D uv;
247     uv[0] = ot_decalage.decalage_parametre_u(decal_uv[0],-decal_u);
248     uv[1] = ot_decalage.decalage_parametre_v(decal_uv[1],-decal_v);
249    
250     F[face]=uv;
251     face->evaluer(uv,xyz);
252     result = MCNode(_mcTopo,face,uv,xyz);
253    
254     if (tangent)
255     {
256     OT_MATRICE_3D tangentPlaneFrame = GeometricTools::TangentPlaneFrame(face,xi_uv);
257     OT_VECTEUR_3D tangentTemp = tangentPlaneFrame*Duv;
258     tangentTemp.norme();
259     for (int i=0;i<3;i++) tangent[i] = tangentTemp[i];
260     }
261     if (curvature)
262     {
263     }
264     }
265     if (topo->get_dimension()==1)
266     {
267     MG_ARETE * edge = ( MG_ARETE * ) topo;
268     double t[3];
269     t[0] = xi->T(edge);
270     t[1] = xii->T(edge);
271     if ( edge->get_courbe()->est_periodique() )
272     {
273     double period=edge->get_courbe()->get_periode();
274     for (unsigned k=0;k<2;k++)
275     if (t[k] < edge->get_tmin() - 1E-6*edge->get_courbe()->get_periode())
276     t[k] += period;
277     if (fabs(t[1]-t[0])>.5*period)
278     {
279     if (t[1] < t[0]) t[1]+=period;
280     else t[0]+=period;
281     }
282     //if ((t[1]-t[0])*(edge->get_tmax()-edge->get_tmin()) < 0)
283     // std::swap(t[0],t[1]);
284     }
285     t[2] = t[0] + (t[1]-t[0])*coef;
286     edge->evaluer(t[2],xyz);
287     result = MCNode(_mcTopo,edge,t[2],xyz);
288    
289     if (tangent)
290     {
291     OT_VECTEUR_3D tangentTemp;
292     edge->deriver(t[2],tangentTemp);
293     tangentTemp.norme();
294     for (int i=0;i<3;i++) tangent[i] = tangentTemp[i];
295     }
296     }
297     }
298     if (topo == NULL || topo->get_dimension()==0)
299     {
300     for (int i=0; i<3; i++)
301     xyz[i]=(xii->get_coord()[i]-xi->get_coord()[i])*coef+xi->get_coord()[i];
302     result = MCNode(_mcTopo,topo,xyz[0],xyz[1],xyz[2]);
303     if (tangent)
304     {
305     OT_VECTEUR_3D tangentTemp;
306     for (int i=0; i<3; i++)
307     tangentTemp[i]=(xii->get_coord()[i]-xi->get_coord()[i]);
308     if ( tangentTemp.get_longueur2() > 1E-50 )
309     tangentTemp.norme();
310     for (int i=0; i<3; i++)
311     tangent[i]=tangentTemp[i];
312     }
313     }
314    
315     return result;
316     }
317    
318     unsigned MCNodePolyline::GetPolylineNodeCount()
319     {
320     return _polylineNodes.size();
321     }