2 // C++ : Gestion des Quadrangles
4 // Copyright (C) 2009-2013 CEA/DEN, EDF R&D
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include "HexQuad.hxx"
24 #include "HexDocument.hxx"
25 #include "HexHexa.hxx"
26 #include "HexElements.hxx"
27 #include "HexGlobale.hxx"
29 #include "HexXmlWriter.hxx"
30 #include "HexNewShape.hxx"
31 #include "HexFaceShape.hxx"
37 // ======================================================== Constructeur
38 Quad::Quad (Vertex* va, Vertex* vb, Vertex* vc, Vertex* vd)
39 : EltBase (va->dad(), EL_QUAD)
46 q_orientation = Q_UNDEFINED;
48 for (int nro=0 ; nro<QUAD4 ; nro++)
50 q_edge [nro] = new Edge (q_vertex[nro],
51 q_vertex[(nro+1) MODULO QUAD4]);
53 if (BadElement (q_vertex [nro]) || BadElement (q_edge [nro]))
56 for (int nv=nro+1 ; nv<QUAD4 ; nv++)
57 if (q_vertex[nv] == q_vertex[nro])
63 // ======================================================== Constructeur bis
64 Quad::Quad (Edge* ea, Edge* eb, Edge* ec, Edge* ed)
65 : EltBase (ea->dad(), EL_QUAD)
72 q_orientation = Q_UNDEFINED;
74 for (int nro=0 ; nro<QUAD4 ; nro++)
76 int prec = (nro+1) MODULO QUAD4;
79 if (BadElement (q_edge[nro]))
83 for (int nv=nro+1 ; nv<QUAD4 ; nv++)
84 if (q_edge[nv] == q_edge[nro])
86 int nc = q_edge[nro] -> inter (q_edge[prec]);
88 node = q_edge[nro]->getVertex (nc);
92 q_vertex [prec] = node;
97 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
98 printf (" +++ Quadrangle impossible \n");
99 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
101 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
103 for (int ned=0; ned<QUAD4; ned++)
105 q_edge[ned]->dumpPlus ();
107 HexDump (q_vertex[0]);
108 HexDump (q_vertex[1]);
109 HexDump (q_vertex[2]);
110 HexDump (q_vertex[3]);
112 printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
113 fatal_error ("Quadrangle impossible");
118 // ======================================================== Constructeur ter
119 Quad::Quad (Quad* other)
120 : EltBase (other->dad(), EL_QUAD)
122 for (int nro=0 ; nro<QUAD4 ; nro++)
125 q_vertex [nro] = NULL;
127 q_orientation = Q_UNDEFINED;
130 // ============================================================ getEdge
131 Edge* Quad::getEdge (int nro)
134 if (nro >=0 && nro < QUAD4 && el_status == HOK && q_edge [nro]->isValid())
137 DumpStart ("getEdge", nro);
141 // ============================================================ getVertex
142 Vertex* Quad::getVertex (int nro)
145 if (nro >=0 && nro < QUAD4 && el_status == HOK && q_vertex [nro]->isValid())
146 elt = q_vertex [nro];
148 DumpStart ("getVertex", nro);
152 // ========================================================= majReferences
153 void Quad::majReferences ()
155 for (int nro=0 ; nro<QUAD4 ; nro++)
156 q_edge [nro] -> addParent (this);
158 // ========================================================= getParent
159 Hexa* Quad::getParent (int nro)
161 return static_cast <Hexa*> (getFather (nro));
163 // ======================================================== anaMerge
164 int Quad::anaMerge (Vertex* v1, Vertex* v2, Vertex* tv1[], Edge* te1[])
167 for (int nro=0 ; orig == NOTHING && nro < QUAD4 ; nro++)
168 if (q_vertex [nro] == v1)
174 int nsp1 = (orig+1) MODULO QUAD4;
175 int nsm1 = (orig+QUAD4-1) MODULO QUAD4;
177 if (q_vertex [nsp1] == v2)
179 for (int nro=0 ; nro < QUAD4 ; nro++)
181 tv1 [nro] = q_vertex [(orig+nro) MODULO QUAD4];
182 te1 [nro] = q_edge [(orig+nro) MODULO QUAD4];
185 else if (q_vertex [nsm1] == v2)
187 for (int nro=0 ; nro < QUAD4 ; nro++)
189 tv1 [nro] = q_vertex [(orig+QUAD4-nro) MODULO QUAD4];
190 te1 [nro] = q_edge [(orig+QUAD4-nro) MODULO QUAD4];
198 // ======================================================== ordoVertex
199 int Quad::ordoVertex (Vertex* v1, Vertex* v2, Vertex* tv1[])
202 for (int nro=0 ; orig == NOTHING && nro < QUAD4 ; nro++)
203 if (q_vertex [nro] == v1)
209 int nsp1 = (orig+1) MODULO QUAD4;
210 int nsm1 = (orig+QUAD4-1) MODULO QUAD4;
212 if (q_vertex [nsp1] == v2)
214 for (int nro=0 ; nro < QUAD4 ; nro++)
215 tv1 [nro] = q_vertex [(orig+nro) MODULO QUAD4];
217 else if (q_vertex [nsm1] == v2)
219 for (int nro=0 ; nro < QUAD4 ; nro++)
220 tv1 [nro] = q_vertex [(orig+QUAD4-nro) MODULO QUAD4];
227 // ======================================================== getBrother
228 Quad* Quad::getBrother (StrOrient* orient)
230 /* *****************************
231 printf (" getBrother ");
233 printf (" .. Base : ");
234 orient->v21->printName();
235 orient->v22->printName();
236 printf ("dir=%d, arete=", orient->dir);
237 ***************************** */
239 int n21 = indexVertex (orient->v21);
240 int n22 = indexVertex (orient->v22);
242 int sens = n22 - n21;
243 if (sens > 1) sens -= QUAD4;
244 if (sens < -1) sens += QUAD4;
245 if (sens*sens !=1) return NULL;
249 case OR_LEFT : n22 = n21 - sens;
251 case OR_RIGHT : n21 = n22 + sens;
253 case OR_FRONT : n21 += 2;
259 n21 = (n21 + QUAD4) MODULO QUAD4;
260 n22 = (n22 + QUAD4) MODULO QUAD4;
262 orient->v21 = q_vertex [n21];
263 orient->v22 = q_vertex [n22];
265 Edge* arete = findEdge (orient->v21, orient->v22);
266 // arete->printName("\n");
268 int nbfreres = arete->getNbrParents ();
270 for (int nq = 0 ; nq < nbfreres ; nq++)
272 Quad* next = arete->getParent (nq);
273 if (next!=NULL && next != this )
275 int nbp = next->getNbrParents();
276 Hexa* dad = next->getParent(0);
277 int mark = next->getMark();
278 int mark2 = dad ? dad->getMark() : IS_NONE;
280 if (nbp <= 1 && mark2 != IS_MARRIED && mark == IS_NONE)
282 // if (nbp <= 1 && mark == IS_NONE)
288 // ======================================================== coupler
289 int Quad::coupler (Quad* other, StrOrient* orient, Elements* table)
294 Hexa* hexa = other->getParent(0);
296 setMark (IS_MARRIED);
297 other->setMark (IS_MARRIED);
299 hexa->setMark (IS_MARRIED);
301 for (int ned = 0 ; ned < QUAD4 ; ned++)
303 Edge* arete = q_edge[ned];
304 int nbfreres = arete ->getNbrParents ();
305 for (int nq = 0 ; nq < nbfreres ; nq++)
307 Quad* next = arete->getParent (nq);
308 if (next!=NULL && next != this && next->getMark() > 0)
310 StrOrient new_ori (orient);
311 new_ori.dir = OR_FRONT;
312 Vertex* va = arete->getVertex (V_AMONT);
313 Vertex* vb = arete->getVertex (V_AVAL);
315 // On voit si un point de repere est conserve
316 if (va == orient->v11)
319 new_ori.dir += OR_LEFT;
321 else if (vb == orient->v11)
324 new_ori.dir += OR_LEFT;
327 if (va == orient->v12)
330 new_ori.dir += OR_RIGHT;
332 else if (vb == orient->v12)
335 new_ori.dir += OR_RIGHT;
338 if (new_ori.dir == OR_FRONT)
340 if (definedBy (va, orient->v11))
352 int nro = next->getMark ();
353 Quad* beauf = other->getBrother (&new_ori);
354 int ier = table->coupler (nro, beauf, &new_ori);
357 ier = next->coupler (beauf, &new_ori, table);
365 // ======================================================== getOpposVertex
366 Vertex* Quad::getOpposVertex (Vertex* start)
368 int na = indexVertex (start);
371 return q_vertex [(na+2) MODULO QUAD4];
373 // ======================================================== getOpposEdge
374 Edge* Quad::getOpposEdge (Edge* start, int& sens)
377 int na = indexVertex (start->getVertex (V_AMONT));
378 int nb = indexVertex (start->getVertex (V_AVAL));
380 Vertex* vaprim = q_vertex [(nb+2) MODULO QUAD4];
381 Vertex* vbprim = q_vertex [(na+2) MODULO QUAD4];
383 for (int ned = 0 ; ned < QUAD4 ; ned++)
385 if ( q_edge[ned]->getVertex(V_AMONT) == vaprim
386 && q_edge[ned]->getVertex(V_AVAL ) == vbprim)
391 else if ( q_edge[ned]->getVertex(V_AMONT) == vbprim
392 && q_edge[ned]->getVertex(V_AVAL ) == vaprim)
398 // TODO : traiter l'erreur
399 cout << " ... Probleme dans Quad::getOpposedEdge :" << endl;
400 HexDisplay (el_name);
408 for (int ned = 0 ; ned < QUAD4 ; ned++)
413 // ========================================================= saveXml
414 void Quad::saveXml (XmlWriter* xml)
419 for (int nro=0 ; nro<QUAD4 ; nro++)
421 if (nro>0) edges += " ";
422 edges += q_edge[nro]->getName(buffer);
425 xml->openMark ("Quad");
426 xml->addAttribute ("id", getName (buffer));
427 xml->addAttribute ("edges", edges);
429 xml->addAttribute ("name", el_name);
432 int nbass = tab_assoc.size();
433 for (int nro=0 ; nro<nbass ; nro++)
434 if (tab_assoc[nro] != NULL)
435 tab_assoc[nro]->saveXml (xml);
437 // ======================================================== replaceEdge
438 void Quad::replaceEdge (Edge* old, Edge* par)
440 for (int nro=0 ; nro<QUAD4 ; nro++)
442 if (q_edge[nro]==old)
449 printf (" [%d], ", nro);
450 old->printName (" est remplace par ");
451 par->printName ("\n");
456 // ======================================================== replaceVertex
457 void Quad::replaceVertex (Vertex* old, Vertex* par)
459 for (int nro=0 ; nro<QUAD4 ; nro++)
461 if (q_vertex [nro]==old)
463 q_vertex [nro] = par;
468 printf (" [%d], ", nro);
469 old->printName (" est remplace par ");
470 par->printName ("\n");
475 // ======================================================== dump
481 printf ("*** deleted ***)\n");
485 for (int nro=0 ; nro<QUAD4 ; nro++)
486 PrintName (q_edge[nro]);
490 for (int nro=0 ; nro<QUAD4 ; nro++)
491 PrintName (q_vertex[nro]);
496 // ======================================================== dumpPlus
497 void Quad::dumpPlus ()
503 for (int nro=0 ; nro < QUAD4 ; nro++)
505 Vertex* pv = q_vertex[nro];
510 printf ( " (%g, %g, %g)\n", pv->getX(), pv->getY(), pv->getZ());
518 // ======================================================== getOpposEdge (2)
519 Edge* Quad::getOpposEdge (Edge* start)
521 int na = indexEdge (start);
524 return q_edge [(na+2) MODULO QUAD4];
526 // ======================================================== getPerpendicular
527 Edge* Quad::getPerpendicular (Edge* arete, Vertex* node)
529 int na = indexEdge (arete);
533 int nv = arete->index (node);
536 Edge* perp = q_edge [(na+1) MODULO QUAD4];
538 nv = perp->index (node);
542 perp = q_edge [(na+3) MODULO QUAD4];
543 nv = perp->index (node);
549 static cpchar t_ori[] = {"Q_INSIDE", "Q_DIRECT", "Q_INVERSE", "Q_UNDEF"};
550 // ======================================================== setOrientation
551 void Quad::setOrientation (int ori)
554 if (db && (ori==Q_DIRECT || ori==Q_INVERSE))
555 printf (" %s = %s\n", el_name.c_str(), t_ori [ q_orientation ]);
557 // ======================================================== setOrientation
558 int Quad::setOrientation ()
560 q_orientation = Q_INSIDE;
561 if (getNbrParents() != 1)
562 return q_orientation;
564 Real3 cg, orig, pi, pj, vi, vj, vk;
566 Hexa* hexa = getParent(0);
567 hexa->getCenter (cg);
569 /********************************************************************
572 for (int np=0 ; np < QUAD4 ; np++)
574 q_vertex [np ] -> getPoint (orig);
575 q_vertex [(np+1) % 4] -> getPoint (pi);
576 q_vertex [(np+3) % 4] -> getPoint (pj);
578 calc_vecteur (orig, pi, vi);
579 calc_vecteur (orig, pj, vj);
580 calc_vecteur (orig, cg, vk);
581 double pmixte = prod_mixte (vi, vj, vk);
582 q_orientation = pmixte > ZEROR ? Q_DIRECT : Q_INVERSE;
583 if (pmixte>0) printf (">");
589 ******************************************************************* */
590 q_vertex [0] -> getPoint (orig);
591 q_vertex [1] -> getPoint (pi);
592 q_vertex [3] -> getPoint (pj);
594 calc_vecteur (orig, pi, vi);
595 calc_vecteur (orig, pj, vj);
596 calc_vecteur (cg, orig, vk);
598 double pmixte = prod_mixte (vi, vj, vk);
599 q_orientation = pmixte > ZEROR ? Q_DIRECT : Q_INVERSE;
601 printf (" %s = %s\n", el_name.c_str(), t_ori [ q_orientation ]);
602 return q_orientation;
604 // ========================================================== clearAssociation
605 void Quad::clearAssociation ()
608 is_associated = false;
610 // ========================================================== addAssociation
611 int Quad::addAssociation (NewShape* geom, int subid)
616 FaceShape* face = geom->findFace (subid);
617 int ier = addAssociation (face);
621 // ========================================================== addAssociation
622 int Quad::addAssociation (FaceShape* face)
627 face->addAssociation (this);
628 tab_assoc.push_back (face);
629 is_associated = true;
632 // ========================================================== getAssociation
633 FaceShape* Quad::getAssociation (int nro)
635 if (nro < 0 || nro >= tab_assoc.size())
638 return tab_assoc [nro];