Salome HOME
Merge from V6_main 01/04/2013
[modules/hexablock.git] / src / HEXABLOCK / HexDocument.cxx
1
2 // C++ : La clase principale de Hexa
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 "HexDocument.hxx"
24
25 #include "HexEltBase.hxx"
26 #include "HexVertex.hxx"
27 #include "HexEdge.hxx"
28 #include "HexQuad.hxx"
29 #include "HexHexa.hxx"
30
31 #include "HexElements.hxx"
32 #include "HexCrossElements.hxx"
33 #include "HexBiCylinder.hxx"
34
35 #include "HexVector.hxx"
36 #include "HexCylinder.hxx"
37 #include "HexPipe.hxx"
38 #include "HexMatrix.hxx"
39 #include "HexCloner.hxx"
40 #include "HexPropagation.hxx"
41 #include "HexLaw.hxx"
42
43 #include "HexXmlWriter.hxx"
44 #include "HexXmlTree.hxx"
45 #include "HexGlobale.hxx"
46 #include "HexGroup.hxx"
47 #include "Hex.hxx"
48 #include "HexNewShape.hxx"
49
50 BEGIN_NAMESPACE_HEXA
51
52 int Document::doc_number = 0;
53
54 // ======================================================== Constructeur
55 Document::Document (cpchar name, Hex* dad)
56 {
57    el_name    = name;
58    hex_parent = dad;
59    glob       = Globale::getInstance ();
60    el_root    = this;
61
62    doc_db        = 0;
63    nbr_errors    = 0;
64    doc_modified  = true;
65    doc_saved     = false;
66    doc_tolerance = 1e-6;
67    nbr_laws      = 0;
68    nbr_propagations = 0;
69    maj_propagation  = true;
70    doc_xml          = NULL;
71
72    nbr_used_hexas = nbr_used_quads = nbr_used_edges = nbr_used_vertex = 0;
73
74    for (EnumElt type = EL_NONE ; type < EL_MAXI ; type=(EnumElt) (type+1))
75        {
76        doc_first_elt [type] = doc_last_elt [type] = new EltBase ();
77        doc_nbr_elt   [type] = 0;
78        }
79
80    if (doc_number == 0)
81       strcpy (doc_ident, "doc");
82    else
83       sprintf (doc_ident, "doc%02d", doc_number);
84    doc_number++;
85
86    DumpLock;
87    defaultLaw = addLaw ("DefaultLaw", 0);
88    DumpRestore;
89
90    addCloud ();
91 }
92 // ======================================================== Destructeur
93 Document::~Document ()
94 {
95    delete doc_xml;
96
97    for (EnumElt type = EL_NONE ; type < EL_MAXI ; type=(EnumElt) (type+1))
98        {
99        //  printf ("____________________________ Type=%d\n", type);
100        EltBase* next = NULL;
101        for (EltBase* elt=doc_first_elt [type] ; elt != NULL ; elt=next)
102            {
103            next = elt->next();
104            delete elt;
105            }
106        }
107 }
108 // ======================================================== addVector
109 Vector* Document::addVector (double dx, double dy, double dz)
110 {
111    DumpStart ("addVector", dx  << dy  << dz);
112    Vector* pv = new Vector (this, dx, dy, dz);
113    doc_vector.push_back (pv);
114
115    DumpReturn (pv);
116    return  pv;
117 }
118 // ======================================================== addVectorVertices
119 Vector* Document::addVectorVertices (Vertex* va, Vertex* vb)
120 {
121    DumpStart ("addVectorVertices", va  << vb);
122
123    Vector* pv = addVector (vb->getX () - va->getX (),
124                            vb->getY () - va->getY (),
125                            vb->getZ () - va->getZ ());
126
127    DumpReturn (pv);
128    return  pv;
129 }
130 // ======================================================== addVertex
131 Vertex* Document::addVertex (double x, double y, double z)
132 {
133    DumpStart ("addVertex", x  << y  << z);
134
135    Vertex* pv   = new Vertex (this, x, y, z);
136    DumpReturn (pv);
137    return pv;
138 }
139 // ======================================================== addEdge
140 Edge* Document::addEdge (Vertex* va, Vertex* vb)
141 {
142    DumpStart ("addEdge", va  << vb );
143
144    if (va==NULL || vb==NULL)
145       return NULL;
146
147    Edge* arete  = new Edge (va, vb);
148    DumpReturn (arete);
149    return arete;
150 }
151 // ======================================================== addEdgeVector
152 Edge* Document::addEdgeVector (Vertex* va, Vector* vec)
153 {
154    DumpStart ("addEdgeVector", va  << vec );
155
156    Vertex* vb   = addVertex (va->getX () + vec->getDx(),
157                              va->getY () + vec->getDy(),
158                              va->getZ () + vec->getDz());
159
160    Edge*  arete = addEdge (va, vb);
161    DumpReturn (arete);
162    return arete;
163 }
164 // ======================================================== addQuadVertices
165 Quad* Document::addQuadVertices (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd)
166 {
167    DumpStart ("addQuadVertices", va << vb << vc << vd );
168
169    Quad*  face   = new Quad (va, vb, vc, vd);
170    DumpReturn (face);
171    return face;
172 }
173 // ======================================================== addQuad
174 Quad* Document::addQuad (Edge* ea, Edge* eb, Edge* ec, Edge* ed)
175 {
176    DumpStart ("addQuad", ea << eb << ec << ed );
177
178    Quad*  face   = new Quad (ea, eb, ec, ed);
179    DumpReturn (face);
180    return face;
181 }
182 // ======================================================== addHexaVertices
183 Hexa* Document::addHexaVertices (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd,
184                                  Vertex* ve, Vertex* vf, Vertex* vg, Vertex* vh)
185 {
186    DumpStart ("addHexaVertices", va << vb << vc << vd << ve << vf << vg << vh);
187
188    Hexa*  pave   = new Hexa (va, vb, vc, vd, ve, vf, vg, vh);
189    DumpReturn (pave);
190    return pave;
191 }
192 // ======================================================== addHexa
193 Hexa* Document::addHexa (Quad* qa, Quad* qb, Quad* qc, Quad* qd, Quad* qe,
194                          Quad* qf)
195 {
196    DumpStart ("addHexa", qa << qb << qc << qd << qe << qf );
197
198    Hexa*  pave   = new Hexa (qa, qb, qc, qd, qe, qf);
199    DumpReturn (pave);
200    return pave;
201 }
202 // ======================================================== addCylinder
203 Cylinder* Document::addCylinder (Vertex* b, Vector* d, double r,  double h)
204 {
205    DumpStart ("addCylinder", b << d << r << h);
206
207    Cylinder* cyl = new  Cylinder (b, d, r, h);
208    doc_cylinder.push_back (cyl);
209
210    DumpReturn (cyl);
211    return    cyl;
212 }
213 // ======================================================== addPipe
214 Pipe* Document::addPipe (Vertex* b, Vector* d, double ri, double re, double h)
215 {
216    DumpStart ("addPipe", b << d << ri << re << h);
217
218    Pipe*  tuyau = new  Pipe (b, d, ri, re, h);
219    doc_pipe.push_back (tuyau);
220
221    DumpReturn (tuyau);
222    return tuyau;
223 }
224 // ======================================================== makeCartesian
225 Elements* Document::makeCartesian (Vertex* v, Vector* dir,
226                             int px, int py, int pz, int mx, int my, int mz)
227 {
228    DumpStart ("makeCartesianDiag", v << dir << px << py << pz << mx << my << mz);
229
230    Vector* v1 = new Vector (this, dir->getDx(), 0, 0);
231    Vector* v2 = new Vector (this, 0, dir->getDy(), 0);
232    Vector* v3 = new Vector (this, 0,0,  dir->getDz());
233    Elements*  grille = new Elements (this);
234    grille->makeCartesianGrid (v, v1, v2, v3, px, py, pz, mx, my, mz);
235
236    DumpReturn (grille);
237    return grille;
238 }
239 // ======================================================== makeCartesian
240 Elements* Document::makeCartesian (Vertex* v, Vector* v1, Vector* v2,
241                                    Vector* v3, int px, int py, int pz)
242 {
243    DumpStart ("makeCartesian", v << v1 << v2 << v3 << px << py << pz);
244
245    Elements* grille = new Elements (this);
246    grille->makeCartesianGrid (v, v1, v2, v3, px, py, pz);
247
248    DumpReturn (grille);
249    return grille;
250 }
251 // ======================================================== makeCartesian1
252 Elements* Document::makeCartesian1 (Vertex* v, Vector* v1, Vector* v2,
253                     Vector* v3, int px, int py, int pz, int mx, int my, int mz)
254 {
255    DumpStart ("makeCartesian1", v << v1 << v2 << v3 << px << py << pz
256                               << mx << my << mz);
257
258    Elements* grille = new Elements (this);
259    grille->makeCartesianGrid (v, v1, v2, v3, px, py, pz, mx, my, mz);
260
261    DumpReturn (grille);
262    return grille;
263 }
264 // ======================================================== makeSpherical
265 Elements* Document::makeSpherical (Vertex* c, double rayon, int nb, double k)
266 {
267    DumpStart ("makeSpherical", c << rayon << nb << k );
268
269    Elements* grille = new Elements (this);
270    grille->makeSphericalGrid (c, rayon, nb, k);
271
272    DumpReturn (grille);
273    return grille;
274 }
275 // ======================================================== makeCylindrical
276 Elements* Document::makeCylindrical (Vertex* c, Vector* b, Vector* h,
277         double dr, double da, double dl, int nr, int na, int nl, bool fill)
278 {
279    DumpStart ("makeCylindrical", c << b << h << dr << da << dl << nr << na
280                                    << nl << fill);
281
282    Elements* grille = new Elements (this);
283    grille->makeCylindricalGrid (c, b, h, dr, da, dl, nr, na, nl, fill);
284
285    DumpReturn (grille);
286    return grille;
287 }
288 // ======================================================== makeSphere
289 Elements* Document::makeSphere (Vertex* center, Vector* vx, Vector* vz,
290                                 double radius, double radhole, Vertex* plorig,
291                                 int nrad, int nang, int nhaut)
292 {
293    DumpStart ("makeSphere", center << vx << vz << radius << radhole << plorig
294                   << nrad << nang << nhaut);
295
296    Elements* grille = new Elements (this);
297    double radint = (radhole + radius)*DEMI;
298    grille->makeRind (GR_HEMISPHERIC, center, vx, vz, radius, radint, radhole,
299                      plorig, 360.0, nrad, nang, nhaut);
300
301    DumpReturn (grille);
302    return grille;
303 }
304 // ======================================================== makePartSphere
305 Elements* Document::makePartSphere (Vertex* center, Vector* vx, Vector* vz,
306                                  double  radius, double radhole,
307                                  Vertex* plorig, double angle,
308                                  int nrad, int nang, int nhaut)
309 {
310    DumpStart ("makePartSphere", center << vx << vz
311                   << radius << radhole
312                   << plorig << angle
313                   << nrad   << nang << nhaut);
314
315    Elements* grille = new Elements (this);
316    double radint = (radhole + radius)*DEMI;
317    grille->makeRind (GR_PART_SPHERIC, center, vx, vz, radius, radint, radhole,
318                      plorig, angle, nrad, nang, nhaut);
319
320    DumpReturn (grille);
321    return grille;
322 }
323 // ======================================================== makeRind
324 Elements* Document::makeRind (Vertex* center, Vector* vx, Vector* vz,
325                               double  radext, double radint, double radhole,
326                               Vertex* plorig, int nrad, int nang, int nhaut)
327 {
328    DumpStart ("makeRind", center << vx << vz
329                   << radext << radint << radhole
330                   << plorig << nrad   << nang << nhaut);
331
332    Elements* grille = new Elements (this);
333    grille->makeRind (GR_RIND, center, vx, vz, radext, radint, radhole,
334                      plorig, 360.0, nrad, nang, nhaut);
335
336    DumpReturn (grille);
337    return grille;
338 }
339 // ======================================================== makePartRind
340 Elements* Document::makePartRind (Vertex* center, Vector* vx, Vector* vz,
341                            double  radext, double radint, double radhole,
342                            Vertex* plorig, double angle,
343                                int nrad, int nang, int nhaut)
344 {
345    DumpStart ("makePartRind", center << vx << vz
346                   << radext << radint << radhole
347                   << plorig << angle  << nrad  << nang << nhaut);
348
349    Elements* grille = new Elements (this);
350    grille->makeRind (GR_PART_RIND, center, vx, vz, radext, radint, radhole,
351                      plorig, angle, nrad, nang, nhaut);
352
353    DumpReturn (grille);
354    return grille;
355 }
356 // ======================================================== findVertex
357 Vertex* Document::findVertex (double vx, double vy, double vz)
358 {
359    double xmin = vx - doc_tolerance;
360    double xmax = vx + doc_tolerance;
361    double ymin = vy - doc_tolerance;
362    double ymax = vy + doc_tolerance;
363    double zmin = vz - doc_tolerance;
364    double zmax = vz + doc_tolerance;
365
366    for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
367                  elt = elt->next())
368        {
369        if (elt->isHere())
370           {
371           Vertex* node = static_cast <Vertex*> (elt);
372           if (node->isin (xmin, xmax, ymin, ymax, zmin, zmax))
373              return node;
374           }
375        }
376    return NULL;
377 }
378 // ======================================================== findEdge
379 Edge* Document::findEdge (Vertex* v1, Vertex* v2)
380 {
381    for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); elt!=NULL;
382                  elt = elt->next())
383        {
384        Edge* candidat  = static_cast <Edge*> (elt);
385        if (candidat->definedBy (v1, v2))
386           return candidat;
387        }
388    return NULL;
389 }
390 // ======================================================== findQuad
391 Quad* Document::findQuad (Vertex* v1, Vertex* v2)
392 {
393    for (EltBase* elt = doc_first_elt[EL_QUAD]->next (); elt!=NULL;
394                  elt = elt->next())
395        {
396        Quad* candidat  = static_cast <Quad*> (elt);
397        if (candidat->definedBy (v1, v2))
398           return candidat;
399        }
400    return NULL;
401 }
402 // ======================================================== findHexa
403 Hexa* Document::findHexa (Vertex* v1, Vertex* v2)
404 {
405    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
406                  elt = elt->next())
407        {
408        Hexa* candidat  = static_cast <Hexa*> (elt);
409        if (candidat->definedBy (v1, v2))
410           return candidat;
411        }
412    return NULL;
413 }
414 // ======================================================== findElement
415 EltBase* Document::findElement (EnumElt type, int ident)
416 {
417    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
418                  elt = elt->next())
419        {
420        if (elt->isHere() && elt->getId()==ident)
421           return elt;
422        }
423    return NULL;
424 }
425 // ======================================================== findVertex
426 Vertex* Document::findVertex (int ident)
427 {
428    Vertex* node = static_cast <Vertex*> (findElement (EL_VERTEX, ident));
429    return  node;
430
431 }
432 // ======================================================== index_tv
433 int index_tv (Vertex* table[], Vertex* elt)
434 {
435    for (int nro=0; nro<QUAD4; nro++)
436         if (elt == table[nro])
437            return nro;
438
439    return NOTHING;
440 }
441 // ======================================================== mergeQuads
442 int Document::mergeQuads (Quad* dest, Quad* orig, Vertex* v1, Vertex* v2,
443                                                 Vertex* v3, Vertex* v4)
444 {
445    DumpStart ("mergeQuads", dest << orig << v1 << v2  << v3 << v4);
446
447    update ();
448
449    if (dest==orig)
450       {
451       printf (" *** Quads identiques dans mergeQuads\n");
452       DumpEnd;
453       return HERR;
454       }
455    else if (dest==NULL || dest->isDeleted())
456       {
457       printf (" *** Quad nro 1 incorrect dans mergeQuads \n");
458       DumpEnd;
459       return HERR;
460       }
461    else if (orig==NULL || orig->isDeleted() )
462       {
463       printf (" *** Quad nro 2 incorrect dans mergeQuads \n");
464       DumpEnd;
465       return HERR;
466       }
467
468    int nbcomm = 0;
469    for (int nro=0 ; nro<QUAD4 ; nro++)
470        {
471        int norig = orig->indexVertex (dest->getVertex(nro));
472        if (norig != NOTHING)
473           {
474           Vertex* uv = dest->getVertex(nro);
475           char nom[12];
476           nbcomm ++;
477           if (nbcomm==1)
478              {
479              printf ("  +++ Sommets communs dans mergeQuads");
480              printf (" (%s,",  dest->getName (nom));
481              printf (" %s)\n", orig->getName (nom));
482              }
483           printf ("  +++ quad1[%d] = quad2[%d] = %s\n", nro,  norig,
484                                                         uv->getName (nom));
485           }
486        }
487
488    if (nbcomm == 2)
489       {
490       printf ("  +++ Les vertex passes en arguments sont ignores\n");
491       int ier = closeQuads (dest, orig);
492       DumpEnd;
493       return ier;
494       }
495    else if (nbcomm != 0)
496       {
497       printf ("  *** _____________________ mergeQuads refuse: \n");
498       printf (" il y a %d sommet(s) sont commun(s)\n", nbcomm);
499       DumpEnd;
500       return HERR;
501       }
502
503    if (   v1 ==NULL || v1 ->isDeleted() || v2 ==NULL || v2 ->isDeleted()
504        || v3 ==NULL || v3 ->isDeleted() || v4 ==NULL || v4 ->isDeleted())
505       {
506       printf ("  *** _____________________ mergeQuads refuse: \n");
507       printf (" un sommet est incorrect\n");
508       DumpEnd;
509       return HERR;
510       }
511
512
513    if (debug())
514       {
515       printf ("  ----------------- mergeQuads : \n");
516       HexDump (orig);
517       HexDump (dest);
518       HexDump (v1);
519       HexDump (v2);
520       HexDump (v3);
521       HexDump (v4);
522       }
523
524    Vertex *tv1 [QUAD4], *tv2 [QUAD4];
525    Edge   *te1 [QUAD4], *te2 [QUAD4];
526
527    int ier1 = dest->ordoVertex (v1, v3, tv1);
528    int ier2 = orig->ordoVertex (v2, v4, tv2);
529    if (ier1 != HOK)
530       {
531       DumpEnd;
532       return ier1;
533       }
534    else if (ier2 != HOK)
535       {
536       DumpEnd;
537       return ier2;
538       }
539
540    for (int nro=0 ; nro<QUAD4 ; nro++)
541        {
542        te1 [nro] = dest->getEdge(nro);
543        Vertex* va1 = te1[nro]->getVertex(V_AMONT);
544        Vertex* vb1 = te1[nro]->getVertex(V_AVAL);
545        int na = index_tv  (tv1, va1);
546        int nb = index_tv  (tv1, vb1);
547        if (na==NOTHING || nb==NOTHING)
548           {
549           DumpEnd;
550           return HERR;
551           }
552
553        te2 [nro] = orig->findEdge (tv2[na], tv2[nb]);
554        if (te2[nro]==NULL)
555           {
556           DumpEnd;
557           return HERR;
558           }
559        }
560
561    if (debug())
562       {
563       printf ("  ----------------- Correspondances mergeQuads : \n");
564       for (int nro=0 ; nro<QUAD4 ; nro++)
565           {
566           printf ("  %d  : ", nro);
567           tv2 [nro]->printName(" -> ");
568           tv1 [nro]->printName("\n");
569           }
570       for (int nro=0 ; nro<QUAD4 ; nro++)
571           {
572           printf ("  %d  : ", nro);
573           te2 [nro]->printName(" (");
574           te2 [nro]->getVertex(0)->printName(", ");
575           te2 [nro]->getVertex(1)->printName(") -> ");
576           te1 [nro]->printName(" (");
577           te1 [nro]->getVertex(0)->printName(", ");
578           te1 [nro]->getVertex(1)->printName(")\n");
579           }
580       }
581
582    replaceQuad (orig, dest);
583    for (int nro=0 ; nro<QUAD4 ; nro++)
584        replaceEdge   (te2[nro], te1[nro]);
585    for (int nro=0 ; nro<QUAD4 ; nro++)
586        replaceVertex (tv2[nro], tv1[nro]);
587
588    maj_connection = false;
589    purge_elements = false;
590
591    DumpEnd;
592    return HOK;
593 }
594 // ======================================================== closeQuads
595 int Document::closeQuads (Quad* dest, Quad* orig)
596 {
597    DumpStart ("closeQuads", dest << orig);
598
599    update ();
600    char nom[12];
601
602    if (dest==orig)
603       {
604       printf (" *** Quads identiques dans closeQuads : %s\n",
605                  dest->getName(nom));
606       DumpEnd;
607       return HERR;
608       }
609    else if (dest==NULL || dest->isDeleted())
610       {
611       printf (" *** Quad nro 1 incorrect dans closeQuads \n");
612       DumpEnd;
613       return HERR;
614       }
615    else if (orig==NULL || orig->isDeleted() )
616       {
617       printf (" *** Quad nro 2 incorrect dans closeQuads \n");
618       DumpEnd;
619       return HERR;
620       }
621
622    Edge* edc = NULL;
623    for (int nro=0 ; nro<QUAD4 ; nro++)
624        {
625        int norig = orig->indexEdge (dest->getEdge(nro));
626        if (norig != NOTHING)
627           {
628           if (edc != NULL)
629              {
630              printf ("  *** Plus d'une arete commune dans closeQuads");
631              printf (" (%s,",  dest->getName (nom));
632              printf (" %s)\n", orig->getName (nom));
633              DumpEnd;
634              return HERR;
635              }
636           edc = dest->getEdge (nro);
637           printf ("  +++ quad1[%d] = quad2[%d] = %s\n", nro,  norig,
638                                                         edc->getName (nom));
639           }
640        }
641
642    Vertex* va = edc->getVertex (V_AMONT);
643    Vertex* vb = edc->getVertex (V_AVAL);
644    Vertex *tv1 [QUAD4], *tv2 [QUAD4];
645    Edge   *te1 [QUAD4], *te2 [QUAD4];
646
647    int ier1 = dest->ordoVertex (va, vb, tv1);
648    int ier2 = orig->ordoVertex (va, vb, tv2);
649
650    if (ier1 != HOK)
651       {
652       DumpEnd;
653       return ier1;
654       }
655    else if (ier2 != HOK)
656       {
657       DumpEnd;
658       return ier2;
659       }
660
661    for (int nro=0 ; nro<QUAD4 ; nro++)
662        {
663        te1 [nro] = dest->getEdge(nro);
664        Vertex* va1 = te1[nro]->getVertex(V_AMONT);
665        Vertex* vb1 = te1[nro]->getVertex(V_AVAL);
666        int na = index_tv  (tv1, va1);
667        int nb = index_tv  (tv1, vb1);
668        if (na==NOTHING || nb==NOTHING)
669           {
670           DumpEnd;
671           return HERR;
672           }
673
674        te2 [nro] = orig->findEdge (tv2[na], tv2[nb]);
675        if (te2[nro]==NULL)
676           {
677           DumpEnd;
678           return HERR;
679           }
680        }
681
682    if (debug())
683       {
684       printf ("  ----------------- Correspondances mergeQuads : \n");
685       for (int nro=0 ; nro<QUAD4 ; nro++)
686           {
687           printf ("  %d  : ", nro);
688           tv2 [nro]->printName(" -> ");
689           tv1 [nro]->printName("\n");
690           }
691       for (int nro=0 ; nro<QUAD4 ; nro++)
692           {
693           printf ("  %d  : ", nro);
694           te2 [nro]->printName(" (");
695           te2 [nro]->getVertex(0)->printName(", ");
696           te2 [nro]->getVertex(1)->printName(") -> ");
697           te1 [nro]->printName(" (");
698           te1 [nro]->getVertex(0)->printName(", ");
699           te1 [nro]->getVertex(1)->printName(")\n");
700           }
701       }
702
703    replaceQuad (orig, dest);
704    for (int nro=0 ; nro<QUAD4 ; nro++)
705        replaceEdge   (te2[nro], te1[nro]);
706    for (int nro=0 ; nro<QUAD4 ; nro++)
707        replaceVertex (tv2[nro], tv1[nro]);
708
709    maj_connection = false;
710    purge_elements = false;
711
712    DumpEnd;
713    return HOK;
714 }
715 // ======================================================== mergeEdges
716 int Document::mergeEdges (Edge* e1, Edge* e2, Vertex* v1, Vertex* v2)
717 {
718    DumpStart ("mergeEdges", e1 << e2 << v1 << v2);
719
720    if (e1==NULL || e1->isDeleted() || e2==NULL || e2->isDeleted())
721       {
722       DumpEnd;
723       return HERR;
724       }
725
726    for (int nro=0 ; nro<V_TWO ; nro++)
727        if (e1->index (e2->getVertex(nro))!= NOTHING)
728           {
729           DumpEnd;
730           return HERR+nro+1;
731           }
732
733    Vertex *tv1 [V_TWO], *tv2 [V_TWO];
734
735    int ier1 = e1->anaMerge (v1, tv1);
736    int ier2 = e2->anaMerge (v2, tv2);
737
738    if (ier1 != HOK)
739       {
740       DumpEnd;
741       return ier1;
742       }
743    else if (ier2 != HOK)
744       {
745       DumpEnd;
746       return ier2;
747       }
748
749    replaceEdge (e2, e1);
750    for (int nro=0 ; nro<V_TWO ; nro++)
751        replaceVertex (tv2[nro], tv1[nro]);
752
753    maj_connection = false;
754    DumpEnd;
755    return HOK;
756 }
757 // ======================================================== mergeVertices
758 int Document::mergeVertices (Vertex* v1, Vertex* v2)
759 {
760    DumpStart ("mergeVertices", v1 << v2);
761
762    if (v1==v2 || v1==NULL || v1->isDeleted()
763               || v2==NULL || v2->isDeleted())
764       {
765       DumpEnd;
766       return HERR;
767       }
768
769    replaceVertex (v2, v1);
770
771    maj_connection = false;
772    DumpEnd;
773    return HOK;
774 }
775 // ======================================================== replaceVertex
776 void Document::replaceVertex (Vertex* old, Vertex* par)
777 {
778    DumpStart ("replaceVertex", old << par);
779    if (BadElement(old) || BadElement(par) ||  old==par)
780       {
781       DumpEnd;
782       return;
783       }
784
785    // par->replaceAssociation (old);   TODO
786
787    for (int type=EL_EDGE ; type <= EL_HEXA ; type++)
788        {
789        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
790                      elt = elt->next())
791            if (elt->isHere ())
792                elt->replaceVertex (old, par);
793        }
794    old->suppress ();
795    DumpEnd;
796 }
797 // ======================================================== replaceEdge
798 void Document::replaceEdge (Edge* old, Edge* par)
799 {
800    DumpStart ("replaceEdge", old << par);
801    if (BadElement(old) || BadElement(par) ||  old==par)
802       {
803       DumpEnd;
804       return;
805       }
806
807    // par->replaceAssociation (old);   TODO
808
809    for (int type=EL_QUAD ; type <= EL_HEXA ; type++)
810        {
811        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
812                      elt = elt->next())
813            if (elt->isHere ())
814                elt->replaceEdge (old, par);
815        }
816
817    old->suppress ();
818    DumpEnd;
819 }
820 // ======================================================== replaceQuad
821 void Document::replaceQuad (Quad* old, Quad* par)
822 {
823    DumpStart ("replaceQuad", old << par);
824    if (BadElement(old) || BadElement(par) ||  old==par)
825       {
826       DumpEnd;
827       return;
828       }
829
830    // par->replaceAssociation (old);   TODO
831
832    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
833                  elt = elt->next())
834        if (elt->isHere ())
835           {
836           Hexa* cell = static_cast <Hexa*> (elt);
837           cell->replaceQuad (old, par);
838           }
839    old->suppress ();
840 }
841 // ======================================================== prismQuad
842 Elements* Document::prismQuad  (Quad* qstart, Vector* dir, int nb)
843 {
844    DumpStart ("prismQuad", qstart << dir << nb);
845
846    Quads  tstart;
847    tstart.push_back (qstart);
848
849    update ();
850    Elements* prisme = prismQuads (tstart, dir, nb);
851
852    DumpReturn (prisme);
853    return      prisme;
854 }
855 // ======================================================== prismQuads
856 Elements* Document::prismQuads (Quads& tstart, Vector* dir, int nb)
857 {
858    DumpStart ("prismQuads", tstart << dir << nb);
859
860    Elements*  prisme = new Elements (this);
861
862    prisme->prismQuads (tstart, dir, nb);
863
864    DumpReturn (prisme);
865    return prisme;
866 }
867 // ======================================================== prismQuadsVec
868 Elements* Document::prismQuadsVec (Quads& tstart, Vector* dir, RealVector& tlen,
869                                    int crit)
870 {
871    DumpStart ("prismQuadVec", tstart << dir << tlen << crit);
872    Elements*  prisme = new Elements (this);
873    if (tlen.size()<=0) return prisme;
874
875    prisme->prismQuadsVec (tstart, dir, tlen, crit);
876
877    DumpReturn (prisme);
878    return prisme;
879 }
880 // ======================================================== joinQuads
881 Elements* Document::joinQuads (Quads& tstart, Quad* dest, Vertex* v1,
882                                Vertex* v2, Vertex* v3, Vertex* v4, int nb)
883 {
884    DumpStart ("joinQuads", tstart << dest << v1 << v2 << v3 << v4 << nb);
885    update ();
886    Elements*  joint = new Elements (this);
887    if (nb<=0)      return joint;
888
889    int ier = joint->joinQuads (tstart, nb, v1, v2, v3, v4, dest);
890    if (ier !=HOK)
891       printf ("\n ****\n **** Error in joinQuad(s)\n ****\n");
892
893    DumpReturn (joint);
894    return joint;
895 }
896 // ======================================================== joinQuad
897 Elements* Document::joinQuad (Quad* qstart, Quad* dest, Vertex* v1,
898                               Vertex* v2,  Vertex* v3, Vertex* v4, int nb)
899 {
900    DumpStart ("joinQuad", qstart << dest << v1 << v2 << v3 << v4 << nb);
901
902    Quads  tstart;
903    tstart.push_back (qstart);
904
905    Elements* joint = joinQuads (tstart, dest, v1, v2, v3, v4, nb);
906
907    DumpReturn (joint);
908    return    joint;
909 }
910 // ========================================================== getHexa
911 Hexa* Document::getHexa (int nro)
912 {
913    return static_cast <Hexa*> (getElement (EL_HEXA, nro));
914 }
915 // ========================================================== getQuad
916 Quad* Document::getQuad (int nro)
917 {
918    return static_cast <Quad*> (getElement (EL_QUAD, nro));
919 }
920 // ========================================================== getEdge
921 Edge* Document::getEdge (int nro)
922 {
923    return static_cast <Edge*> (getElement (EL_EDGE, nro));
924 }
925 // ========================================================== getVertex
926 Vertex* Document::getVertex (int nro)
927 {
928    return static_cast <Vertex*> (getElement (EL_VERTEX, nro));
929 }
930 // ========================================================== countElement
931 int Document::countElement (EnumElt type)
932 {
933    int compteur = 0;
934    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
935                  elt = elt->next())
936        if (elt->isHere())
937           compteur ++;
938
939    return compteur;
940 }
941 // ========================================================== getElement
942 EltBase* Document::getElement (EnumElt type, int nro)
943 {
944    int compteur = 0;
945    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
946                  elt = elt->next())
947        {
948        if (elt->isHere())
949           {
950           if (compteur>=nro)
951              return elt;
952           compteur ++;
953           }
954        }
955    return NULL;
956 }
957 // ========================================================= addLaw
958 Law* Document::addLaw (const char* name, int nbnodes)
959 {
960    DumpStart ("addLaw", name << nbnodes);
961    Law* loi = new Law (this, name, nbnodes);
962    addLaw (loi);
963    DumpReturn (loi);
964    return loi;
965 }
966 // ========================================================= addLaw
967 Law* Document::addLaw (Law* loi)
968 {
969    doc_laws.push_back (loi);
970    nbr_laws ++;
971    return loi;
972 }
973 // ========================================================= GetLaw
974 Law* Document::getLaw (int nro)
975 {
976    if (nro <0 || nro>= nbr_laws)
977       return NULL;
978
979    return doc_laws [nro];
980 }
981 // ========================================================= FindLaw
982 Law* Document::findLaw (const char* name)
983 {
984    string nom = name;
985    for (int nro=0 ; nro<nbr_laws; nro++)
986        if (doc_laws [nro]->getName() == nom)
987           return doc_laws [nro];
988
989    return NULL;
990 }
991 // ========================================================= removeLaw
992 int Document::removeLaw (Law* loi)
993 {
994    for (int nro=1 ; nro<nbr_laws; nro++)
995        if (doc_laws [nro] == loi)
996           {
997           //All propagations having this law should now have the default law.
998           for (int nl=0 ; nl<nbr_propagations ; nl++)
999               {
1000               if ( doc_propagation [nl]->getLaw() == loi )
1001                    doc_propagation [nl]->setLaw(defaultLaw);
1002               }
1003
1004           delete doc_laws [nro];
1005           doc_laws.erase (doc_laws.begin()+nro);
1006           nbr_laws = doc_laws.size();
1007           return HOK;
1008           }
1009
1010    return HERR;
1011 }
1012 // ========================================================= majPropagation
1013 void Document::majPropagation ()
1014 {
1015    DumpLock;
1016    majReferences ();
1017    update ();
1018    // if (purge_elements)
1019        // purge ();
1020
1021    for (int nro=0 ; nro<nbr_propagations ; nro++)
1022        {
1023        delete doc_propagation [nro];
1024        }
1025
1026    doc_propagation.clear ();
1027    nbr_propagations = 0;
1028    maj_propagation  = false;
1029
1030    for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); elt!=NULL;
1031                  elt = elt->next())
1032        {
1033        Edge* arete = static_cast <Edge*> (elt);
1034        if (arete!=NULL)
1035            arete->setPropag (NOTHING, true);
1036        }
1037
1038    //  markAll (NO_COUNTED, EL_EDGE);
1039
1040    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
1041                  elt = elt->next())
1042        {
1043        Hexa* cell = static_cast <Hexa*> (elt);
1044        if (cell!=NULL && cell->isHere())
1045           {
1046           for (int ne=0 ; ne<HE_MAXI ; ne++)
1047               {
1048               Edge* arete = cell->getEdge(ne);
1049               if (arete->getPropag()<0)
1050                  {
1051                  Propagation* prop = new Propagation ();
1052                  doc_propagation.push_back (prop);
1053                  arete->propager (prop, nbr_propagations);
1054                  nbr_propagations ++;
1055                  prop->majLaw();
1056                  }
1057               }
1058           }
1059        }
1060    DumpRestore;
1061 }
1062 // ======================================================== countPropagation
1063 int Document::countPropagation ()
1064 {
1065    if (maj_propagation)
1066        majPropagation ();
1067
1068    return nbr_propagations;
1069 }
1070 // ======================================================== getPropagation
1071 Propagation* Document::getPropagation (int nro)
1072 {
1073    if (maj_propagation)
1074        majPropagation ();
1075
1076    if (nro < 0 || nro >= nbr_propagations)
1077        return NULL;
1078
1079    return doc_propagation [nro];
1080 }
1081 // ======================================================== findPropagation
1082 Propagation* Document::findPropagation (Edge* arete)
1083 {
1084    if (arete==NULL)
1085        return NULL;
1086
1087    if (maj_propagation)
1088        majPropagation ();
1089
1090    return getPropagation (arete->getPropag ());
1091 }
1092 // ======================================================== disconnectQuad
1093 Elements* Document::disconnectQuad (Hexa* cell, Quad* element)
1094 {
1095    if (cell==NULL || element==NULL)
1096       return NULL;
1097
1098    update ();
1099    Elements* crees = cell->disconnectQuad (element);
1100
1101    if (crees!=NULL)
1102        majReferences ();
1103
1104    return crees;
1105 }
1106 // ======================================================== disconnectEdge
1107 Elements* Document::disconnectEdge (Hexa* cell, Edge* element)
1108 {
1109    if (cell==NULL || element==NULL)
1110       return NULL;
1111
1112    update ();
1113    Elements* crees = cell->disconnectEdge (element);
1114
1115    if (crees!=NULL)
1116        majReferences ();
1117    return crees;
1118 }
1119 // ======================================================== disconnectVertex
1120 Elements* Document::disconnectVertex (Hexa* cell, Vertex* element)
1121 {
1122    if (cell==NULL || element==NULL)
1123       return NULL;
1124
1125    update ();
1126    Elements* crees = cell->disconnectVertex (element);
1127
1128    if (crees!=NULL)
1129        majReferences ();
1130    return crees;
1131 }
1132 // ======================================================== cut
1133 Elements* Document::cut (Edge* edge, int nbcuts)
1134 {
1135    Elements* t_hexas = new Elements (this);
1136
1137    if (edge==NULL || nbcuts<=0)
1138       return t_hexas;
1139
1140    Propagation* prop    = findPropagation (edge);
1141    const Edges& t_edges = prop->getEdges ();
1142
1143    t_hexas->cutHexas (t_edges, nbcuts);
1144
1145    majPropagation ();
1146    return t_hexas;
1147 }
1148 // ======================================================== addGroup
1149 Group* Document::addGroup (cpchar name, EnumGroup kind)
1150 {
1151    Group* grp = new Group (name, kind);
1152    doc_group.push_back (grp);
1153    return grp;
1154 }
1155 // ======================================================== findGroup
1156 Group* Document::findGroup (cpchar name)
1157 {
1158    int nbre = doc_group.size();
1159
1160    for (int ng=0 ; ng<nbre ; ng++)
1161        if (Cestegal (doc_group [ng]->getName(), name))
1162           return doc_group [ng];
1163
1164    return NULL;
1165 }
1166 // ======================================================== removeGroup
1167 int Document::removeGroup (Group* grp)
1168 {
1169    int nbre = doc_group.size();
1170    for (int ng=0 ; ng<nbre ; ng++)
1171        {
1172        if (grp == doc_group [ng])
1173           {
1174           doc_group.erase (doc_group.begin() + ng);
1175           delete grp;
1176           return HOK;
1177           }
1178        }
1179                       // Pas trouve dans la liste. On detruit quand meme
1180    delete grp;
1181    return HERR;
1182 }
1183 // ======================================================== makeCylinder
1184 Elements* Document::makeCylinder (Cylinder* cyl, Vector* base, int nr, int na,
1185                                                                        int nl)
1186 {
1187    DumpStart ("makeCylinder", cyl << base << nr << na << nl);
1188
1189    Elements* grille = new Elements (this);
1190    grille->makeCylinder (cyl, base, nr, na, nl);
1191
1192    DumpReturn (grille);
1193    return grille;
1194 }
1195 // ======================================================== makeCylinders
1196 CrossElements* Document::makeCylinders (Cylinder* cyl1, Cylinder* cyl2)
1197 {
1198    DumpStart ("makeCylinders", cyl1 << cyl2 );
1199
1200    CrossElements* grille = new CrossElements (this, GR_BICYL);
1201    grille->crossCylinders (cyl1, cyl2, true);
1202
1203    DumpReturn (grille);
1204    return grille;
1205 }
1206
1207 // ======================================================== makePipe
1208 Elements* Document::makePipe (Pipe* pipe, Vector* bx, int nr, int na, int nl)
1209 {
1210    DumpStart ("makePipe",
1211         pipe << bx << nr << na << nl);
1212
1213    Elements* grille = new Elements (this);
1214    grille->makePipe (pipe, bx, nr, na, nr);
1215
1216    DumpReturn (grille);
1217    return grille;
1218 }
1219 // ======================================================== makePipes
1220 CrossElements* Document::makePipes (Pipe* pipe1, Pipe* pipe2)
1221 {
1222    DumpStart ("makePipes",
1223         pipe1 << pipe2);
1224
1225    CrossElements* grille = new CrossElements (this, GR_BIPIPE);
1226    grille->crossCylinders (pipe1, pipe2, false);
1227
1228    DumpReturn (grille);
1229    return grille;
1230 }
1231 // ======================================================== setName
1232 int Document::setName (cpchar prefix)
1233 {
1234    if (Cestvide (prefix) || el_name==prefix)
1235        return HERR;
1236
1237    string name = prefix;
1238    if (hex_parent != NULL)
1239        hex_parent->makeName (prefix, name);
1240
1241    el_name = name;
1242    return HOK ;
1243 }
1244 // ======================================================== setLevel
1245
1246 #ifdef  NO_CASCADE
1247 #define _TEST_BIC
1248 #endif
1249
1250 class BiCylinder;
1251
1252 BiCylinder* test_bicylinder (Document* docu, int option);
1253 void        set_debug_asso  (bool boule);
1254
1255 void Document::setLevel (int niv)
1256 {
1257    if (niv == 747)
1258       checkAssociations ();
1259    else if (niv == 748)
1260       {
1261       int nbshapes = countShape ();
1262       for (int nsh=0 ; nsh < nbshapes ; nsh++)
1263           {
1264           doc_tab_shape[nsh]->saveBrep();
1265           }
1266       }
1267    else if (niv == 777)
1268       set_special_option (true);
1269    else if (niv == 778)
1270       set_special_option (false);
1271 #ifdef _TEST_BICYL
1272    else if (niv >=90 && niv <=99)
1273       test_bicylinder (this, niv-90);
1274 #endif
1275    else
1276       {
1277       doc_db = niv;
1278       set_debug_asso (niv>0);
1279       }
1280 }
1281 #if 0
1282 // ======================================================== getAssoVertices
1283 void Document::getAssoVertices (Vertices& tabelt)
1284 {
1285    tabelt.clear ();
1286    for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
1287                  elt = elt->next())
1288        if (elt->isHere() && elt->getAssociation()!=NULL)
1289           tabelt.push_back (static_cast <Vertex*> (elt));
1290 }
1291 // ======================================================== getAssoEdges
1292 void Document::getAssoEdges (Edges& tabelt)
1293 {
1294    tabelt.clear ();
1295    for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); elt!=NULL;
1296                  elt = elt->next())
1297        if (elt->isHere())
1298           {
1299           Edge* edge = static_cast <Edge*> (elt);
1300           int nbass  = edge->getAssociations().size();
1301           if (nbass>0)
1302               tabelt.push_back (edge);
1303           }
1304 }
1305 #endif
1306 // ======================================================== makeVarName
1307 char* Document::makeVarName (char* name)
1308 {
1309    strcpy (name, doc_ident);
1310    return doc_ident ;
1311 }
1312 // ======================================================== isEmpty
1313 bool Document::isEmpty ()
1314 {
1315    int nombre = countVertex () + countVector ()
1316                                + countCylinder() + countPipe();
1317    return nombre <= 0 && countLaw  () <= 1;
1318 }
1319 // ======================================================== getNextName
1320 cpchar Document::getNextName (EnumElt type, string& buff)
1321 {
1322    char name [8];
1323    EltBase::makeName (type, doc_nbr_elt [type], name);
1324
1325    buff = name;
1326    return buff.c_str();
1327 }
1328
1329 // ======================================================== getNextName
1330 string Document::getNextName (EnumElt type)
1331 {
1332    char name [8];
1333    EltBase::makeName (type, doc_nbr_elt [type], name);
1334
1335    return string(name);
1336 }
1337
1338 // ======================================================== lockDump
1339 void Document::lockDump ()
1340 {
1341    glob->dump.lock ();
1342 }
1343 // ======================================================== restoreDump
1344 void Document::restoreDump ()
1345 {
1346    glob->dump.restore (DumpActif);
1347 }
1348 // ======================================================== getGroup
1349 Group* Document::getGroup (int nro)
1350 {
1351    int size = doc_group.size();
1352    if (nro>=0 && nro<size)
1353       return doc_group [nro];
1354    else
1355       return NULL;
1356 }
1357 // ======================================================== getVector
1358 Vector* Document::getVector (int nro)
1359 {
1360    int size = doc_vector.size();
1361    if (nro>=0 && nro<size)
1362       return doc_vector [nro];
1363    else
1364       return NULL;
1365 }
1366 // ======================================================== getCylinder
1367 Cylinder* Document::getCylinder (int nro)
1368 {
1369    int size = doc_cylinder.size();
1370    if (nro>=0 && nro<size)
1371       return doc_cylinder [nro];
1372    else
1373       return NULL;
1374 }
1375 // ======================================================== getPipe
1376 Pipe* Document::getPipe (int nro)
1377 {
1378    int size = doc_pipe.size();
1379    if (nro>=0 && nro<size)
1380       return doc_pipe [nro];
1381    else
1382       return NULL;
1383 }
1384
1385 // ======================================================== makeBiCylinder
1386 BiCylinder* Document::makeBiCylinder (Cylinder* cyl1, Cylinder* cyl2)
1387 {
1388    DumpStart ("makeBiCylinder", cyl1 << cyl2 );
1389
1390    BiCylinder* grille = new BiCylinder (this);
1391    grille->crossCylinders (cyl1, cyl2);
1392
1393    DumpReturn (grille);
1394    return grille;
1395 }
1396 // ======================================================== makeBiPipe
1397 BiCylinder* Document::makeBiPipe (Pipe* pipe1, Pipe* pipe2)
1398 {
1399    DumpStart ("makeBiPipe", pipe1 << pipe2);
1400
1401    BiCylinder* grille = new BiCylinder (this);
1402    grille->crossCylinders (pipe1, pipe2);
1403
1404    DumpReturn (grille);
1405    return grille;
1406 }
1407 END_NAMESPACE_HEXA