Salome HOME
Mise a jour source recette Hexablock 6
[modules/hexablock.git] / src / HEXABLOCK / HexNewShape.cxx
1
2 // C++ : Gestion des Shapes (Hexa v5)
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/
21 // or email : webmaster.salome@opencascade.com
22
23 #include "HexNewShape.hxx"
24 #include "HexSubShape.hxx"
25 #include "HexVertexShape.hxx"
26 #include "HexEdgeShape.hxx"
27 #include "HexFaceShape.hxx"
28
29 #include "HexQuad.hxx"
30 #include "HexEdge.hxx"
31 #include "HexMatrix.hxx"
32
33 #include "HexKas_functions.hxx"
34
35 #include "HexXmlWriter.hxx"
36 #include "HexXmlTree.hxx"
37
38 #include <TopoDS.hxx>
39 #include <TopoDS_Iterator.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS_Compound.hxx>
42
43 #include <BRepTools.hxx>
44 #include <BRep_Builder.hxx>
45 #include <BRepBuilderAPI_MakeEdge.hxx>
46 #include <BRepPrimAPI_MakeSphere.hxx>
47 #include <BRepBuilderAPI_Transform.hxx>
48
49 #include <BRep_Tool.hxx>
50
51
52 #include <gp_Pnt.hxx>
53 #include <gp_Pln.hxx>
54 #include <gp_Dir.hxx>
55 #include <gp_Lin.hxx>
56 #include <gp_Circ.hxx>
57
58
59 BEGIN_NAMESPACE_HEXA
60
61 static bool db  = on_debug ();  // == getenv ("HEXA_DB") > 0
62 static bool db0 = db;
63
64 // ====================================================== Constructeur
65 NewShape::NewShape (Document* dad, EnumShape type)
66         : EltBase  (dad, EL_SHAPE)
67 {
68    sh_origin    =  type;
69    brep_defined =  shape_defined = false;
70
71    sh_level     = sh_indice      = 0;
72    sh_face_max  = sh_edge_max    = sh_vertex_max = 0;
73
74    curr_subid = 2;
75 }
76 // ====================================================== setShape
77 void NewShape::setShape (const TopoDS_Shape& shape, EnumShape type)
78 {
79    sh_origin = type;
80    geo_shape = shape;
81    geo_brep  = "";
82
83    shape_defined = true;
84    brep_defined  = false;
85
86    map_shape .Clear ();
87    tab_face  .clear ();
88    tab_edge  .clear ();
89    tab_vertex.clear ();
90
91    sh_level    = sh_indice   = 0;
92    sh_face_max = sh_edge_max = sh_vertex_max = 0;
93
94    if (db)
95       cout <<  " ------------------- setShape " << el_name << endl;
96    parseShape (geo_shape);
97 }
98 // ====================================================== setBrep
99 void NewShape::setBrep (rcstring brep)
100 {
101    geo_brep     = brep;
102    brep_defined = true;
103    updateShape ();
104 }
105 // ====================================================== getGeoShape
106 const TopoDS_Shape& NewShape::getGeoShape (int id)
107 {
108    const TopoDS_Shape& shape = map_shape.FindKey (id);
109    return shape;
110 }
111 // ====================================================== getShape
112 const TopoDS_Shape& NewShape::getShape ()
113 {
114    return geo_shape;
115 }
116 // ====================================================== openShape
117 void NewShape::openShape ()
118 {
119    geo_builder.MakeCompound (geo_compound);
120    curr_subid = 2;
121
122    asso_edge.clear ();
123    asso_pmin.clear ();
124    asso_pmax.clear ();
125    asso_edid.clear ();
126    asso_quad.clear ();
127    asso_quid.clear ();
128 }
129 // ====================================================== addCircle
130 int NewShape::addCircle (double* milieu, double rayon, double* normale,
131                          double* base)
132 {
133    gp_Pnt gp_center (milieu [dir_x], milieu [dir_y], milieu [dir_z]);
134    gp_Vec gp_vx     (base   [dir_x], base   [dir_y], base   [dir_z]);
135    gp_Vec gp_norm   (normale[dir_x], normale[dir_y], normale[dir_z]);
136
137    gp_Ax2  gp_axes (gp_center, gp_norm, gp_vx);
138    gp_Circ gp_circ (gp_axes,   rayon);
139
140    TopoDS_Edge  geom_circ = BRepBuilderAPI_MakeEdge(gp_circ).Edge();
141    geo_builder.Add (geo_compound, geom_circ);
142
143    if (db)
144    cout << " .... AddCircle subid " << curr_subid << " : rayon=" << rayon
145         << " centre = " << milieu[dir_x] << "," << milieu[dir_y]
146         << "," << milieu[dir_z]
147         << " norm = " << normale[dir_x] << "," << normale[dir_y]
148         << "," << normale[dir_z]
149         << endl;
150
151    int  subid  = curr_subid;
152    curr_subid += 2;
153    return subid;
154 }
155 // ====================================================== addSphere
156 int NewShape::addSphere (double* milieu, double radius)
157 {
158    gp_Pnt  gp_center (milieu [dir_x], milieu [dir_y], milieu [dir_z]);
159    gp_Ax2  gp_axis (gp_center, gp_Dir(0,0,1), gp_Dir(1,0,0));
160
161    BRepPrimAPI_MakeSphere make_sphere (gp_axis, radius);
162    make_sphere.Build();
163    TopoDS_Shape   geom_sphere = make_sphere.Face();
164    geo_builder.Add (geo_compound, geom_sphere);
165
166    if (db)
167    cout << " .... AddSphere subid " << curr_subid << " : rayon=" << radius
168         << " centre = " << milieu[dir_x] << "," << milieu[dir_y]
169         << "," << milieu[dir_z] << endl;
170
171    int  subid  = curr_subid;
172    curr_subid += 7;
173    return subid;
174 }
175 // ====================================================== transfoShape
176 int NewShape::transfoShape (Matrix& matrice, SubShape* shape)
177 {
178    gp_Trsf transfo;
179    double             a11,a12,a13,a14, a21,a22,a23,a24, a31,a32,a33,a34;
180    matrice.getCoeff  (a11,a12,a13,a14, a21,a22,a23,a24, a31,a32,a33,a34);
181    transfo.SetValues (a11,a12,a13,a14, a21,a22,a23,a24, a31,a32,a33,a34,
182                       Epsil2, Epsil2);
183
184    TopoDS_Shape shape_orig = shape->getShape ();
185    BRepBuilderAPI_Transform builder (shape_orig, transfo, Standard_True);
186    TopoDS_Shape result = builder.Shape();
187
188    geo_builder.Add (geo_compound, result);
189
190    int  subid  = curr_subid;
191    curr_subid += 2;                       // PROVISOIRE
192    return subid;
193 }
194 // ====================================================== translateShape
195 int NewShape::translateShape (double dir[], SubShape* shape)
196 {
197    gp_Trsf transfo;
198    gp_Vec  vecteur        (dir [dir_x], dir [dir_y], dir [dir_z]);
199    transfo.SetTranslation (vecteur);
200
201    TopoDS_Shape shape_orig = shape->getShape ();
202    BRepBuilderAPI_Transform builder (shape_orig, transfo, Standard_True);
203    TopoDS_Shape result = builder.Shape();
204
205    geo_builder.Add (geo_compound, result);
206
207    int  subid  = curr_subid;
208    curr_subid += 2;                       // PROVISOIRE
209    return subid;
210 }
211 // ====================================================== addAssociation
212 void NewShape::addAssociation (Vertex* vertex, int subid, double param)
213 {
214    if (vertex==NULL)
215       return;
216
217    asso_vertex.push_back (vertex);
218    asso_param .push_back (param);
219    asso_vxid  .push_back (subid);
220 }
221 // ====================================================== addAssociation
222 void NewShape::addAssociation (Edge* edge, int subid, double pmin, double pmax)
223 {
224    if (edge==NULL)
225       return;
226
227    if (db0) 
228       {
229       cout << edge->getName() 
230            << " = (" << edge->getVertex(0)->getName() 
231            << ", "   << edge->getVertex(1)->getName() 
232            << ") --> subid= " << subid << " [ " 
233            << pmin << ", " << pmax << "]" << endl;
234       }
235
236    asso_edge.push_back (edge);
237    asso_pmin.push_back (pmin);
238    asso_pmax.push_back (pmax);
239    asso_edid.push_back (subid);
240 }
241 // ====================================================== addAssociation
242 void NewShape::addAssociation (Quad* quad, int subid)
243 {
244    if (quad==NULL)
245       return;
246
247    asso_quad.push_back (quad);
248    asso_quid.push_back (subid);
249 }
250 // ====================================================== closeShape
251 void NewShape::closeShape ()
252 {
253    geo_shape     = geo_compound;
254    shape_defined = true;
255    if (db)
256    cout <<  " ------------------- closeShape " << el_name << endl;
257    parseShape (geo_shape);
258
259    int nombre = asso_edge.size ();
260    for (int nro = 0 ; nro < nombre ; ++nro)
261        asso_edge[nro]->addAssociation (this, asso_edid[nro], asso_pmin[nro],
262                                                              asso_pmax[nro]);
263    nombre = asso_quad.size ();
264    for (int nro = 0 ; nro < nombre ; ++nro)
265        asso_quad[nro]->addAssociation (this, asso_quid[nro]);
266
267    Real3 point;
268    nombre = asso_vertex.size ();
269    for (int nro = 0 ; nro < nombre ; ++nro)
270        {
271        EdgeShape* line   = findEdge (asso_vxid[nro]);
272        Vertex*    vertex = asso_vertex[nro];
273        if (line!=NULL && vertex!=NULL && NOT vertex->isAssociated())
274           {
275           line->getPoint (asso_param[nro], point);
276           asso_vertex[nro]->setAssociation (point);
277           }
278        }
279
280 }
281 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
282 // ====================================================== findVertex
283 VertexShape* NewShape::findVertex (int shid)
284 {
285    int nbre = tab_vertex.size ();
286    for (int nro=0 ; nro < nbre ; nro++)
287        {
288        VertexShape* shape = tab_vertex [nro];
289        if (shape->getIdent() == shid)
290           return shape;
291        }
292    return NULL;
293 }
294 // ====================================================== findEdge
295 EdgeShape* NewShape::findEdge (int shid)
296 {
297    int nbre = tab_edge.size ();
298    for (int nro=0 ; nro < nbre ; nro++)
299        {
300        EdgeShape* shape = tab_edge [nro];
301        if (shape->getIdent() == shid)
302           return shape;
303        }
304    return NULL;
305 }
306 // ====================================================== findFace
307 FaceShape* NewShape::findFace (int shid)
308 {
309    int nbre = tab_face.size ();
310    for (int nro=0 ; nro < nbre ; nro++)
311        {
312        FaceShape* shape = tab_face [nro];
313        if (shape->getIdent() == shid)
314           return shape;
315        }
316    return NULL;
317 }
318 // ====================================================== findSubShape
319 SubShape* NewShape::findSubShape (int shid)
320 {
321    SubShape* shape = findEdge (shid);
322    if (shape==NULL)
323        shape = findVertex (shid);
324    if (shape==NULL)
325        shape = findFace (shid);
326
327    return shape;
328 }
329 // ====================================================== getVertex
330 int NewShape::getVertex (int nro)
331 {
332    if (nro <0 || nro >= (int) tab_vertex.size())
333       return 0;
334
335    SubShape* shape = tab_vertex [nro];
336    return shape->getIdent() ;
337 }
338 // ====================================================== getEdge
339 int NewShape::getEdge   (int nro)
340 {
341    if (nro <0 || nro >= (int) tab_edge.size())
342       return 0;
343
344    SubShape* shape = tab_edge [nro];
345    return shape->getIdent() ;
346 }
347 // ====================================================== getFace
348 int NewShape::getFace   (int nro)
349 {
350    if (nro <0 || nro >= (int) tab_face.size())
351       return 0;
352
353    SubShape* shape = tab_face [nro];
354    return shape->getIdent() ;
355 }
356
357 // ====================================================== getNameVertex
358 cpchar NewShape::getNameVertex  (int nro)
359 {
360    if (nro <0 || nro >= (int) tab_vertex.size())
361       return "?";
362
363    SubShape* shape = tab_vertex [nro];
364    return shape->getName() ;
365 }
366 // ====================================================== getNameEdge
367 cpchar NewShape::getNameEdge    (int nro)
368 {
369    if (nro <0 || nro >= (int) tab_edge.size())
370       return "?";
371
372    SubShape* shape = tab_edge [nro];
373    return shape->getName() ;
374 }
375 // ====================================================== getNameFace
376 cpchar NewShape::getNameFace    (int nro)
377 {
378    if (nro <0 || nro >= (int) tab_face.size())
379       return "?";
380
381    SubShape* shape = tab_face [nro];
382    return shape->getName() ;
383 }
384 // ====================================================== getFaceShape
385 FaceShape* NewShape::getFaceShape (int nro)
386 {
387    if (nro <0 || nro >= (int) tab_face.size())
388       return 0;
389
390    FaceShape* shape = tab_face [nro];
391    return shape;
392 }
393 // ====================================================== getEdgeShape
394 EdgeShape* NewShape::getEdgeShape (int nro)
395 {
396    if (nro <0 || nro >= (int) tab_edge.size())
397       return 0;
398
399    EdgeShape* shape = tab_edge [nro];
400    return shape;
401 }
402 // ====================================================== getVertexShape
403 VertexShape* NewShape::getVertexShape (int nro)
404 {
405    if (nro <0 || nro >= (int) tab_vertex.size())
406       return 0;
407
408    VertexShape* shape = tab_vertex [nro];
409    return shape;
410 }
411 // ====================================================== addPoint
412 int NewShape::addPoint (double* point)
413 {
414    char suffix [32];
415    int  subid = tab_vertex.size() + 2;
416
417    sprintf (suffix, ":vertex_%02d", subid);
418    string name = el_name + suffix;
419
420    VertexShape* sub_shape = new VertexShape (this, subid, point);
421    sub_shape->setName (name);
422    tab_vertex.push_back (sub_shape);
423    return subid;
424 }
425 // ===================================================== saveBrep
426 int NewShape::saveBrep ()
427 {
428    string filename = el_name + ".brep";
429
430    int ier   = updateBrep ();
431    if (ier != HOK)
432       return ier;
433
434    pfile fic = fopen (filename.c_str(), "w");
435    if (fic==NULL)
436       return HERR;
437
438    fprintf (fic, "%s\n", geo_brep.c_str());
439    fclose  (fic);
440    return HOK;
441 }
442 // ====================================================== saveXml
443 void NewShape::saveXml (XmlWriter* xml)
444 {
445    if (sh_origin==SH_CLOUD)
446       {
447       int nbre = tab_vertex.size();
448       xml->addMark ("Cloud");
449       for (int nro=0 ; nro<nbre ; nro++)
450           tab_vertex[nro]->saveXml (xml);
451       xml->closeMark ();
452       return;
453       }
454
455    char buffer [32];
456    int  ya1brep = updateBrep ();
457
458    xml->openMark     ("Shape");
459    xml->addAttribute ("id",    getName (buffer));
460    xml->addAttribute ("type",  sh_origin);
461    if (el_name!=buffer)
462       xml->addAttribute ("name", el_name);
463
464    if (ya1brep == HOK)
465       {
466       clean_brep (geo_brep);
467       xml->addAttribute ("brep",  geo_brep.c_str());
468       }
469    xml->closeMark ();
470 }
471 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
472 // ===================================================== parseShape
473 void NewShape::parseShape (const TopoDS_Shape& shape)
474 {
475    push_level ();
476    addSubShape (shape);
477
478    TopoDS_Iterator iter (shape);
479    for (; iter.More(); iter.Next())
480        {
481        TopoDS_Shape sub_shape = iter.Value();
482        parseShape (sub_shape);
483        }
484
485    pop_level ();
486 }
487 // ===================================================== addSubShape
488 void NewShape::addSubShape (const TopoDS_Shape& shape)
489 {
490    char chnum [32];
491    string name;
492    sh_indice ++;
493
494    int subid = map_shape.Add (shape);
495    int type  = shape.ShapeType();
496
497    switch (type)
498       {
499       case TopAbs_FACE :
500            sprintf (chnum, ":face_%02d", subid);
501            name = el_name + chnum;
502            if (subid > sh_face_max)
503               {
504               FaceShape* sub_shape = new FaceShape (this, subid);
505               sub_shape->setName (name);
506               tab_face.push_back (sub_shape);
507               sh_face_max = subid;
508               }
509            break;
510       case TopAbs_EDGE  :
511            sprintf (chnum, ":edge_%02d", subid);
512            name = el_name + chnum;
513            if (subid > sh_edge_max)
514               {
515               EdgeShape* sub_shape = new EdgeShape (this, subid);
516               sub_shape->setName (name);
517               tab_edge.push_back (sub_shape);
518               sh_edge_max = subid;
519               }
520            break;
521       case TopAbs_VERTEX :
522            sprintf (chnum, ":vertex_%02d", subid);
523            name = el_name + chnum;
524            if (subid > sh_vertex_max)
525               {
526               VertexShape* sub_shape = new VertexShape (this, subid);
527               sub_shape->setName (name);
528               tab_vertex.push_back (sub_shape);
529               sh_vertex_max = subid;
530               }
531            break;
532       default : ;
533            sprintf (chnum, "type=%d, subid=%02d", type, subid);
534            name   = chnum;
535       }
536
537    if (db0)
538       {
539       sprintf (chnum, "%4d : ", sh_indice);
540       cout <<  chnum;
541       for (int nro=1; nro<sh_level; nro++) cout << " | ";
542       cout <<  name;
543
544       if (type == TopAbs_VERTEX)
545          {
546          TopoDS_Vertex gver = TopoDS::Vertex (shape);
547          gp_Pnt      gpoint = BRep_Tool::Pnt (gver);
548
549          cout << " = (" << gpoint.X()
550               << ","    << gpoint.Y()
551               << ","    << gpoint.Z() << ")";
552          }
553       cout << endl;
554       }
555 }
556 // ===================================================== updateShape
557 int NewShape::updateShape ()
558 {
559    if (shape_defined)
560       return HOK;
561
562    if (NOT brep_defined)
563       return HERR;
564
565    shape_defined = true;
566    geom_brep2shape (geo_brep, geo_shape);
567    cout <<  " ------------------- updateShape " << el_name << endl;
568    parseShape (geo_shape);
569    return HOK;
570 }
571 // ===================================================== updateBrep
572 int NewShape::updateBrep ()
573 {
574    if (brep_defined)
575       return HOK;
576
577    if (NOT shape_defined)
578       return HERR;
579
580    brep_defined = true;
581    geom_make_brep (geo_shape, geo_brep);
582    return HOK;
583 }
584 END_NAMESPACE_HEXA