]> SALOME platform Git repositories - modules/hexablock.git/blob - src/HEXABLOCK/HexKasLine.cxx
Salome HOME
Merge from V6_main 01/04/2013
[modules/hexablock.git] / src / HEXABLOCK / HexKasLine.cxx
1 //
2 // CC++ : Implementation Cascade des lignes
3 //
4 // Copyright (C) 2009-2013  CEA/DEN, EDF R&D
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HexKasLine.hxx"
24 #include "HexKasPoint.hxx"
25 #include "HexKas_functions.hxx"
26
27 #ifndef NO_CASCADE
28
29 #include <BRepTools.hxx>
30 #include <BRep_Builder.hxx>
31 #include <BRepAdaptor_Curve.hxx>
32 #include <BRepBuilderAPI_Transform.hxx>
33 #include <BRepBuilderAPI_MakeVertex.hxx>
34
35 #include <GCPnts_AbscissaPoint.hxx>
36
37 #include <TopoDS.hxx>
38 #include <TopoDS_Shape.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Compound.hxx>
41 #include <TopoDS_Vertex.hxx>
42
43 #include <gp_Pln.hxx>
44 #include <gp_Pnt.hxx>
45 #include <gp_Dir.hxx>
46 #include <gp_Lin.hxx>
47
48 // HEXABLOCK includes
49 #include "HexVertex.hxx"
50 #include "HexEdge.hxx"
51 #include "HexOldShape.hxx"
52 #include "HexDiagnostics.hxx"
53
54 #include <GeomAPI_ProjectPointOnCurve.hxx>
55
56 BEGIN_NAMESPACE_HEXA
57
58 static bool db = on_debug ();
59 static const double TolAsso = 1e-2;    // Tolerance pour les associations
60
61 void arrondir (double &val);
62
63 // ======================================================= Constructeur
64 KasLine::KasLine ()
65 {
66    lig_brep     = "";
67    lig_debut    = 0;
68    lig_fin      = 1;
69    geom_inverse = false;
70    start_absc   = 0;
71    end_absc     = 1;
72    geom_rang    = NOTHING;
73
74    // geom_line   = TopoDS::Edge(shape);
75    geom_curve  = NULL;
76    geom_length = 0;
77    geom_total_length = 0;
78    for (int nc=0; nc <DIM3 ; nc++) start_coord [nc] = end_coord [nc] = 0;
79 }
80 // ========================================================= Constructeur bis
81 KasLine::KasLine (Shape* asso, double deb, double fin)
82 {
83    db = on_debug ();
84    geom_curve  = NULL;
85    defineLine (asso, deb, fin);
86 }
87 // ========================================================= Destructeur
88 KasLine::~KasLine ()
89 {
90    delete geom_curve;
91 }
92 // ========================================================= defineLine
93 // === Creation de la quincaillerie associee a une shape
94 void KasLine::defineLine (Shape* asso, double deb, double fin)
95 {
96    lig_brep  = asso->getBrep  ();
97    lig_ident = asso->getIdent ();
98    lig_ior   = asso->getIor   ();
99
100    if (fin<0.0)
101       {
102       lig_debut = asso->getStart();;
103       lig_fin   = asso->getEnd();;
104       }
105    else if (deb >= UnEpsil)
106       {
107       lig_debut = fin;
108       lig_fin   = deb ;
109       }
110    else
111       {
112       lig_debut = deb;
113       lig_fin   = fin;
114       }
115
116    geom_inverse = false;
117    start_absc   = 0;
118    end_absc     = 1;
119
120    istringstream streamBrep (lig_brep);
121    BRep_Builder  aBuilder;
122    TopoDS_Shape  topo;
123
124    BRepTools::Read(topo, streamBrep, aBuilder);
125    geom_line  = TopoDS::Edge(topo);
126    delete geom_curve;
127    geom_curve = new BRepAdaptor_Curve (geom_line);
128                                // Longueur de la ligne
129    double umin = 0, umax = 0;
130    TopLoc_Location    loc;
131    Handle(Geom_Curve) handle = BRep_Tool::Curve (geom_line, loc, umin, umax);
132    GeomAdaptor_Curve  AdaptCurve (handle);
133    geom_total_length = GCPnts_AbscissaPoint::Length(AdaptCurve, umin, umax);
134    geom_length = geom_total_length * fabs (lig_fin-lig_debut);
135
136                                // Extremites
137    GCPnts_AbscissaPoint s1 (*geom_curve, geom_total_length*lig_debut,
138                              geom_curve->FirstParameter());
139    GCPnts_AbscissaPoint s2 (*geom_curve, geom_total_length*lig_fin,
140                              geom_curve->FirstParameter());
141
142    par_mini     = s1.Parameter ();
143    par_maxi     = s2.Parameter ();
144    start_gpoint = geom_curve->Value (par_mini);
145    end_gpoint   = geom_curve->Value (par_maxi);
146    majCoord ();
147
148    if (db)
149       {
150       Echo (" ____________________________________  KasLine::defineLine");
151       HexDisplay (deb);
152       HexDisplay (fin);
153       HexDisplay (lig_debut);
154       HexDisplay (lig_fin);
155       HexDisplay (geom_total_length);
156       HexDisplay (geom_curve->FirstParameter());
157       HexDisplay (s1.Parameter());
158       HexDisplay (s2.Parameter());
159
160       PutCoord (start_coord);
161       PutCoord (end_coord);
162       }
163 }
164 // ========================================================= assoPoint
165 void KasLine::assoPoint (double abscis, Vertex* node)
166 {
167    GCPnts_AbscissaPoint s1 (*geom_curve, abscis,
168                              geom_curve->FirstParameter());
169    double gparam       = s1.Parameter ();
170    gp_Pnt pnt_asso = geom_curve->Value (gparam);
171
172    KasPoint gpoint;
173    gpoint.definePoint (pnt_asso);
174    gpoint.associate   (node);
175
176    if (db)
177       {
178       double* coord = gpoint.getCoord();
179       char    car   = '%';
180       if (node->definedBy (coord[dir_x], coord[dir_y], coord[dir_z]))
181          car= ' ';
182       printf (" ... assoPoint%c: v=%s (%g,%g,%g), p=%g", car,
183            node->getName(), node->getX(), node->getY(), node->getZ(), abscis);
184
185       printf (" -> (%g,%g,%g)\n", coord[dir_x], coord[dir_y], coord[dir_z]);
186       }
187 }
188 // ========================================================= associate
189 void KasLine::associate (Edge* edge, double sm1, double sm2, int vorig)
190 {
191    if (sm2 < start_absc) return;
192    if (sm1 > end_absc)   return;
193
194    Vertex* segment[V_TWO] = { edge->getVertex (vorig),
195                               edge->getVertex (1-vorig) };
196
197    double vpara1 = lig_debut + (sm1-start_absc)/geom_total_length;
198    double vpara2 = lig_debut + (sm2-start_absc)/geom_total_length;
199    if (geom_inverse)
200       {
201       vpara2 = lig_fin - (sm1-start_absc)/geom_total_length;
202       vpara1 = lig_fin - (sm2-start_absc)/geom_total_length;
203       }
204
205    double lpara1 = std::max (lig_debut, std::min (lig_fin, vpara1));
206    double lpara2 = std::max (lig_debut, std::min (lig_fin, vpara2));
207
208    arrondir (vpara1);    arrondir (vpara2);
209    arrondir (lpara1);    arrondir (lpara2);
210
211    if (db)
212       {
213       cout << " ++ KasLine::associate : rg=" << geom_rang  << "s=" << vorig
214            << endl;
215       cout << " ligpara = [ " << lig_debut << ", " << lig_fin << " ]" << endl;
216       cout << " absc    = [ " << start_absc << ", " << end_absc << " ]\n" ;
217
218       cout << " Edge    = " << edge->getName() <<
219                       " = [ " << segment[0]->getName() << ", "
220            << ","             << segment[1]->getName() << endl;
221       cout << " smx     = [ " << sm1    << ", " << sm2    << " ]" << endl;
222       cout << " vparam  = [ " << vpara1 << ", " << vpara2 << " ]" << endl;
223       cout << " lparam  = [ " << lpara1 << ", " << lpara2 << " ]" << endl;
224       }
225
226    if (lpara2 >= lpara1 + TolAsso)
227       {
228       assoEdge (edge, lpara1, lpara2);
229       }
230    else if (db)
231       {
232       printf (" Asso Line refusee %s -> (%g,%g)\n", edge->getName(),
233                                                     lpara1, lpara2);
234       }
235
236                                // ---------------Association du vertex
237    double hparam = geom_inverse ? vpara2 : vpara1;
238    double smx   = sm1;
239    double absc1 = start_absc - TolAsso*geom_total_length;
240    double absc2 = end_absc   + TolAsso*geom_total_length;
241
242    for (int nx=V_AMONT ; nx<=V_AVAL ; nx++)
243        {
244        if (smx >= absc1 && smx <= absc2)
245           {
246           Vertex* node = segment [nx];
247           if (node->getAssociation()==NULL)
248              {
249                                           // .....  Coordonnees du point
250
251              double abscis = geom_total_length*hparam;
252              GCPnts_AbscissaPoint s1 (*geom_curve, abscis,
253                                        geom_curve->FirstParameter());
254              double gparam       = s1.Parameter ();
255              gp_Pnt pnt_asso = geom_curve->Value (gparam);
256
257                                           // .....  Creation d'un vertex Geom
258              KasPoint gpoint;
259              gpoint.definePoint (pnt_asso);
260              gpoint.associate (node);
261              if (db)
262                 {
263                 double* ass = gpoint.getCoord();
264                 printf (" Asso Point %s (%g,%g,%g) -> (%g,%g,%g) p=%g s=%g\n",
265                     node->getName(), node->getX(), node->getY(), node->getZ(),
266                     ass[dir_x], ass[dir_y], ass[dir_z], hparam, smx);
267                 }
268              }
269          else if (db)
270              {
271              double abscis = geom_total_length*hparam;
272              GCPnts_AbscissaPoint s1 (*geom_curve, abscis,
273                                     geom_curve->FirstParameter());
274              double gparam   = s1.Parameter ();
275              gp_Pnt pnt_asso = geom_curve->Value (gparam);
276
277                                           // .....  Creation d'un vertex Geom
278              KasPoint gpoint;
279              gpoint.definePoint (pnt_asso);
280              double* ass = gpoint.getCoord();
281              // gpoint.associate (node);
282              printf (" Asso Point %s (%g,%g,%g) -> (%g,%g,%g) p=%g s=%g\n",
283                      node->getName(),
284                      node->getX(), node->getY(), node->getZ(),
285                      ass[dir_x], ass[dir_y], ass[dir_z], hparam, smx);
286
287              gpoint.definePoint (node);
288              ass = gpoint.getCoord();
289              printf ("               ignore car deja associe a (%g,%g, %g)\n",
290                      ass[dir_x], ass[dir_y], ass[dir_z]);
291              }
292           }
293       hparam = geom_inverse ? vpara1 : vpara2;
294       smx   = sm2;
295       }
296 }
297 // ========================================================= assoEdge
298 void KasLine::assoEdge (Edge* edge, double para1, double para2, int vass)
299 {
300    Shape* shape = new Shape (lig_brep);
301    shape->setIdent  (lig_ident);
302    shape->setIor    (lig_ior);
303    shape->setBounds (para1, para2);
304
305    edge ->addAssociation (shape);
306
307    if (db) printf (" ... Asso Edge %s -> (%g,%g)\n",
308            edge->getName(), para1, para2);
309
310    double lg = geom_total_length;
311    switch (vass)
312       {
313       case V_AMONT :
314            assoPoint (para1*lg, edge->getVertex (V_AMONT));
315            break;
316       case V_AVAL  :
317            assoPoint (para2*lg, edge->getVertex (V_AVAL));
318            break;
319       case V_TWO   :
320            assoPoint (para1*lg, edge->getVertex (V_AMONT));
321            assoPoint (para2*lg, edge->getVertex (V_AVAL ));
322            break;
323       default :;
324       }
325 }
326 // ========================================================= majCoord
327 void KasLine::majCoord ()
328 {
329    start_coord [dir_x] = start_gpoint.X();
330    start_coord [dir_y] = start_gpoint.Y();
331    start_coord [dir_z] = start_gpoint.Z();
332
333    end_coord   [dir_x] = end_gpoint.X();
334    end_coord   [dir_y] = end_gpoint.Y();
335    end_coord   [dir_z] = end_gpoint.Z();
336 }
337 // ========================================================= setBounds
338 void KasLine::setBounds (double deb, double fin)
339 {
340    lig_debut = deb;
341    lig_fin   = fin;
342 }
343 // ========================================================= inverser
344 void KasLine::inverser ()
345 {
346    gp_Pnt  foo  = start_gpoint;
347    start_gpoint = end_gpoint;
348    end_gpoint   = foo;
349
350               // Prendre le complementaire de l'intercvale initial
351    if (lig_debut > Epsil && lig_debut < UnEpsil)
352       {
353       lig_fin  = lig_debut;
354       lig_debut = 0;
355       if (db)
356          cout << " ... inverser : fin = debut = " << lig_fin << endl;
357       }
358    else if (lig_fin > Epsil && lig_fin < UnEpsil)
359       {
360       lig_debut = lig_fin;
361       lig_fin   = 1;
362       if (db)
363           cout << " ... inverser : debut = fin = " << lig_debut  << endl;
364       }
365
366    geom_inverse = NOT geom_inverse;
367    majCoord ();
368 }
369 // ========================================================= setRank
370 void KasLine::setRank (int nro, int sens, double& abscisse)
371 {
372    if (sens==V_AVAL)
373       inverser ();
374
375    geom_rang  = nro;
376    start_absc = abscisse;
377    abscisse   = end_absc = start_absc + (lig_fin-lig_debut) * geom_total_length;
378
379    if (db)
380       {
381       cout << "KasLine::setRank : nro = " << nro << " sens="  << sens
382            <<  " = (" << start_absc << ", " << end_absc << ")" << endl;
383       }
384 }
385 // ========================================================= findBound
386 int KasLine::findBound (double* coord)
387 {
388    if (same_coords (coord, start_coord) )
389       return V_AMONT;
390
391    if (same_coords (coord, end_coord) )
392       return V_AVAL;
393
394    return NOTHING;
395 }
396 // ========================================================= findParam
397 double KasLine::findParam (double* coord)
398 {
399    double umin = 0, umax = 0;
400    gp_Pnt gpoint (coord[dir_x], coord[dir_y], coord[dir_z]);
401    Handle(Geom_Curve) handle = BRep_Tool::Curve (geom_line, umin, umax);
402
403    GeomAPI_ProjectPointOnCurve projector (gpoint, handle);
404    if ( projector.NbPoints() == 0 )
405       return -1.0;
406
407    double gparam = projector.LowerDistanceParameter();
408    if (gparam <par_mini || gparam>par_maxi)
409       {
410       // cout << " Rejet : " << gparam << " not in (" << par_mini
411       //                              << ", " << par_maxi << ")" << endl;
412       return -1.0;
413       }
414
415    gp_Pnt rpoint = geom_curve->Value (gparam);
416    if (NOT same_coords (gpoint, rpoint))
417       {
418       //  cout << " Rejet : points differents " << endl;
419       return -1.0;
420       }
421
422
423    GeomAdaptor_Curve  adapt_curve (handle);
424    double abscis = GCPnts_AbscissaPoint::Length (adapt_curve, umin, gparam);
425    double hparam = abscis/geom_total_length;
426
427    // gparam = (gparam-par_mini) / (par_maxi-par_mini);
428    return hparam;
429 }
430 // ========================================================= arrondir
431 void arrondir (double &val)
432 {
433    if (val >= -TolAsso && val <= TolAsso)
434       {
435       val = 0.0;
436       }
437    else if (val >= 1.0-TolAsso && val <= 1.0+TolAsso)
438       {
439       val = 1.0;
440       }
441 }
442 END_NAMESPACE_HEXA
443 #endif