Salome HOME
5a1e00c97fb0ef7b941bba909d6e92693af5ad99
[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/
21 //  or email : webmaster.salome@opencascade.com
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
34 #include "HexVector.hxx"
35 #include "HexMatrix.hxx"
36 #include "HexCloner.hxx"
37 #include "HexPropagation.hxx"
38 #include "HexLaw.hxx"
39
40 #include "HexXmlWriter.hxx"
41 #include "HexXmlTree.hxx"
42 #include "HexGlobale.hxx"
43 #include "HexGroup.hxx"
44 #include "Hex.hxx"
45 #include "HexNewShape.hxx"
46
47 void test_six (Hex::Document* docu, int option);
48
49 BEGIN_NAMESPACE_HEXA
50
51 int Document::doc_number = 0;
52
53 // ======================================================== Constructeur
54 Document::Document (cpchar name, Hex* dad)
55 {
56    el_name    = name;
57    hex_parent = dad;
58    glob       = Globale::getInstance ();
59    el_root    = this;
60
61    doc_db        = 0;
62    nbr_errors    = 0;
63    doc_modified  = true;
64    doc_saved     = false;
65    doc_tolerance = 1e-6;
66    nbr_laws      = 0;
67    nbr_propagations = 0;
68    maj_propagation  = true;
69    doc_xml          = NULL;
70
71    nbr_used_hexas = nbr_used_quads = nbr_used_edges = nbr_used_vertex = 0;
72
73    for (EnumElt type = EL_NONE ; type < EL_MAXI ; type=(EnumElt) (type+1))
74        {
75        doc_first_elt [type] = doc_last_elt [type] = new EltBase ();
76        doc_nbr_elt   [type] = 0;
77        }
78
79    if (doc_number == 0)
80       strcpy (doc_ident, "doc");
81    else
82       sprintf (doc_ident, "doc%02d", doc_number);
83    doc_number++;
84
85    DumpLock;
86    defaultLaw = addLaw ("DefaultLaw", 0);
87    DumpRestore;
88
89    maj_connection = false;
90    purge_elements = false;
91    holes_elements = false;
92    addCloud ();
93 }
94 // ======================================================== Destructeur
95 Document::~Document ()
96 {
97    delete doc_xml;
98
99    for (EnumElt type = EL_NONE ; type < EL_MAXI ; type=(EnumElt) (type+1))
100        {
101        //  printf ("____________________________ Type=%d\n", type);
102        EltBase* next = NULL;
103        for (EltBase* elt=doc_first_elt [type] ; elt != NULL ; elt=next)
104            {
105            next = elt->next();
106            delete elt;
107            }
108        }
109 }
110 // ======================================================== addVector
111 Vector* Document::addVector (double dx, double dy, double dz)
112 {
113    DumpStart ("addVector", dx  << dy  << dz);
114    Vector* pv = new Vector (this, dx, dy, dz);
115    doc_vector.push_back (pv);
116
117    DumpReturn (pv);
118    return  pv;
119 }
120 // ======================================================== addVectorVertices
121 Vector* Document::addVectorVertices (Vertex* va, Vertex* vb)
122 {
123    DumpStart ("addVectorVertices", va  << vb);
124
125    Vector* pv = addVector (vb->getX () - va->getX (),
126                            vb->getY () - va->getY (),
127                            vb->getZ () - va->getZ ());
128
129    DumpReturn (pv);
130    return  pv;
131 }
132 // ======================================================== addVertex
133 Vertex* Document::addVertex (double x, double y, double z)
134 {
135    DumpStart ("addVertex", x  << y  << z);
136
137    Vertex* pv   = new Vertex (this, x, y, z);
138    DumpReturn (pv);
139    return pv;
140 }
141 // ======================================================== addEdge
142 Edge* Document::addEdge (Vertex* va, Vertex* vb)
143 {
144    DumpStart ("addEdge", va  << vb );
145
146    if (va==NULL || vb==NULL)
147       return NULL;
148
149    Edge* arete  = new Edge (va, vb);
150    DumpReturn (arete);
151    return arete;
152 }
153 // ======================================================== addEdgeVector
154 Edge* Document::addEdgeVector (Vertex* va, Vector* vec)
155 {
156    DumpStart ("addEdgeVector", va  << vec );
157
158    Vertex* vb   = addVertex (va->getX () + vec->getDx(),
159                              va->getY () + vec->getDy(),
160                              va->getZ () + vec->getDz());
161
162    Edge*  arete = addEdge (va, vb);
163    DumpReturn (arete);
164    return arete;
165 }
166 // ======================================================== addQuadVertices
167 Quad* Document::addQuadVertices (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd)
168 {
169    DumpStart ("addQuadVertices", va << vb << vc << vd );
170
171    Quad*  face   = new Quad (va, vb, vc, vd);
172    DumpReturn (face);
173    return face;
174 }
175 // ======================================================== addQuad
176 Quad* Document::addQuad (Edge* ea, Edge* eb, Edge* ec, Edge* ed)
177 {
178    DumpStart ("addQuad", ea << eb << ec << ed );
179
180    Quad*  face   = new Quad (ea, eb, ec, ed);
181    DumpReturn (face);
182    return face;
183 }
184 // ======================================================== addHexaVertices
185 Hexa* Document::addHexaVertices (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd,
186                                  Vertex* ve, Vertex* vf, Vertex* vg, Vertex* vh)
187 {
188    DumpStart ("addHexaVertices", va << vb << vc << vd << ve << vf << vg << vh);
189
190    Hexa*  pave   = new Hexa (va, vb, vc, vd, ve, vf, vg, vh);
191    DumpReturn (pave);
192    return pave;
193 }
194 // ======================================================== addHexa
195 Hexa* Document::addHexa (Quad* qa, Quad* qb, Quad* qc, Quad* qd, Quad* qe,
196                          Quad* qf)
197 {
198    DumpStart ("addHexa", qa << qb << qc << qd << qe << qf );
199
200    Hexa*  pave   = new Hexa (qa, qb, qc, qd, qe, qf);
201    DumpReturn (pave);
202    return pave;
203 }
204 // ======================================================== findVertex
205 Vertex* Document::findVertex (double vx, double vy, double vz)
206 {
207    DumpStart ("findVertex", vx << vy << vz);
208    Vertex* found = NULL;
209
210    double xmin = vx - doc_tolerance;
211    double xmax = vx + doc_tolerance;
212    double ymin = vy - doc_tolerance;
213    double ymax = vy + doc_tolerance;
214    double zmin = vz - doc_tolerance;
215    double zmax = vz + doc_tolerance;
216  
217    for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); 
218                  elt!= NULL && found == NULL ;
219                  elt = elt->next())
220        {
221        if (elt->isHere())
222           {
223           Vertex* candidat = static_cast <Vertex*> (elt);
224           if (candidat->isin (xmin, xmax, ymin, ymax, zmin, zmax))
225              found = candidat;
226           }
227        }
228
229    DumpReturn (found);
230    return found;
231 }
232 // ======================================================== findEdge
233 Edge* Document::findEdge (Vertex* v1, Vertex* v2)
234 {
235    DumpStart ("findEdge", v1 << v2);
236    Edge* found = NULL;
237
238    for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); 
239                  elt!= NULL && found == NULL ;
240                  elt = elt->next())
241        {
242        Edge* candidat  = static_cast <Edge*> (elt);
243        if (candidat->definedBy (v1, v2))
244           found = candidat;
245        }
246
247    DumpReturn (found);
248    return found;
249 }
250 // ======================================================== findQuad
251 Quad* Document::findQuad (Vertex* v1, Vertex* v2)
252 {
253    DumpStart ("findQuad", v1 << v2);
254    Quad* found = NULL;
255
256    for (EltBase* elt = doc_first_elt[EL_QUAD]->next (); 
257                  elt!= NULL && found == NULL ;
258                  elt = elt->next())
259        {
260        Quad* candidat  = static_cast <Quad*> (elt);
261        if (candidat->definedBy (v1, v2))
262           found = candidat;
263        }
264
265    DumpReturn (found);
266    return found;
267 }
268 // ======================================================== findQuad
269 Quad* Document::findQuad (Edge* e1, Edge* e2)
270 {
271    DumpStart ("findQuad", e1 << e2);
272    Quad* found = NULL;
273
274    for (EltBase* elt = doc_first_elt[EL_QUAD]->next (); 
275                  elt!= NULL && found == NULL ;
276                  elt = elt->next())
277        {
278        Quad* candidat  = static_cast <Quad*> (elt);
279        if (candidat->definedBy (e1, e2))
280           found = candidat;
281        }
282
283    DumpReturn (found);
284    return found;
285 }
286 // ======================================================== findHexa
287 Hexa* Document::findHexa (Vertex* v1, Vertex* v2)
288 {
289    DumpStart ("findHexa", v1 << v2);
290    Hexa* found = NULL;
291
292    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); 
293                  elt!= NULL && found == NULL ;
294                  elt = elt->next())
295        {
296        Hexa* candidat  = static_cast <Hexa*> (elt);
297        if (candidat->definedBy (v1, v2))
298           found = candidat;
299        }
300
301    DumpReturn (found);
302    return found;
303 }
304 // ======================================================== findElement
305 EltBase* Document::findElement (EnumElt type, int ident)
306 {
307    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
308                  elt = elt->next())
309        {
310        if (elt->isHere() && elt->getId()==ident)
311           return elt;
312        }
313    return NULL;
314 }
315 // ======================================================== findVertex
316 Vertex* Document::findVertex (int ident)
317 {
318    Vertex* node = static_cast <Vertex*> (findElement (EL_VERTEX, ident));
319    return  node;
320
321 }
322 // ======================================================== index_tv
323 int index_tv (Vertex* table[], Vertex* elt)
324 {
325    for (int nro=0; nro<QUAD4; nro++)
326         if (elt == table[nro])
327            return nro;
328
329    return NOTHING;
330 }
331 // ======================================================== mergeQuads
332 int Document::mergeQuads (Quad* dest, Quad* orig, Vertex* v1, Vertex* v2,
333                                                 Vertex* v3, Vertex* v4)
334 {
335    DumpStart ("mergeQuads", dest << orig << v1 << v2  << v3 << v4);
336
337    update ();
338
339    if (dest==orig)
340       {
341       printf (" *** Quads identiques dans mergeQuads\n");
342       DumpEnd;
343       return HERR;
344       }
345    else if (dest==NULL || dest->isDeleted())
346       {
347       printf (" *** Quad nro 1 incorrect dans mergeQuads \n");
348       DumpEnd;
349       return HERR;
350       }
351    else if (orig==NULL || orig->isDeleted() )
352       {
353       printf (" *** Quad nro 2 incorrect dans mergeQuads \n");
354       DumpEnd;
355       return HERR;
356       }
357
358    int nbcomm = 0;
359    for (int nro=0 ; nro<QUAD4 ; nro++)
360        {
361        int norig = orig->indexVertex (dest->getVertex(nro));
362        if (norig != NOTHING)
363           {
364           Vertex* uv = dest->getVertex(nro);
365           char nom[12];
366           nbcomm ++;
367           if (nbcomm==1)
368              {
369              printf ("  +++ Sommets communs dans mergeQuads");
370              printf (" (%s,",  dest->getName (nom));
371              printf (" %s)\n", orig->getName (nom));
372              }
373           printf ("  +++ quad1[%d] = quad2[%d] = %s\n", nro,  norig,
374                                                         uv->getName (nom));
375           }
376        }
377
378    if (nbcomm == 2)
379       {
380       printf ("  +++ Les vertex passes en arguments sont ignores\n");
381       int ier = closeQuads (dest, orig);
382       DumpEnd;
383       return ier;
384       }
385    else if (nbcomm != 0)
386       {
387       printf ("  *** _____________________ mergeQuads refuse: \n");
388       printf (" il y a %d sommet(s) sont commun(s)\n", nbcomm);
389       DumpEnd;
390       return HERR;
391       }
392
393    if (   v1 ==NULL || v1 ->isDeleted() || v2 ==NULL || v2 ->isDeleted()
394        || v3 ==NULL || v3 ->isDeleted() || v4 ==NULL || v4 ->isDeleted())
395       {
396       printf ("  *** _____________________ mergeQuads refuse: \n");
397       printf (" un sommet est incorrect\n");
398       DumpEnd;
399       return HERR;
400       }
401
402
403    if (debug())
404       {
405       printf ("  ----------------- mergeQuads : \n");
406       HexDump (orig);
407       HexDump (dest);
408       HexDump (v1);
409       HexDump (v2);
410       HexDump (v3);
411       HexDump (v4);
412       }
413
414    Vertex *tv1 [QUAD4], *tv2 [QUAD4];
415    Edge   *te1 [QUAD4], *te2 [QUAD4];
416
417    int ier1 = dest->ordoVertex (v1, v3, tv1);
418    int ier2 = orig->ordoVertex (v2, v4, tv2);
419    if (ier1 != HOK)
420       {
421       DumpEnd;
422       return ier1;
423       }
424    else if (ier2 != HOK)
425       {
426       DumpEnd;
427       return ier2;
428       }
429
430    for (int nro=0 ; nro<QUAD4 ; nro++)
431        {
432        te1 [nro] = dest->getEdge(nro);
433        Vertex* va1 = te1[nro]->getVertex(V_AMONT);
434        Vertex* vb1 = te1[nro]->getVertex(V_AVAL);
435        int na = index_tv  (tv1, va1);
436        int nb = index_tv  (tv1, vb1);
437        if (na==NOTHING || nb==NOTHING)
438           {
439           DumpEnd;
440           return HERR;
441           }
442
443        te2 [nro] = orig->findEdge (tv2[na], tv2[nb]);
444        if (te2[nro]==NULL)
445           {
446           DumpEnd;
447           return HERR;
448           }
449        }
450
451    if (debug())
452       {
453       printf ("  ----------------- Correspondances mergeQuads : \n");
454       for (int nro=0 ; nro<QUAD4 ; nro++)
455           {
456           printf ("  %d  : ", nro);
457           tv2 [nro]->printName(" -> ");
458           tv1 [nro]->printName("\n");
459           }
460       for (int nro=0 ; nro<QUAD4 ; nro++)
461           {
462           printf ("  %d  : ", nro);
463           te2 [nro]->printName(" (");
464           te2 [nro]->getVertex(0)->printName(", ");
465           te2 [nro]->getVertex(1)->printName(") -> ");
466           te1 [nro]->printName(" (");
467           te1 [nro]->getVertex(0)->printName(", ");
468           te1 [nro]->getVertex(1)->printName(")\n");
469           }
470       }
471
472    replaceQuad (orig, dest);
473    for (int nro=0 ; nro<QUAD4 ; nro++)
474        replaceEdge   (te2[nro], te1[nro]);
475    for (int nro=0 ; nro<QUAD4 ; nro++)
476        replaceVertex (tv2[nro], tv1[nro]);
477
478    maj_connection = false;
479    purge_elements = false;
480
481    DumpEnd;
482    return HOK;
483 }
484 // ======================================================== closeQuads
485 int Document::closeQuads (Quad* dest, Quad* orig)
486 {
487    DumpStart ("closeQuads", dest << orig);
488
489    update ();
490    char nom[12];
491
492    if (dest==orig)
493       {
494       printf (" *** Quads identiques dans closeQuads : %s\n",
495                  dest->getName(nom));
496       DumpEnd;
497       return HERR;
498       }
499    else if (dest==NULL || dest->isDeleted())
500       {
501       printf (" *** Quad nro 1 incorrect dans closeQuads \n");
502       DumpEnd;
503       return HERR;
504       }
505    else if (orig==NULL || orig->isDeleted() )
506       {
507       printf (" *** Quad nro 2 incorrect dans closeQuads \n");
508       DumpEnd;
509       return HERR;
510       }
511
512    Edge* edc = NULL;
513    for (int nro=0 ; nro<QUAD4 ; nro++)
514        {
515        int norig = orig->indexEdge (dest->getEdge(nro));
516        if (norig != NOTHING)
517           {
518           if (edc != NULL)
519              {
520              printf ("  *** Plus d'une arete commune dans closeQuads");
521              printf (" (%s,",  dest->getName (nom));
522              printf (" %s)\n", orig->getName (nom));
523              DumpEnd;
524              return HERR;
525              }
526           edc = dest->getEdge (nro);
527           printf ("  +++ quad1[%d] = quad2[%d] = %s\n", nro,  norig,
528                                                         edc->getName (nom));
529           }
530        }
531
532    Vertex* va = edc->getVertex (V_AMONT);
533    Vertex* vb = edc->getVertex (V_AVAL);
534    Vertex *tv1 [QUAD4], *tv2 [QUAD4];
535    Edge   *te1 [QUAD4], *te2 [QUAD4];
536
537    int ier1 = dest->ordoVertex (va, vb, tv1);
538    int ier2 = orig->ordoVertex (va, vb, tv2);
539
540    if (ier1 != HOK)
541       {
542       DumpEnd;
543       return ier1;
544       }
545    else if (ier2 != HOK)
546       {
547       DumpEnd;
548       return ier2;
549       }
550
551    for (int nro=0 ; nro<QUAD4 ; nro++)
552        {
553        te1 [nro] = dest->getEdge(nro);
554        Vertex* va1 = te1[nro]->getVertex(V_AMONT);
555        Vertex* vb1 = te1[nro]->getVertex(V_AVAL);
556        int na = index_tv  (tv1, va1);
557        int nb = index_tv  (tv1, vb1);
558        if (na==NOTHING || nb==NOTHING)
559           {
560           DumpEnd;
561           return HERR;
562           }
563
564        te2 [nro] = orig->findEdge (tv2[na], tv2[nb]);
565        if (te2[nro]==NULL)
566           {
567           DumpEnd;
568           return HERR;
569           }
570        }
571
572    if (debug())
573       {
574       printf ("  ----------------- Correspondances mergeQuads : \n");
575       for (int nro=0 ; nro<QUAD4 ; nro++)
576           {
577           printf ("  %d  : ", nro);
578           tv2 [nro]->printName(" -> ");
579           tv1 [nro]->printName("\n");
580           }
581       for (int nro=0 ; nro<QUAD4 ; nro++)
582           {
583           printf ("  %d  : ", nro);
584           te2 [nro]->printName(" (");
585           te2 [nro]->getVertex(0)->printName(", ");
586           te2 [nro]->getVertex(1)->printName(") -> ");
587           te1 [nro]->printName(" (");
588           te1 [nro]->getVertex(0)->printName(", ");
589           te1 [nro]->getVertex(1)->printName(")\n");
590           }
591       }
592
593    replaceQuad (orig, dest);
594    for (int nro=0 ; nro<QUAD4 ; nro++)
595        replaceEdge   (te2[nro], te1[nro]);
596    for (int nro=0 ; nro<QUAD4 ; nro++)
597        replaceVertex (tv2[nro], tv1[nro]);
598
599    maj_connection = false;
600    purge_elements = false;
601
602    DumpEnd;
603    return HOK;
604 }
605 // ======================================================== mergeEdges
606 int Document::mergeEdges (Edge* e1, Edge* e2, Vertex* v1, Vertex* v2)
607 {
608    DumpStart ("mergeEdges", e1 << e2 << v1 << v2);
609
610    if (e1==NULL || e1->isDeleted() || e2==NULL || e2->isDeleted())
611       {
612       DumpEnd;
613       return HERR;
614       }
615
616    for (int nro=0 ; nro<V_TWO ; nro++)
617        if (e1->index (e2->getVertex(nro))!= NOTHING)
618           {
619           DumpEnd;
620           return HERR+nro+1;
621           }
622
623    Vertex *tv1 [V_TWO], *tv2 [V_TWO];
624
625    int ier1 = e1->anaMerge (v1, tv1);
626    int ier2 = e2->anaMerge (v2, tv2);
627
628    if (ier1 != HOK)
629       {
630       DumpEnd;
631       return ier1;
632       }
633    else if (ier2 != HOK)
634       {
635       DumpEnd;
636       return ier2;
637       }
638
639    replaceEdge (e2, e1);
640    for (int nro=0 ; nro<V_TWO ; nro++)
641        replaceVertex (tv2[nro], tv1[nro]);
642
643    maj_connection = false;
644    DumpEnd;
645    return HOK;
646 }
647 // ======================================================== mergeVertices
648 int Document::mergeVertices (Vertex* vpar, Vertex* vold)
649 {
650    DumpStart ("mergeVertices", vpar << vold);
651
652    int ier = HOK;
653    if (BadElement (vpar))
654       {
655       Mess << "First vertex is not valid";
656       ier = HERR;
657       }
658    else if (BadElement (vold))
659       {
660       Mess << "Second vertex is not valid";
661       ier = HERR;
662       }
663    else if (vpar==vold)
664       {
665       Mess << "Vertices are identical";
666       ier = HERR;
667       }
668    else if (EltIsValid (findEdge (vpar, vold)))
669       {
670       Mess << "Theese vertices are connected by an edge";
671       ier = HERR;
672       }
673
674    if (ier != HOK)
675       {
676       DumpEnd;
677       return ier;
678       }
679
680    map <Quad*,   Quad*>   rep_quad;
681    map <Edge*,   Edge*>   rep_edge;
682    map <Vertex*, Vertex*> rep_vertex;
683
684    map <Quad*,   Quad*>   :: iterator itq;
685    map <Edge*,   Edge*>   :: iterator ited;
686    map <Vertex*, Vertex*> :: iterator itv;
687    
688    rep_vertex [vold] = vpar;
689    int nbparv  = vold->getNbrParents ();
690
691    for (int ned=0 ; ned<nbparv ; ++ned)
692        {
693        Edge* edold = vold->getParent (ned);
694        if (edold->isHere())
695           {
696           Vertex* vopp  = edold->opposedVertex (vold);
697           Edge*   edpar = findEdge (vpar, vopp);
698           if (edpar != NULL)
699              rep_edge [edold] = edpar;
700           }
701        }
702
703    Quad *qold=NULL,  *qpar=NULL;
704
705    for (ited=rep_edge.begin(); ited!=rep_edge.end() ; ++ited)
706        {
707        Edge* edold = ited->first;
708        Edge* edpar = ited->second;
709        int nbpared = edold->getNbrParents ();
710        for (int nq=0 ; nq<nbpared ; ++nq)
711            {
712            qold = edold->getParent (nq);
713            if (qold->isHere())
714               {
715               for (int ned=0 ; ned<QUAD4 ; ned++)
716                   {
717                   // Edge* edge = quad->getEdge(ned);
718                   Edge* edge = qold->getEdge (ned);
719                   if (edge != edold)
720                      {
721                      qpar = findQuad (edpar, edge);
722                      if (qpar != NULL)
723                         rep_quad [qold] = qpar;
724                      }
725                   }
726               }
727            }
728        }
729
730    cout << " +++ Intersection : veq = "   << rep_vertex.size() 
731         << " " << rep_edge.size() <<  " " << rep_quad.size()
732         << endl;
733
734    for (itq=rep_quad.begin(); itq!=rep_quad.end() ; ++itq)
735       {
736       qold = itq->first;
737       qpar = itq->second;
738       Vertex *tv1[QUAD4], *tv2[QUAD4];
739       Edge   *te1[QUAD4], *te2[QUAD4];
740       Edge*  einter = qpar->inter (qold);
741       if (einter!=NULL)
742          {
743          Vertex* va = einter->getVertex (V_AMONT);
744          Vertex* vb = einter->getVertex (V_AVAL);
745          qpar->ordonner (va, vb, tv1, te1); 
746          qold->ordonner (va, vb, tv2, te2); 
747          for (int nro=0 ; nro<QUAD4 ; nro++)
748              {
749              rep_edge   [te2[nro]] =  te1[nro];
750              rep_vertex [tv2[nro]] =  tv1[nro];
751              }
752          }
753       replaceQuad (qold, qpar);
754       }
755
756    for (ited=rep_edge.begin(); ited!=rep_edge.end() ; ++ited)
757         replaceEdge (ited->first, ited->second);
758        
759    for (itv=rep_vertex.begin(); itv!=rep_vertex.end() ; ++itv)
760         replaceVertex (itv->first, itv->second);
761        
762    maj_connection = false;
763    DumpEnd;
764    return HOK;
765 }
766 // ======================================================== replaceVertex
767 void Document::replaceVertex (Vertex* old, Vertex* par)
768 {
769    if (BadElement(old) || BadElement(par) ||  old==par)
770       return ;
771
772    // par->replaceAssociation (old);   TODO
773
774    for (int type=EL_EDGE ; type <= EL_HEXA ; type++)
775        {
776        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
777                      elt = elt->next())
778            if (elt->isHere ())
779                elt->replaceVertex (old, par);
780        }
781    old->suppress ();
782 }
783 // ======================================================== replaceEdge
784 void Document::replaceEdge (Edge* old, Edge* par)
785 {
786    if (BadElement(old) || BadElement(par) ||  old==par)
787       return;
788
789    // par->replaceAssociation (old);   TODO
790
791    for (int type=EL_QUAD ; type <= EL_HEXA ; type++)
792        {
793        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
794                      elt = elt->next())
795            if (elt->isHere ())
796                elt->replaceEdge (old, par);
797        }
798
799    old->suppress ();
800 }
801 // ======================================================== replaceQuad
802 int Document::replaceQuad (Quad* old, Quad* par)
803 {
804    if (BadElement(old) || BadElement(par) ||  old==par)
805       return HERR;
806
807    // par->replaceAssociation (old);   TODO
808
809    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
810                  elt = elt->next())
811        if (elt->isHere ())
812           {
813           Hexa* cell = static_cast <Hexa*> (elt);
814           cell->replaceQuad (old, par);
815           }
816    old->suppress ();
817    return HOK;
818 }
819 // ========================================================== countElement
820 int Document::countElement (EnumElt type)
821 {
822    int compteur = 0;
823    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
824                  elt = elt->next())
825        if (elt->isHere())
826           compteur ++;
827
828    return compteur;
829 }
830 // ========================================================== getElement
831 EltBase* Document::getElement (EnumElt type, int nro)
832 {
833    int compteur = 0;
834    for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
835                  elt = elt->next())
836        {
837        if (elt->isHere())
838           {
839           if (compteur>=nro)
840              return elt;
841           compteur ++;
842           }
843        }
844    return NULL;
845 }
846 // ========================================================= addLaw
847 Law* Document::addLaw (const char* name, int nbnodes)
848 {
849    DumpStart ("addLaw", name << nbnodes);
850    Law* loi = new Law (this, name, nbnodes);
851    addLaw (loi);
852    DumpReturn (loi);
853    return loi;
854 }
855 // ========================================================= addLaw
856 Law* Document::addLaw (Law* loi)
857 {
858    doc_laws.push_back (loi);
859    nbr_laws ++;
860    return loi;
861 }
862 // ========================================================= getLaw
863 Law* Document::getLaw (int nro)
864 {
865    DumpStart ("getLaw", nro);
866    Law* loi = NULL;
867
868    if (nro >= 0 && nro < nbr_laws)
869        loi =  doc_laws [nro];
870
871    DumpReturn (loi);
872    return loi;
873 }
874 // ========================================================= findLaw
875 Law* Document::findLaw (const char* name)
876 {
877    DumpStart ("findLaw", name);
878
879    string nom = name;
880    Law*   loi = NULL;
881
882    for (int nro=0 ;loi==NULL &&  nro<nbr_laws; nro++)
883        if (doc_laws [nro]->getName() == nom)
884           loi = doc_laws [nro];
885
886    DumpReturn (loi);
887    return loi;
888 }
889 // ========================================================= removeLaw
890 int Document::removeLaw (Law* loi)
891 {
892    DumpStart ("removeLaw", loi);
893
894    for (int nro=1 ; nro<nbr_laws; nro++)
895        if (doc_laws [nro] == loi)
896           {
897           //All propagations having this law should now have the default law.
898           for (int nl=0 ; nl<nbr_propagations ; nl++)
899               {
900               if ( doc_propagation [nl]->getLaw() == loi )
901                    doc_propagation [nl]->setLaw(defaultLaw);
902               }
903
904           // delete doc_laws [nro];
905           doc_laws [nro]->suppress ();
906           doc_laws.erase (doc_laws.begin()+nro);
907           nbr_laws = doc_laws.size();
908
909           DumpReturn (HOK);
910           return HOK;
911           }
912
913    DumpReturn (HERR);
914    return HERR;
915 }
916 // ========================================================= majPropagation
917 void Document::majPropagation ()
918 {
919    DumpLock;
920    majReferences ();
921    update ();
922    // if (purge_elements)
923        // purge ();
924
925    for (int nro=0 ; nro<nbr_propagations ; nro++)
926        {
927        // delete doc_propagation [nro];
928        // doc_propagation [nro]->suppress();
929        ;
930        }
931
932    doc_propagation.clear ();
933    nbr_propagations = 0;
934    maj_propagation  = false;
935
936    for (EltBase* elt = doc_first_elt[EL_EDGE]->next (); elt!=NULL;
937                  elt = elt->next())
938        {
939        Edge* arete = static_cast <Edge*> (elt);
940        if (arete!=NULL)
941            arete->setPropag (NOTHING, true);
942        }
943
944    //  markAll (NO_COUNTED, EL_EDGE);
945
946    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
947                  elt = elt->next())
948        {
949        Hexa* cell = static_cast <Hexa*> (elt);
950        if (cell!=NULL && cell->isHere())
951           {
952           for (int ne=0 ; ne<HE_MAXI ; ne++)
953               {
954               Edge* arete = cell->getEdge(ne);
955               if (arete->getPropag()<0)
956                  {
957                  Propagation* prop = new Propagation (this);
958                  doc_propagation.push_back (prop);
959                  arete->propager (prop, nbr_propagations);
960                  nbr_propagations ++;
961                  prop->majLaw();
962                  }
963               }
964           }
965        }
966    maj_propagation  = false;
967    DumpRestore;
968 }
969 // ======================================================== countPropagation
970 int Document::countPropagation ()
971 {
972    if (maj_propagation)
973        majPropagation ();
974
975    return nbr_propagations;
976 }
977 // ======================================================== getPropagation
978 Propagation* Document::getPropagation (int nro)
979 {
980    DumpStart ("getPropagation", nro);
981
982    if (maj_propagation)
983        majPropagation ();
984
985    Propagation* prop = NULL;
986    if (nro >= 0 && nro < nbr_propagations)
987        prop = doc_propagation [nro];
988
989    DumpReturn (prop);
990    return prop;
991 }
992 // ======================================================== findPropagation
993 Propagation* Document::findPropagation (Edge* arete)
994 {
995    DumpStart ("findPropagation", arete);
996
997    Propagation* prop = NULL;
998    if (arete!=NULL)
999       {
1000       if (maj_propagation)
1001           majPropagation ();
1002       prop = getPropagation (arete->getPropag ());
1003       }
1004
1005    DumpReturn (prop);
1006    return  prop;
1007 }
1008 // ======================================================== disconnectQuad
1009 Elements* Document::disconnectQuad (Hexa* cell, Quad* element)
1010 {
1011    DumpStart ("disconnectQuad", cell << element);
1012
1013    Elements* grid = new Elements (this);
1014    grid->checkDisco (cell, element);
1015
1016    if (grid->isValid())
1017       {
1018       update ();
1019       cell->disconnectQuad (element, grid);
1020       majReferences ();
1021       }
1022
1023    DumpReturn (grid);
1024    return grid;
1025 }
1026 // ======================================================== disconnectEdge
1027 Elements* Document::disconnectEdge (Hexa* cell, Edge* element)
1028 {
1029    DumpStart ("disconnectEdge", cell << element);
1030
1031    Elements* grid = new Elements (this);
1032    grid->checkDisco (cell, element);
1033
1034    if (grid->isValid())
1035       {
1036       update ();
1037       cell->disconnectEdge (element, grid);
1038       majReferences ();
1039       }
1040
1041    DumpReturn (grid);
1042    return grid;
1043 }
1044 // ======================================================== disconnectVertex
1045 Elements* Document::disconnectVertex (Hexa* cell, Vertex* element)
1046 {
1047    DumpStart ("disconnectVertex", cell << element);
1048
1049    Elements* grid = new Elements (this);
1050    grid->checkDisco (cell, element);
1051
1052    if (grid->isValid())
1053       {
1054       update ();
1055       cell->disconnectVertex (element, grid);
1056       majReferences ();
1057       }
1058
1059    DumpReturn (grid);
1060    return grid;
1061 }
1062 // ======================================================== setName
1063 int Document::setName (cpchar prefix)
1064 {
1065    DumpStart ("setName", prefix);
1066
1067    int ier = HOK;
1068    if (Cestvide (prefix) || el_name==prefix)
1069        ier = HERR;
1070    else
1071        {
1072        string name = prefix;
1073        if (hex_parent != NULL)
1074            hex_parent->makeName (prefix, name);
1075        el_name = name;
1076        }
1077
1078    DumpReturn (ier);
1079    return ier ;
1080 }
1081 // ======================================================== setLevel
1082
1083 #ifdef  NO_CASCADE
1084 #define _TEST_BICYL
1085 #endif
1086
1087 void Document::setLevel (int niv)
1088 {
1089    DumpStart ("setLevel", niv);
1090
1091    if (niv == 747)
1092       checkAssociations ();
1093    else if (niv == 748)
1094       {
1095       int nbshapes = countShape ();
1096       for (int nsh=0 ; nsh < nbshapes ; nsh++)
1097           {
1098           doc_tab_shape[nsh]->saveBrep();
1099           }
1100       }
1101    else if (niv == 777)
1102       set_special_option (true);
1103    else if (niv == 778)
1104       set_special_option (false);
1105
1106    else if (niv >=100 && niv <=200)
1107       test_six (this, niv);
1108    else
1109       {
1110       doc_db = niv;
1111       }
1112
1113    DumpEnd;
1114 }
1115 // ======================================================== makeVarName
1116 char* Document::makeVarName (char* name)
1117 {
1118    strcpy (name, doc_ident);
1119    return doc_ident ;
1120 }
1121 // ======================================================== isEmpty
1122 bool Document::isEmpty ()
1123 {
1124    int nombre = countVertex () + countVector ()
1125                                + countCylinder() + countPipe();
1126    return nombre <= 0 && countLaw  () <= 1;
1127 }
1128 // ======================================================== getNextName
1129 cpchar Document::getNextName (EnumElt type, string& buff)
1130 {
1131    char name [8];
1132    EltBase::makeName (type, doc_nbr_elt [type], name);
1133
1134    buff = name;
1135    return buff.c_str();
1136 }
1137
1138 // ======================================================== getNextName
1139 string Document::getNextName (EnumElt type)
1140 {
1141    char name [8];
1142    EltBase::makeName (type, doc_nbr_elt [type], name);
1143
1144    return string(name);
1145 }
1146
1147 // ======================================================== lockDump
1148 void Document::lockDump ()
1149 {
1150    glob->dump.lock ();
1151 }
1152 // ======================================================== restoreDump
1153 void Document::restoreDump ()
1154 {
1155    glob->dump.restore (DumpActif);
1156 }
1157 // ======================================================== getGroup
1158 Group* Document::getGroup (int nro)
1159 {
1160    int size = doc_group.size();
1161    if (nro>=0 && nro<size)
1162       return doc_group [nro];
1163    else
1164       return NULL;
1165 }
1166 // ======================================================== getVector
1167 Vector* Document::getVector (int nro)
1168 {
1169    int size = doc_vector.size();
1170    if (nro>=0 && nro<size)
1171       return doc_vector [nro];
1172    else
1173       return NULL;
1174 }
1175 END_NAMESPACE_HEXA