Salome HOME
First publish of HEXABLOCKcomponant
[modules/hexablock.git] / src / HEXABLOCK / HexQuad.cxx
1
2 // C++ : Gestion des Quadrangles
3
4 #include "HexQuad.hxx"
5
6 #include "HexDocument.hxx"
7 #include "HexHexa.hxx"
8 #include "HexElements.hxx"
9
10 #include "HexXmlWriter.hxx"
11 #include "HexShape.hxx"
12
13 BEGIN_NAMESPACE_HEXA
14
15 // ======================================================== Constructeur
16 Quad::Quad (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd)
17     : EltBase (va->dad(), EL_QUAD)
18 {
19    q_vertex [E_A] = va;
20    q_vertex [E_B] = vb;
21    q_vertex [E_C] = vc;
22    q_vertex [E_D] = vd;
23
24    for (int nro=0 ; nro<QUAD4 ; nro++)
25        {
26        q_edge [nro] = new Edge (q_vertex[nro], 
27                                 q_vertex[(nro+1) MODULO QUAD4]);
28        }
29
30    majReferences ();
31 }
32 // ======================================================== Constructeur bis
33 Quad::Quad (Edge* ea, Edge* eb, Edge* ec, Edge* ed)
34     : EltBase (ea->dad(), EL_QUAD)
35 {
36    q_edge [E_A] = ea;
37    q_edge [E_B] = eb;
38    q_edge [E_C] = ec;
39    q_edge [E_D] = ed;
40
41    for (int nro=0 ; nro<QUAD4 ; nro++)
42        {
43        int ns = (nro+1) MODULO QUAD4; 
44        Vertex* node = NULL;
45        int nc  = q_edge[nro] -> inter (q_edge[ns]);
46        if (nc>=0)
47           node = q_edge[nro]->getVertex (nc);
48        else  
49           el_status = 888;
50        q_vertex [ns] = node;
51        }
52
53    if (el_status != HOK)
54       {
55       printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
56       printf (" +++ Quadrangle impossible \n");
57       printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
58       dump ();
59       printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
60       // el_root->dump ();
61       for (int ned=0; ned<QUAD4; ned++) 
62           {
63           q_edge[ned]->dumpPlus ();
64           }
65       HexDump (q_vertex[0]);
66       HexDump (q_vertex[1]);
67       HexDump (q_vertex[2]);
68       HexDump (q_vertex[3]);
69
70       printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
71       // exit (1);
72       }
73
74    majReferences ();
75 }
76 // ======================================================== Constructeur bis
77 Quad::Quad (Quad* other)
78     : EltBase (other->dad(), EL_QUAD)
79 {
80    for (int nro=0 ; nro<QUAD4 ; nro++)
81        {
82        q_edge   [nro] = NULL;
83        q_vertex [nro] = NULL;
84        }
85 }
86 // ========================================================= getParent 
87 void Quad::majReferences ()
88 {
89    for (int nro=0 ; nro<QUAD4 ; nro++)
90        q_edge [nro] -> addParent (this);
91 }
92 // ========================================================= getParent 
93 Hexa* Quad::getParent  (int nro)
94 {
95    return static_cast <Hexa*> (getFather (nro));
96 }
97 // ======================================================== anaMerge
98 int Quad::anaMerge (Vertex* v1, Vertex* v2, Vertex* tv1[], Edge* te1[])
99 {
100    int orig = NOTHING;
101    for (int nro=0 ; orig == NOTHING && nro < QUAD4 ; nro++)
102        if (q_vertex [nro] == v1)
103            orig = nro;
104
105    if (orig==NOTHING)
106       return HERR;
107
108    int nsp1 = (orig+1)       MODULO QUAD4;
109    int nsm1 = (orig+QUAD4-1) MODULO QUAD4;
110
111    if (q_vertex [nsp1] == v2) 
112       {
113       for (int nro=0 ; nro < QUAD4 ; nro++)
114           {
115           tv1 [nro] = q_vertex [(orig+nro) MODULO QUAD4];
116           te1 [nro] = q_edge   [(orig+nro) MODULO QUAD4];
117           }
118       }
119    else if (q_vertex [nsm1] == v2) 
120       {
121       for (int nro=0 ; nro < QUAD4 ; nro++)
122           {
123           tv1 [nro] = q_vertex [(orig+QUAD4-nro) MODULO QUAD4];
124           te1 [nro] = q_edge   [(orig+QUAD4-nro) MODULO QUAD4];
125           }
126       }
127    else 
128       return 588;
129
130    return HOK;
131 }
132 // ======================================================== ordoVertex
133 int Quad::ordoVertex (Vertex* v1, Vertex* v2, Vertex* tv1[])
134 {
135    int orig = NOTHING;
136    for (int nro=0 ; orig == NOTHING && nro < QUAD4 ; nro++)
137        if (q_vertex [nro] == v1)
138            orig = nro;
139
140    if (orig==NOTHING)
141       return HERR;
142
143    int nsp1 = (orig+1)       MODULO QUAD4;
144    int nsm1 = (orig+QUAD4-1) MODULO QUAD4;
145
146    if (q_vertex [nsp1] == v2) 
147       {
148       for (int nro=0 ; nro < QUAD4 ; nro++)
149           tv1 [nro] = q_vertex [(orig+nro) MODULO QUAD4];
150       }
151    else if (q_vertex [nsm1] == v2) 
152       {
153       for (int nro=0 ; nro < QUAD4 ; nro++)
154           tv1 [nro] = q_vertex [(orig+QUAD4-nro) MODULO QUAD4];
155       }
156    else 
157       return 588;
158
159    return HOK;
160 }
161 // ======================================================== getBrother
162 Quad* Quad::getBrother (StrOrient* orient)
163 {
164 /* *****************************
165    printf (" getBrother ");
166    dump ();
167    printf (" .. Base  : ");
168    orient->v21->printName();
169    orient->v22->printName();
170    printf ("dir=%d, arete=", orient->dir);
171   ***************************** */
172
173    int n21 = indexVertex (orient->v21);
174    int n22 = indexVertex (orient->v22);
175
176    int sens  = n22 - n21;
177    if (sens >  1) sens -= QUAD4;
178    if (sens < -1) sens += QUAD4;
179    if (sens*sens !=1) return NULL;
180
181    switch (orient->dir)
182       {
183       case OR_LEFT  : n22 = n21 - sens;
184            break;
185       case OR_RIGHT : n21 = n22 + sens;
186            break;
187       case OR_FRONT : n21 += 2; 
188                       n22 += 2; 
189            break;
190       default : ;
191       }
192
193    n21 = (n21 + QUAD4) MODULO QUAD4;
194    n22 = (n22 + QUAD4) MODULO QUAD4;
195
196    orient->v21 = q_vertex [n21];
197    orient->v22 = q_vertex [n22];
198
199    Edge* arete  = findEdge (orient->v21, orient->v22);
200    arete->printName("\n");
201
202    int nbfreres = arete->getNbrParents ();
203
204    for (int nq = 0 ; nq < nbfreres ; nq++)
205        {
206        Quad* next = arete->getParent (nq);
207        if (next!=NULL && next != this )
208           {
209           int   nbp   = next->getNbrParents();
210           Hexa* dad   = next->getParent(0);
211           int   mark  = next->getMark();
212           int   mark2 = dad ? dad->getMark() : IS_NONE;
213
214           if (nbp  <= 1  && mark2 != IS_MARRIED && mark == IS_NONE)
215              return next;
216           // if (nbp  <= 1  && mark == IS_NONE)
217              // return next;
218           }
219        }
220    return NULL;
221 }
222 // ======================================================== coupler
223 int Quad::coupler (Quad* other, StrOrient* orient, Elements* table)
224 {
225    if (other==NULL) 
226       return HERR;
227
228    Hexa* hexa = other->getParent(0);
229
230    setMark (IS_MARRIED);
231    other->setMark (IS_MARRIED);
232    if (hexa != NULL)
233        hexa->setMark (IS_MARRIED);
234
235    for (int ned = 0 ; ned < QUAD4 ; ned++)
236        {
237        Edge* arete  = q_edge[ned]; 
238        int nbfreres = arete ->getNbrParents (); 
239        for (int nq = 0 ; nq < nbfreres ; nq++)
240            {
241            Quad* next = arete->getParent (nq);
242            if (next!=NULL && next != this && next->getMark() > 0)
243               {
244               StrOrient new_ori (orient);
245               new_ori.dir = OR_FRONT;
246               Vertex* va  = arete->getVertex (V_AMONT); 
247               Vertex* vb  = arete->getVertex (V_AVAL); 
248
249 //    On voit si un point de repere est conserve
250               if (va == orient->v11)
251                  {
252                  new_ori.v12 = vb;
253                  new_ori.dir += OR_LEFT;
254                  }
255               else if (vb == orient->v11)
256                  {
257                  new_ori.v12 = va;
258                  new_ori.dir += OR_LEFT;
259                  }
260
261               if (va == orient->v12)
262                  {
263                  new_ori.v11 = vb;
264                  new_ori.dir += OR_RIGHT;
265                  }
266               else if (vb == orient->v12)
267                  {
268                  new_ori.v11 = va;
269                  new_ori.dir += OR_RIGHT;
270                  }
271
272               if (new_ori.dir == OR_FRONT)
273                  {
274                  if (definedBy (va, orient->v11))
275                     {
276                     new_ori.v11 = va;
277                     new_ori.v12 = vb;
278                     }
279                  else
280                     {
281                     new_ori.v11 = vb;
282                     new_ori.v12 = va;
283                     }
284                  }
285
286               int nro = next->getMark ();
287               Quad* beauf = other->getBrother (&new_ori);
288               table->coupler (nro, beauf, &new_ori);
289               next->coupler (beauf, &new_ori, table);
290               }
291            }
292        }
293    return HOK;
294 }
295 // ======================================================== getOpposEdge
296 Edge* Quad::getOpposEdge (Edge* start, int& sens)
297 {
298    sens = 1;
299    int  na = indexVertex (start->getVertex (V_AMONT));
300    int  nb = indexVertex (start->getVertex (V_AVAL));
301
302    Vertex* vaprim = q_vertex [(nb+2) MODULO QUAD4];
303    Vertex* vbprim = q_vertex [(na+2) MODULO QUAD4];
304
305    for (int ned = 0 ; ned < QUAD4 ; ned++)
306        {
307        if (   q_edge[ned]->getVertex(V_AMONT) == vaprim
308            && q_edge[ned]->getVertex(V_AVAL ) == vbprim)
309            {
310            sens = 1;
311            return q_edge[ned];
312            }
313        else if (   q_edge[ned]->getVertex(V_AMONT) == vbprim
314                 && q_edge[ned]->getVertex(V_AVAL ) == vaprim)
315            {
316            sens = -1;
317            return q_edge[ned];
318            }
319        }
320    //             TODO : traiter l'erreur
321    dumpPlus ();
322    for (int ned = 0 ; ned < QUAD4 ; ned++)
323        q_edge[ned]->dump();
324
325    return NULL;
326 }
327 // ========================================================= getParent 
328 void Quad::saveXml (XmlWriter& xml)
329 {
330    char buffer[12];
331    string edges;
332
333    for (int nro=0 ; nro<QUAD4 ; nro++)
334        {
335        if (nro>0) edges += " ";
336        edges += q_edge[nro]->getName(buffer);
337        }
338
339    xml.openMark     ("Quad");
340    xml.addAttribute ("id",    getName (buffer));
341    xml.addAttribute ("edges", edges);
342    if (el_assoc!=NULL)
343       xml.addAttribute ("shape", el_assoc->getBrep().c_str());
344    xml.closeMark ();
345 }
346 // ======================================================== replaceEdge
347 void Quad::replaceEdge (Edge* old, Edge* par)
348 {
349    for (int nro=0 ; nro<QUAD4 ; nro++)
350        {
351        if (q_edge[nro]==old) 
352            {
353            q_edge[nro] = par;
354            if (debug())
355               {
356               printf (" Dans ");
357               printName ();
358               printf (" [%d], ", nro);
359               old->printName (" est remplace par ");
360               par->printName ("\n");
361               }
362            }
363        }
364 }
365 // ======================================================== replaceVertex
366 void Quad::replaceVertex (Vertex* old, Vertex* par)
367 {
368    for (int nro=0 ; nro<QUAD4 ; nro++)
369        {
370        if (q_vertex [nro]==old) 
371           {
372           q_vertex [nro] = par;
373            if (debug())
374               {
375               printf (" Dans ");
376               printName ();
377               printf (" [%d], ", nro);
378               old->printName (" est remplace par ");
379               par->printName ("\n");
380               }
381           }
382        }
383 }
384 // ======================================================== dump
385 void Quad::dump ()
386 {
387    printName(" = (");
388    if (NOT isHere ())
389       {
390       printf ("*** deleted ***)\n");
391       return;
392       }
393
394    for (int nro=0 ; nro<QUAD4 ; nro++)
395         PrintName (q_edge[nro]);
396    printf (")\n" );
397
398    printf ("        (" );
399    for (int nro=0 ; nro<QUAD4 ; nro++)
400         PrintName (q_vertex[nro]);
401    printf (")" );
402
403    dumpRef ();
404 }
405 // ======================================================== dumpPlus
406 void Quad::dumpPlus ()
407 {
408    dump ();
409    if (NOT isHere ())
410       return;
411
412    for (int nro=0 ; nro < QUAD4 ; nro++)
413        {
414        Vertex* pv = q_vertex[nro];
415        printf ( "    ");
416        if (pv!=NULL)
417           {
418           pv->printName ("");
419           printf ( " (%g, %g, %g)\n", pv->getX(),  pv->getY(),  pv->getZ());
420           }
421        else
422           {
423           printf ( "NULL\n");
424           }
425        }
426 }
427 END_NAMESPACE_HEXA