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