Salome HOME
Updated copyright comment
[modules/hexablock.git] / src / HEXABLOCK / HexHexa_disco.cxx
1
2 // C++ : Gestion des Hexaedres
3
4 // Copyright (C) 2009-2024  CEA, EDF
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, or (at your option) any later version.
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 #include "HexHexa.hxx"
23 #include "HexQuad.hxx"
24
25 #include "HexVertex.hxx"
26 #include "HexDocument.hxx"
27 #include "HexEdge.hxx"
28
29 #include "HexGlobale.hxx"
30 #include "HexXmlWriter.hxx"
31 #include "HexDiagnostics.hxx"
32 #include "HexGlobale.hxx"
33 #include "HexMatrix.hxx"
34 #include "HexElements.hxx"
35
36 BEGIN_NAMESPACE_HEXA
37
38 // ========================================================= disconnectQuad
39 int Hexa::disconnectQuad (Quad* quad, Elements* nouveaux)
40 {
41    if (debug())
42       {
43       printf (" ... Avant disconnectQuad, quad=");
44       quad->printName ("\n");
45       dumpFull ();
46       }
47
48    int nface = findQuad (quad);
49    if (nface==NOTHING)
50       {
51       setError (HERR);
52       Mess << "Quadangle doesn't belong to Hexaedron";
53       return HERR;
54       }
55                                        // Face opposee : replace
56    // int nfopp = (nface MODULO 2==0) ? nface+1 : nface-1;
57
58    int  ind_edge  [QUAD4], ind_opp_quad [QUAD4];
59    bool make_quad [QUAD4], make_edge [QUAD4];
60
61    for (int nro=0 ; nro<QUAD4 ; nro++)
62        make_quad [nro] = make_edge[nro] = false;
63
64    for (int nro=0 ; nro<QUAD4 ; nro++)
65        {
66        int nro1  = (nro+1) MODULO QUAD4;
67        int pedge = findEdge   (quad->getEdge   (nro));
68        int pnode = findVertex (quad->getVertex (nro));
69        int oppq  = findOpposedQuad (quad, quad->getEdge (nro));
70
71        ind_edge [nro]     = pedge;
72        ind_opp_quad [nro] = oppq;
73
74        if (pedge==NOTHING || pnode==NOTHING || oppq==NOTHING)
75           {
76           setError (HERR);
77           Mess << "Topologic problem(1) for quad's edge nr " << nro;
78           return HERR;
79           }
80
81        make_quad [nro]  = h_quad[oppq]->getNbrParents() == 2;
82        make_edge [nro ] = make_edge [nro ] || make_quad [nro];
83        make_edge [nro1] = make_edge [nro1] || make_quad [nro];
84
85        if (debug())
86           {
87           printf (" Sommet nro %d : ", nro);
88           quad->getVertex(nro)->printName (", ");
89           printf (" edge = ");
90           quad->getEdge(nro)->printName (", ");
91           printf (" quad oppose = ");
92           h_quad[oppq]->printName("");
93           if (make_quad [nro])
94              printf (" a dissocier\n");
95           else
96              printf ("\n");
97
98           }
99        }
100
101    Vertex* new_node     [QUAD4];
102    Edge*   new_opp_edge [QUAD4];
103    Edge*   old_opp_edge [QUAD4];
104
105    for (int nro=0 ; nro<QUAD4 ; nro++)
106        {
107        old_opp_edge [nro] = NULL;
108        new_opp_edge [nro] = NULL;
109        Vertex*  o_v0  = quad->getVertex (nro);
110        new_node [nro] = new Vertex (o_v0);
111        if (debug())
112           {
113           printf (" quad.vertex [%d] = ", nro);
114           quad->getVertex (nro)->printName (" --> ");
115           new_node [nro]->printName ("\n");
116           }
117
118        if (make_edge[nro])
119           {
120           Quad*   pface  = h_quad [ind_opp_quad [nro]];
121           int     bid;
122           int     ncut = pface->inter (quad, bid);
123           Edge*   ecut = pface->getEdge ((ncut+1) MODULO QUAD4);
124           Vertex* vopp = ecut->getVertex(V_AMONT);
125           if (vopp==o_v0)
126               vopp = ecut->getVertex (V_AVAL);
127           else if (o_v0 != ecut->getVertex (V_AVAL));
128               {
129               ecut = pface->getEdge ((ncut+3) MODULO QUAD4);
130               vopp = ecut->getVertex(V_AMONT);
131               if (vopp==o_v0)
132                   vopp = ecut->getVertex (V_AVAL);
133               else if (o_v0 != ecut->getVertex (V_AVAL))
134                   {
135                   setError (HERR);
136                   Mess << "Topologic problem(2) for quad's edge nr " << nro;
137                   return HERR;
138                   }
139               }
140
141           old_opp_edge [nro] = ecut;
142           new_opp_edge [nro] = new Edge (new_node[nro], vopp);
143           if (debug())
144              {
145              printf (" quad.opp_edge [%d] = ", nro);
146              old_opp_edge [nro]->printName (" --> ");
147              new_opp_edge [nro]->printName ("\n");
148              }
149           }
150        }
151
152    Quad* new_quad = new Quad (new_node[0], new_node[1], new_node[2],
153                                                         new_node[3]);
154
155    Quad* new_opp_quad [QUAD4];
156    Quad* old_opp_quad [QUAD4];
157    for (int nro=0 ; nro<QUAD4 ; nro++)
158        {
159        old_opp_quad [nro] = NULL;
160        new_opp_quad [nro] = NULL;
161        if (make_quad[nro])
162           {
163           int nro1 = (nro+1) MODULO QUAD4;
164
165           Edge* n_edge0 = new_quad->getEdge (nro);
166           Edge* n_edge1 = new_opp_edge [nro];
167           Edge* n_edge3 = new_opp_edge [nro1];
168
169           int iv1 = n_edge1->inter (n_edge0);
170           int iv3 = n_edge3->inter (n_edge0);
171           if (iv1 <0 || iv3 <0)
172              {
173              setError (HERR);
174              Mess << "Topologic problem(3) for quad's edge nr " << nro;
175              return HERR;
176              }
177
178           Quad* o_face = h_quad [ind_opp_quad [nro]];
179           Edge* edge2  = o_face->findEdge (n_edge1->getVertex (1-iv1),
180                                            n_edge3->getVertex (1-iv3));
181           if (edge2==NULL)
182              {
183              setError (HERR);
184              Mess << "Topologic problem(4) for quad's edge nr " << nro;
185              return HERR;
186              }
187           // Edge* o_edge0 = h_edge [ind_edge     [nro]];
188           // int sens = 1;
189           // Edge* edge2   = o_face->getOpposEdge (o_edge0, sens);
190
191           old_opp_quad [nro] = o_face;
192           if (debug())
193              printf (" -------- Quad oppose nro %d\n", nro);
194           new_opp_quad [nro] = new Quad (n_edge0, n_edge1, edge2, n_edge3);
195           }
196        }
197
198    replaceQuad (quad, new_quad);
199    for (int nro=0 ; nro<QUAD4 ; nro++)
200        if (make_quad[nro])
201           replaceQuad (old_opp_quad [nro], new_opp_quad [nro]);
202
203    for (int nro=0 ; nro<QUAD4 ; nro++)
204        {
205        replaceEdge (h_edge[ind_edge[nro]], new_quad->getEdge (nro));
206        if (make_edge[nro])
207           replaceEdge (old_opp_edge [nro], new_opp_edge [nro]);
208        }
209
210    for (int nro=0 ; nro<QUAD4 ; nro++)
211        {
212        replaceVertex (quad->getVertex(nro), new_node[nro]);
213        }
214
215
216    h_quad [nface] = new_quad;
217    if (debug())
218       {
219       printf (" ... Apres disconnectQuad, new_quad=");
220       new_quad->printName ("\n");
221       dumpFull ();
222       }
223
224    nouveaux->addQuad   (new_quad);
225    for (int nro=0 ; nro<QUAD4 ; nro++)
226        {
227        nouveaux->addEdge   (new_quad->getEdge   (nro));
228        nouveaux->addVertex (new_quad->getVertex (nro));
229        if (make_edge[nro])
230           nouveaux->addEdge (new_opp_edge [nro]);
231        if (make_quad[nro])
232           nouveaux->addQuad (new_opp_quad [nro]);
233        }
234    nouveaux->moveDisco (this);
235    return HOK;
236 }
237 // ========================================================= disconnectEdge
238 int Hexa::disconnectEdge (Edge* arete, Elements* nouveaux)
239 {
240    int nedge  = findEdge   (arete);
241    int namont = findVertex (arete->getVertex(V_AMONT));
242    int naval  = findVertex (arete->getVertex(V_AVAL ));
243
244    if (nedge==NOTHING || namont==NOTHING || naval==NOTHING)
245       {
246       setError (HERR);
247       Mess << "Edge doesn't belong to Hexaedron";
248       return HERR;
249       }
250
251    if (debug())
252       {
253       printf (" ... Avant disconnectEdge, arete=");
254       arete->printName ("\n");
255       dumpFull ();
256       }
257
258    Edge*   n_edge   [HE_MAXI];
259    Quad*   n_quad   [HQ_MAXI];
260    Vertex* n_vertex [HV_MAXI];
261
262    for (int nro=0 ; nro<HQ_MAXI ; nro++) n_quad [nro]   = NULL;
263    for (int nro=0 ; nro<HE_MAXI ; nro++) n_edge [nro]   = NULL;
264    for (int nro=0 ; nro<HV_MAXI ; nro++) n_vertex [nro] = NULL;
265
266    Vertex* old_amont = arete->getVertex (V_AMONT);
267    Vertex* old_aval  = arete->getVertex (V_AVAL );
268    Vertex* new_amont = n_vertex [namont] = new Vertex (old_amont);
269    Vertex* new_aval  = n_vertex [naval]  = new Vertex (old_aval);
270    n_edge [nedge]    = new Edge   (new_amont, new_aval);
271
272    // Un edge non remplace, qui contient un vertex remplace
273    //         commun a plus de 2 faces (donc appartenant a un autre hexa)
274    //         doit etre duplique
275
276    for (int nro=0 ; nro<HE_MAXI ; nro++)
277        {
278        if (   n_edge[nro]==NULL && h_edge[nro] != NULL
279            && h_edge[nro]->getNbrParents()>2)
280           {
281           Vertex* va =  h_edge[nro]->getVertex (V_AMONT);
282           Vertex* vb =  h_edge[nro]->getVertex (V_AVAL);
283
284           if (va==old_amont)
285              n_edge [nro] = new Edge (new_amont, vb);
286           else if (va==old_aval)
287              n_edge [nro] = new Edge (new_aval,  vb);
288           else if (vb==old_amont)
289              n_edge [nro] = new Edge (va, new_amont);
290           else if (vb==old_aval)
291              n_edge [nro] = new Edge (va, new_aval);
292           }
293        }
294
295    // Un quad non remplace, qui contient un edge remplace
296    //         commun a plus de 2 Hexas
297    //         doit etre duplique
298
299    Globale* glob = Globale::getInstance();
300    for (int nro=0 ; nro<HQ_MAXI ; nro++)
301        if (   n_quad[nro]==NULL && h_quad[nro] != NULL
302            && h_quad[nro]->getNbrParents()>1)
303           {
304           Edge* qedge[QUAD4];
305           bool  duplic = false;
306           for (int ned=0 ; ned<QUAD4 ; ned++)
307               {
308               int ndup = glob->QuadEdge (nro, (EnumQuad)ned);
309               if (n_edge [ndup] ==NULL)
310                  qedge [ned] = h_edge[ndup];
311               else
312                  {
313                  qedge [ned] = n_edge[ndup];
314                  duplic = true;
315                  }
316               }
317           if (duplic)
318              n_quad[nro] = new Quad (qedge[Q_A], qedge[Q_B],
319                                      qedge[Q_C], qedge[Q_D]);
320           }
321
322    for (int nro=0 ; nro<HQ_MAXI ; nro++)
323        if (n_quad[nro]!=NULL)
324           {
325           replaceQuad (h_quad[nro], n_quad[nro]);
326           nouveaux->addQuad  (n_quad[nro]);
327           }
328
329    for (int nro=0 ; nro<HE_MAXI ; nro++)
330        if (n_edge[nro]!=NULL)
331           {
332           replaceEdge (h_edge[nro], n_edge[nro]);
333           nouveaux->addEdge  (n_edge[nro]);
334           }
335
336    for (int nro=0 ; nro<HV_MAXI ; nro++)
337        if (n_vertex[nro]!=NULL)
338           {
339           replaceVertex (h_vertex[nro], n_vertex[nro]);
340           nouveaux->addVertex  (n_vertex[nro]);
341           }
342
343    if (debug())
344       {
345       printf (" ... Apres disconnectEdge\n");
346       dumpFull ();
347       }
348
349    nouveaux->moveDisco (this);
350    return HOK;
351 }
352 // ========================================================= disconnectVertex
353 int Hexa::disconnectVertex (Vertex* noeud, Elements* nouveaux)
354 {
355    if (debug())
356       {
357       printf (" ... Avant disconnectVertex, vertex=");
358       noeud->printName ("\n");
359       dumpFull ();
360       }
361
362    int node = findVertex (noeud);
363    if (node==NOTHING)
364       {
365       setError (HERR);
366       Mess << "Vertex doesn't belong to Hexaedron";
367       return HERR;
368       }
369
370    Vertex* new_node = new Vertex (noeud);
371    Quad*   new_quad [HQ_MAXI];
372    Edge*   new_edge [HE_MAXI];
373
374    for (int nro=0 ; nro<HE_MAXI ; nro++) new_edge [nro] = NULL;
375    for (int nro=0 ; nro<HQ_MAXI ; nro++)
376        {
377        new_quad [nro] = NULL;
378             // Cete face contient le sommet et est commune a 2 hexas
379        if (   h_quad[nro]->indexVertex(noeud) >= 0
380            && h_quad[nro]->getNbrParents  ()  >= 2)
381            {
382            int nbmod = 0;
383            Edge* tedge [QUAD4];
384            for (int qed=0 ; qed<QUAD4 ; qed++)
385                {
386                Edge* arete = tedge[qed] = h_quad[nro]->getEdge (qed);
387                int   indv  = arete->index (noeud);
388                if (indv>=0)
389                   {
390                   nbmod++;
391                   int hed = findEdge (arete);
392                   if (hed<0)
393                      {
394                      setError (HERR);
395                      Mess << "Topologic problem(1) for face nr " << nro;
396                      return HERR;
397                      }
398                   if (new_edge [hed]==NULL)
399                       new_edge [hed] = new Edge (new_node,
400                                                  arete->getVertex(1-indv));
401                   tedge [qed] = new_edge [hed];
402                   }
403                }
404            if (nbmod!=2)
405               {
406               setError (HERR);
407               Mess << "Topologic problem(2) for face nr " << nro;
408               return HERR;
409               }
410            new_quad [nro] = new Quad (tedge[0], tedge[1], tedge[2], tedge[3]);
411            }
412        }
413
414    for (int nro=0 ; nro<HQ_MAXI ; nro++)
415        if (new_quad [nro] != NULL)
416           {
417           replaceQuad (h_quad [nro], new_quad [nro]);
418           nouveaux->addQuad (new_quad[nro]);
419           }
420
421    for (int nro=0 ; nro<HE_MAXI ; nro++)
422        if (new_edge [nro] != NULL)
423           {
424           replaceEdge (h_edge [nro], new_edge [nro]);
425           nouveaux->addEdge (new_edge[nro]);
426           }
427
428    replaceVertex (noeud, new_node);
429    nouveaux->addVertex (new_node);
430
431    if (debug())
432       {
433       printf (" ... Apres disconnectVertex\n");
434       dumpFull ();
435       }
436
437    nouveaux->moveDisco (this);
438    return HOK;
439 }
440 END_NAMESPACE_HEXA