ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/CAD4FE/src/CAD4FE_MCNodePolyline.cpp
Revision: 27
Committed: Thu Jul 5 15:26:40 2007 UTC (17 years, 10 months ago) by foucault
Original Path: magic/lib/CAD4FE/CAD4FE/src/CAD4FE_MCNodePolyline.cpp
File size: 10522 byte(s)
Log Message:

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     }
164     if ((t2-t1)*(edge->get_tmax()-edge->get_tmin()) < 0)
165     std::swap(t1,t2);
166     if ((t2-t1) < 1E-6*(edge->get_tmax()-edge->get_tmin()) )
167     distEdge = (t2-t1)/(edge->get_tmax()-edge->get_tmin())*edge->get_longueur(edge->get_tmin(),edge->get_tmax());
168     else
169     distEdge = edge->get_longueur(t1,t2);
170     }
171     if (vertex)
172     {
173     if (mcNode1->IsInVertex(vertex) ||mcNode2->IsInVertex(vertex))
174     distVertex=OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3(mcNode1->get_coord(),mcNode2->get_coord());
175     else
176     distVertex=1E300;
177     }
178    
179     dist = distFace;
180     dist = std::min(dist, distEdge);
181     dist = std::min(dist, distVertex);
182    
183     return dist;
184     }
185    
186     MCNode MCNodePolyline::Evaluate(double __s, double * tangent, double * curvature)
187     {
188     //MCNode result(_mcTopo,topo,xyz[0],xyz[1],xyz[2]);
189     MCNode result;
190     double si=0;
191     double xyz[3];
192     MCNode *xi=_polylineNodes[0],*xii=_polylineNodes[1];
193     MG_ELEMENT_TOPOLOGIQUE * topo = NULL;
194     unsigned i=0;
195    
196     double polylineLength = GetLength();
197    
198     if (polylineLength == 0)
199     return *_polylineNodes[_polylineNodes.size()-1];
200    
201     if (1 - (__s / polylineLength) < 1E-6)
202     return *_polylineNodes[_polylineNodes.size()-1];
203    
204     for (i=0; lst_length.size() && __s > si+lst_length[i] && i<lst_length.size(); i++)
205     {
206     si += lst_length[i];
207     }
208    
209     topo = _polylineTopo[i];
210     xi=_polylineNodes[i];
211     xii=_polylineNodes[i+1];
212    
213     if (xi==NULL)
214     printf("Error in MCNodePolyline::Evaluate\n");
215    
216     double L = lst_length[i];
217    
218     double coef = (L > 1E-6*fabs(si-__s) ) ? (__s-si)/L : 0;
219    
220     if (topo != NULL)
221     {
222     if (topo->get_dimension()==2)
223     {
224     MG_FACE * face = (MG_FACE*) topo;
225     MCNode::FMap F;
226    
227     OT_VECTEUR_3D xi_uv = xi->UV(face);
228     OT_VECTEUR_3D xii_uv = xii->UV(face);
229    
230     OT_DECALAGE_PARAMETRE ot_decalage(face->get_surface()->get_periode_u(),face->get_surface()->get_periode_v());
231     double decal_u=ot_decalage.calcul_decalage_parametre_u(xi_uv[0]);
232     double decal_v=ot_decalage.calcul_decalage_parametre_v(xi_uv[1]);
233     OT_VECTEUR_3D decal_xi_uv(0,0,0), decal_xii_uv(0,0,0);
234     decal_xi_uv[0]=ot_decalage.decalage_parametre_u(xi_uv[0],decal_u);
235     decal_xi_uv[1]=ot_decalage.decalage_parametre_v(xi_uv[1],decal_v);
236     decal_xii_uv[0]=ot_decalage.decalage_parametre_u(xii_uv[0],decal_u);
237     decal_xii_uv[1]=ot_decalage.decalage_parametre_v(xii_uv[1],decal_v);
238    
239     OT_VECTEUR_3D Duv = (decal_xii_uv-decal_xi_uv);
240     Duv[2]=0;
241     OT_VECTEUR_3D decal_uv = decal_xi_uv + coef*Duv;
242     OT_VECTEUR_3D uv;
243     uv[0] = ot_decalage.decalage_parametre_u(decal_uv[0],-decal_u);
244     uv[1] = ot_decalage.decalage_parametre_v(decal_uv[1],-decal_v);
245    
246     F[face]=uv;
247     face->evaluer(uv,xyz);
248     result = MCNode(_mcTopo,face,uv,xyz);
249    
250     if (tangent)
251     {
252     OT_MATRICE_3D tangentPlaneFrame = GeometricTools::TangentPlaneFrame(face,xi_uv);
253     OT_VECTEUR_3D tangentTemp = tangentPlaneFrame*Duv;
254     tangentTemp.norme();
255     for (int i=0;i<3;i++) tangent[i] = tangentTemp[i];
256     }
257     if (curvature)
258     {
259     }
260     }
261     if (topo->get_dimension()==1)
262     {
263     MG_ARETE * edge = ( MG_ARETE * ) topo;
264     double t[3];
265     t[0] = xi->T(edge);
266     t[1] = xii->T(edge);
267     if ( edge->get_courbe()->est_periodique() )
268     {
269     double period=edge->get_courbe()->get_periode();
270     for (unsigned k=0;k<2;k++)
271     if (t[k] < edge->get_tmin() - 1E-6*edge->get_courbe()->get_periode())
272     t[k] += period;
273     if (fabs(t[1]-t[0])>.5*period)
274     {
275     if (t[1] < t[0]) t[1]+=period;
276     else t[0]+=period;
277     }
278     //if ((t[1]-t[0])*(edge->get_tmax()-edge->get_tmin()) < 0)
279     // std::swap(t[0],t[1]);
280     }
281     t[2] = t[0] + (t[1]-t[0])*coef;
282     edge->evaluer(t[2],xyz);
283     result = MCNode(_mcTopo,edge,t[2],xyz);
284    
285     if (tangent)
286     {
287     OT_VECTEUR_3D tangentTemp;
288     edge->deriver(t[2],tangentTemp);
289     tangentTemp.norme();
290     for (int i=0;i<3;i++) tangent[i] = tangentTemp[i];
291     }
292     }
293     }
294     if (topo == NULL || topo->get_dimension()==0)
295     {
296     for (int i=0; i<3; i++)
297     xyz[i]=(xii->get_coord()[i]-xi->get_coord()[i])*coef+xi->get_coord()[i];
298     result = MCNode(_mcTopo,topo,xyz[0],xyz[1],xyz[2]);
299     if (tangent)
300     {
301     OT_VECTEUR_3D tangentTemp;
302     for (int i=0; i<3; i++)
303     tangentTemp[i]=(xii->get_coord()[i]-xi->get_coord()[i]);
304     if ( tangentTemp.get_longueur2() > 1E-50 )
305     tangentTemp.norme();
306     for (int i=0; i<3; i++)
307     tangent[i]=tangentTemp[i];
308     }
309     }
310    
311     return result;
312     }
313    
314     unsigned MCNodePolyline::GetPolylineNodeCount()
315     {
316     return _polylineNodes.size();
317     }