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