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