Salome HOME
e2cf86b1c9e0c09a60f54c821d62b15a14bb88c1
[modules/hexablock.git] / src / HEXABLOCK / HexQpattern.cxx
1
2 // C++ : Table d'hexaedres (Evol Versions 3)
3
4 // Copyright (C) 2009-2023  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
23 #include "HexQpattern.hxx"
24
25 #include "HexVector.hxx"
26 #include "HexVertex.hxx"
27 #include "HexEdge.hxx"
28 #include "HexDiagnostics.hxx"
29 #include "HexDocument.hxx"
30 #include "HexHexa.hxx"
31 #include "HexGlobale.hxx"
32
33 #include <cmath>
34 #include <algorithm>
35 #include <map>
36
37 BEGIN_NAMESPACE_HEXA
38
39 static bool db = false;
40
41 // =================================================== Construc QpatQuad
42 QpatQuad::QpatQuad (Quad* elt)
43 {
44    refer = elt;
45    cible = oppos = NULL;
46    for (int nro=0 ; nro<QUAD4 ; ++nro)
47        q_edge [nro] = NOTHING;
48 }
49 // =================================================== operator=
50 void QpatQuad::operator= (const QpatQuad& other)
51 {
52    refer = other.refer;
53    cible = other.cible;
54    oppos = other.oppos;
55    for (int nro=0;nro<QUAD4;++nro) q_edge[nro] = other.q_edge[nro];
56 }
57 // =================================================== Construc QpatEdge
58 QpatEdge::QpatEdge (Edge* elt)
59 {
60    refer   = elt;
61    cible   = oppos = NULL;
62    v_amont = v_aval = NOTHING;
63 }
64 // =================================================== operator=
65 void QpatEdge::operator= (const QpatEdge& other)
66 {
67    refer   = other.refer;
68    cible   = other.cible;
69    oppos   = other.oppos;
70    v_amont = other.v_amont;
71    v_aval  = other.v_aval;
72 }
73 // =================================================== Construc QpatVertex
74 QpatVertex::QpatVertex (Vertex* elt)
75 {
76    refer = elt;
77    cible = oppos = NULL;
78    v_x   = v_y   = 0.0;
79    on_contour    = true;
80    quad_cible    = NOTHING;
81 }
82 // =================================================== operator=
83 void QpatVertex::operator= (const QpatVertex& other)
84 {
85    refer  = other.refer;
86    cible  = other.cible;
87    oppos  = other.oppos;
88    v_x    = other.v_x;
89    v_y    = other.v_y;
90    on_contour = other.on_contour;
91    quad_cible = other.quad_cible;
92 }
93 // =================================================== find_quad
94 int find_quad (Quads& table, Vertex* vertex)
95 {
96    int nbre = table.size();
97    for (int nro=0 ; nro < nbre ; nro++)
98        if (table[nro]->indexVertex(vertex)>=0)
99           return nro;
100
101    return NOTHING;
102 }
103 // -----------------------------------------------------------------------
104 // -----------------------------------------------------------------------
105 // -----------------------------------------------------------------------
106 // -----------------------------------------------------------------------
107 // ===================================================== Constructeur
108 Qpattern::Qpattern ()
109 {
110    nbr_vertex   = nbr_edges = nbr_quads = 0;
111    cont_nbnodes = 0;
112    pos_vertex4 = pos_edge3 = pos_edge4 = NOTHING;
113    for (int nc=0 ; nc<DIM3 ; nc++)
114        origine[nc] = base_i[nc]  = base_j[nc] = 0;
115
116    base_i[0]  = 1; 
117    base_j[1]  = 1;
118    nbr_layers = 0;
119    ux_mini  = uy_mini  = 0;
120    ux_delta = uy_delta = 1;
121 }
122 // ====================================================== setPattern
123 void Qpattern::setPattern (Vertices& contour, Quads& motif)
124 {
125     cont_nbnodes = contour.size();
126     Real3 cg, point, pmax;
127     Vertex::anaVertices (contour, point, pmax, cg);
128     for (int nro=0 ; nro<cont_nbnodes ; ++nro)
129         addVertex (contour[nro]);
130
131     contour[0]->getPoint (origine);
132     contour[1]->getPoint (point);
133     setOrigin (origine, point, cg);
134
135    double vxmin = pat_vertex[0].v_x;
136    double vymin = pat_vertex[0].v_y;
137    double vxmax = vxmin;
138    double vymax = vymin;
139    for (int np=0 ; np<cont_nbnodes ; ++np)
140        {
141        double ux, uy;
142        projeter (contour[np], ux, uy);
143        vxmin = std::min (ux, vxmin);
144        vxmax = std::max (ux, vxmax);
145        vymin = std::min (uy, vymin);
146        vymax = std::max (uy, vymax);
147        }
148
149     ux_mini  = vxmin;
150     uy_mini  = vymin;
151     ux_delta = vxmax-vxmin;
152     uy_delta = vymax-vymin;
153
154     int nbre = motif.size();
155     for (int nro=0 ; nro<nbre ; ++nro)
156         addQuad (motif[nro]);
157
158     for (int nro=0 ; nro<cont_nbnodes ; ++nro)
159         {
160         contour[nro]->getPoint (point);
161         for (int nc=0 ; nc<DIM3 ; nc++) cg[nc] += point[nc];
162         addVertex (contour[nro]);
163         }
164 }
165 // ====================================================== setTarget
166 void Qpattern::setTarget (Vertices& contour, Quads& cible)
167 {
168    old_contour = contour;
169
170    for (int nro=0 ; nro<cont_nbnodes ; ++nro)
171        {
172        Vertex* vertex = contour[nro];
173        pat_vertex[nro].cible = vertex;
174        pat_vertex[nro].quad_cible = find_quad (cible, vertex);
175        }
176
177    int nbre = cible.size();
178    nbr_layers = 999999;
179    for (int nro=0 ; nro<nbre ; ++nro)
180        {
181        Quad* quad  = cible [nro];
182        Hexa* hexa  = quad->getParent (0); 
183        Quad* oppos = hexa->getOpposedQuad (quad);
184
185        old_top   .push_back (quad);
186        old_bottom.push_back (oppos);
187        old_hexa  .push_back (hexa);
188
189        int prof = 0;
190        while (oppos!=NULL)
191           {
192           prof ++;
193           hexa  = oppos->opposedHexa (hexa);
194           oppos = hexa==NULL ? NULL : hexa->getOpposedQuad (oppos);
195           }
196        nbr_layers = std::min (prof, nbr_layers);
197        }
198 }
199 // ====================================================== setOrigin
200 int Qpattern::setOrigin (double* orig, double* p1, double* cg)
201 {
202    base_i[1]   = base_i[2] = 0; 
203    base_j[0]   = base_j[2] = 0; 
204    base_i[0]   = base_j[1] = 1;
205
206    pat_vertex[0].v_x = pat_vertex[1].v_x = 0;
207    pat_vertex[2].v_x = 1; 
208    pat_vertex[0].v_y = 1;
209    pat_vertex[1].v_y = pat_vertex[2].v_y = 0; 
210
211    calc_vecteur (orig, p1, base_i);
212    calc_vecteur (orig, cg, base_j);
213    normer_vecteur (base_i);
214    normer_vecteur (base_j);
215    Real3 vk;
216    prod_vectoriel (base_i, base_j, vk);
217    prod_vectoriel (vk, base_i, base_j);
218
219    if (db)
220       {
221       PutCoord (orig);
222       PutCoord (base_i);
223       PutCoord (base_j);
224       }
225
226    return HOK;
227 }
228 // ====================================================== addQuad
229 int Qpattern::addQuad (Quad* elt)
230 {
231    if (elt==NULL)
232       return HERR;
233
234    QpatQuad quad (elt);
235    for (int nro=0; nro<QUAD4 ; nro++)
236        {
237        Edge* edge = elt->getEdge (nro);
238        quad.q_edge [nro] = addEdge (edge); 
239        }
240
241    pat_quad.push_back (quad);
242    nbr_quads++;
243    return HOK;
244 }
245 // ====================================================== addEdge
246 int Qpattern::addEdge (Edge* elt)
247 {
248    for (int nro=0; nro<nbr_edges ; nro++)
249        {
250        if (elt==pat_edge [nro].refer)
251           return nro;
252        }
253
254    QpatEdge edge (elt);
255    edge.v_amont  = addVertex (elt->getVertex (V_AMONT));
256    edge.v_aval   = addVertex (elt->getVertex (V_AVAL));
257
258    pat_edge.push_back (edge);
259    nbr_edges++;
260    return nbr_edges-1;
261 }
262
263 // ====================================================== projeter
264 void Qpattern::projeter (Vertex* elt, double& ux, double& uy)
265 {
266    Real3 point, local;
267    elt->getPoint (point);
268    calc_vecteur  (origine, point, local); 
269    ux = (prod_scalaire (base_i, local) - ux_mini)/ux_delta ;
270    uy = (prod_scalaire (base_j, local) - uy_mini)/uy_delta ;
271 }
272 // ====================================================== addVertex
273 int Qpattern::addVertex (Vertex* elt, Vertex* ref)
274 {
275    for (int nro=0; nro<nbr_vertex ; nro++)
276        {
277        if (elt==pat_vertex [nro].refer)
278           {
279           if (ref != NULL) 
280               pat_vertex [nro].on_contour = true;
281           return nro;
282           }
283        }
284
285    QpatVertex vertex (elt);
286    projeter (elt, vertex.v_x, vertex.v_y);
287
288    if (db)
289       printf (" Vertex nro %d : (%g, %g, %g)\t -> (%g, %g)\n", 
290                 nbr_vertex, elt->getX(),  elt->getY(),  elt->getZ(), 
291                 vertex.v_x, vertex.v_y);
292    pat_vertex.push_back (vertex);
293    nbr_vertex++;
294    return nbr_vertex-1;
295 }
296 // ====================================================== getSize
297 void Qpattern::getSize (int& nbq, int& nbed, int& nbv, int& prof)
298 {
299    nbv  = nbr_vertex; 
300    nbed = nbr_edges; 
301    nbq  = nbr_quads; 
302    prof = nbr_layers; 
303 }
304 // ====================================================== stepDown
305 void Qpattern::stepDown ()
306 {
307    int nbnodes = old_contour.size();
308    for (int nro=0 ; nro<nbnodes ; ++nro)
309        {
310        int nq = pat_vertex[nro].quad_cible;
311
312        Hexa*   hexa     = old_hexa [nq];
313        Quad*   quad     = old_top  [nq];
314        Vertex* vertex   = hexa->opposedVertex (quad, old_contour[nro]);
315        old_contour[nro] = vertex;
316        }
317
318    int nbquads = old_top.size();
319    for (int nq=0 ; nq<nbquads ; ++nq)
320        {
321        Quad* oppos = old_bottom[nq];
322        Hexa* hexa  = oppos->opposedHexa (old_hexa[nq]);
323
324        old_top    [nq] -> remove ();
325        old_top    [nq] = oppos;
326        old_bottom [nq] = hexa==NULL ? NULL : hexa->getOpposedQuad (oppos);
327        old_hexa   [nq] = hexa;
328        }
329 }
330 // ====================================================== anaTarget
331 void Qpattern::anaTarget  (double tmin[], double tmax[], double centre[])
332 {
333    Vertex::anaVertices (old_contour, tmin, tmax, centre);
334 }
335 END_NAMESPACE_HEXA