Salome HOME
79ac508719eff565a7abae318c730b9008ac7f2a
[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/ 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
32 #include "HexKas_functions.hxx"
33
34 #include "HexXmlWriter.hxx"
35 #include "HexXmlTree.hxx"
36
37 #ifndef NO_CASCADE
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
48 #include <BRep_Tool.hxx>
49
50
51 #include <gp_Pnt.hxx>
52 #include <gp_Pln.hxx>
53 #include <gp_Dir.hxx>
54 #include <gp_Lin.hxx>
55 #include <gp_Circ.hxx>
56
57
58 BEGIN_NAMESPACE_HEXA
59
60 static bool db  = on_debug ();  // == getenv ("HEXA_DB") > 0
61 static bool db0 = true;
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       cout <<  " ------------------- setShape " << el_name << 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    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         << 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    cout << " .... AddSphere subid " << curr_subid << " : rayon=" << radius
167         << " centre = " << milieu[dir_x] << "," << milieu[dir_y]
168         << "," << milieu[dir_z] << endl;
169
170    int  subid  = curr_subid;
171    curr_subid += 7;
172    return subid;
173 }
174 // ====================================================== addAssociation
175 void NewShape::addAssociation (Vertex* vertex, int subid, double param)
176 {
177    if (vertex==NULL)
178       return;
179
180    asso_vertex.push_back (vertex);
181    asso_param .push_back (param);
182    asso_vxid  .push_back (subid);
183 }
184 // ====================================================== addAssociation
185 void NewShape::addAssociation (Edge* edge, int subid, double pmin, double pmax)
186 {
187    if (edge==NULL)
188       return;
189
190    asso_edge.push_back (edge);
191    asso_pmin.push_back (pmin);
192    asso_pmax.push_back (pmax);
193    asso_edid.push_back (subid);
194 }
195 // ====================================================== addAssociation
196 void NewShape::addAssociation (Quad* quad, int subid)
197 {
198    if (quad==NULL)
199       return;
200
201    asso_quad.push_back (quad);
202    asso_quid.push_back (subid);
203 }
204 // ====================================================== closeShape
205 void NewShape::closeShape ()
206 {
207    geo_shape     = geo_compound;
208    shape_defined = true;
209    if (db)
210    cout <<  " ------------------- closeShape " << el_name << endl;
211    parseShape (geo_shape);
212
213    int nombre = asso_edge.size ();
214    for (int nro = 0 ; nro < nombre ; ++nro)
215        asso_edge[nro]->addAssociation (this, asso_edid[nro], asso_pmin[nro],
216                                                              asso_pmax[nro]);
217    nombre = asso_quad.size ();
218    for (int nro = 0 ; nro < nombre ; ++nro)
219        asso_quad[nro]->addAssociation (this, asso_quid[nro]);
220
221    Real3 point;
222    nombre = asso_vertex.size ();
223    for (int nro = 0 ; nro < nombre ; ++nro)
224        {
225        EdgeShape* line   = findEdge (asso_vxid[nro]);
226        Vertex*    vertex = asso_vertex[nro];
227        if (line!=NULL && vertex!=NULL && NOT vertex->isAssociated())
228           {
229           line->getPoint (asso_param[nro], point);
230           asso_vertex[nro]->setAssociation (point);
231           }
232        }
233
234 }
235 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
236 // ====================================================== findVertex
237 VertexShape* NewShape::findVertex (int shid)
238 {
239    int nbre = tab_vertex.size ();
240    for (int nro=0 ; nro < nbre ; nro++)
241        {
242        VertexShape* shape = tab_vertex [nro];
243        if (shape->getIdent() == shid)
244           return shape;
245        }
246    return NULL;
247 }
248 // ====================================================== findEdge
249 EdgeShape* NewShape::findEdge (int shid)
250 {
251    int nbre = tab_edge.size ();
252    for (int nro=0 ; nro < nbre ; nro++)
253        {
254        EdgeShape* shape = tab_edge [nro];
255        if (shape->getIdent() == shid)
256           return shape;
257        }
258    return NULL;
259 }
260 // ====================================================== findFace
261 FaceShape* NewShape::findFace (int shid)
262 {
263    int nbre = tab_face.size ();
264    for (int nro=0 ; nro < nbre ; nro++)
265        {
266        FaceShape* shape = tab_face [nro];
267        if (shape->getIdent() == shid)
268           return shape;
269        }
270    return NULL;
271 }
272 // ====================================================== findSubShape
273 SubShape* NewShape::findSubShape (int shid)
274 {
275    SubShape* shape = findEdge (shid);
276    if (shape==NULL)
277        shape = findVertex (shid);
278    if (shape==NULL)
279        shape = findFace (shid);
280
281    return shape;
282 }
283 // ====================================================== getVertex
284 int NewShape::getVertex (int nro)
285 {
286    if (nro <0 || nro >= tab_vertex.size())
287       return 0;
288
289    SubShape* shape = tab_vertex [nro];
290    return shape->getIdent() ;
291 }
292 // ====================================================== getEdge
293 int NewShape::getEdge   (int nro)
294 {
295    if (nro <0 || nro >= tab_edge.size())
296       return 0;
297
298    SubShape* shape = tab_edge [nro];
299    return shape->getIdent() ;
300 }
301 // ====================================================== getFace
302 int NewShape::getFace   (int nro)
303 {
304    if (nro <0 || nro >= tab_face.size())
305       return 0;
306
307    SubShape* shape = tab_face [nro];
308    return shape->getIdent() ;
309 }
310
311 // ====================================================== getNameVertex
312 cpchar NewShape::getNameVertex  (int nro)
313 {
314    if (nro <0 || nro >= tab_vertex.size())
315       return "?";
316
317    SubShape* shape = tab_vertex [nro];
318    return shape->getName() ;
319 }
320 // ====================================================== getNameEdge
321 cpchar NewShape::getNameEdge    (int nro)
322 {
323    if (nro <0 || nro >= tab_edge.size())
324       return "?";
325
326    SubShape* shape = tab_edge [nro];
327    return shape->getName() ;
328 }
329 // ====================================================== getNameFace
330 cpchar NewShape::getNameFace    (int nro)
331 {
332    if (nro <0 || nro >= tab_face.size())
333       return "?";
334
335    SubShape* shape = tab_face [nro];
336    return shape->getName() ;
337 }
338 // ====================================================== getFaceShape
339 FaceShape* NewShape::getFaceShape (int nro)
340 {
341    if (nro <0 || nro >= tab_face.size())
342       return 0;
343
344    FaceShape* shape = tab_face [nro];
345    return shape;
346 }
347 // ====================================================== getEdgeShape
348 EdgeShape* NewShape::getEdgeShape (int nro)
349 {
350    if (nro <0 || nro >= tab_edge.size())
351       return 0;
352
353    EdgeShape* shape = tab_edge [nro];
354    return shape;
355 }
356 // ====================================================== getVertexShape
357 VertexShape* NewShape::getVertexShape (int nro)
358 {
359    if (nro <0 || nro >= tab_vertex.size())
360       return 0;
361
362    VertexShape* shape = tab_vertex [nro];
363    return shape;
364 }
365 // ====================================================== addPoint
366 int NewShape::addPoint (double* point)
367 {
368    char suffix [32];
369    int  subid = tab_vertex.size() + 1;
370
371    sprintf (suffix, ":vertex%02d", subid);
372    string name = el_name + suffix;
373
374    VertexShape* sub_shape = new VertexShape (this, subid, point);
375    sub_shape->setName (name);
376    tab_vertex.push_back (sub_shape);
377    return subid;
378 }
379 // ===================================================== saveBrep
380 int NewShape::saveBrep ()
381 {
382    string filename = el_name + ".brep";
383
384    int ier   = updateBrep ();
385    if (ier != HOK)
386       return ier;
387
388     pfile fic = fopen (filename.c_str(), "w");
389     if (fic==NULL)
390        return HERR;
391
392     fprintf (fic, "%s\n", geo_brep.c_str());
393     fclose  (fic);
394 }
395 // ====================================================== saveXml
396 void NewShape::saveXml (XmlWriter* xml)
397 {
398    if (sh_origin==SH_CLOUD)
399       {
400       int nbre = tab_vertex.size();
401       xml->addMark ("Cloud");
402       for (int nro=0 ; nro<nbre ; nro++)
403           tab_vertex[nro]->saveXml (xml);
404       xml->closeMark ();
405       return;
406       }
407
408    char buffer [32];
409    int  ya1brep = updateBrep ();
410
411    xml->openMark     ("Shape");
412    xml->addAttribute ("id",    getName (buffer));
413    xml->addAttribute ("type",  sh_origin);
414    if (el_name!=buffer)
415       xml->addAttribute ("name", el_name);
416
417    if (ya1brep == HOK)
418       {
419       clean_brep (geo_brep);
420       xml->addAttribute ("brep",  geo_brep.c_str());
421       }
422    xml->closeMark ();
423 }
424 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
425 // ===================================================== parseShape
426 void NewShape::parseShape (const TopoDS_Shape& shape)
427 {
428    push_level ();
429    addSubShape (shape);
430
431    TopoDS_Iterator iter (shape);
432    for (; iter.More(); iter.Next())
433        {
434        TopoDS_Shape sub_shape = iter.Value();
435        parseShape (sub_shape);
436        }
437
438    pop_level ();
439 }
440 // ===================================================== addSubShape
441 void NewShape::addSubShape (const TopoDS_Shape& shape)
442 {
443    char chnum [32];
444    string name;
445    sh_indice ++;
446
447    int subid = map_shape.Add (shape);
448    int type  = shape.ShapeType();
449
450    switch (type)
451       {
452       case TopAbs_FACE :
453            sprintf (chnum, ":face_%02d", subid);
454            name = el_name + chnum;
455            if (subid > sh_face_max)
456               {
457               FaceShape* sub_shape = new FaceShape (this, subid);
458               sub_shape->setName (name);
459               tab_face.push_back (sub_shape);
460               sh_face_max = subid;
461               }
462            break;
463       case TopAbs_EDGE  :
464            sprintf (chnum, ":edge_%02d", subid);
465            name = el_name + chnum;
466            if (subid > sh_edge_max)
467               {
468               EdgeShape* sub_shape = new EdgeShape (this, subid);
469               sub_shape->setName (name);
470               tab_edge.push_back (sub_shape);
471               sh_edge_max = subid;
472               }
473            break;
474       case TopAbs_VERTEX :
475            sprintf (chnum, ":vertex_%02d", subid);
476            name = el_name + chnum;
477            if (subid > sh_vertex_max)
478               {
479               VertexShape* sub_shape = new VertexShape (this, subid);
480               sub_shape->setName (name);
481               tab_vertex.push_back (sub_shape);
482               sh_vertex_max = subid;
483               }
484            break;
485       default : ;
486            sprintf (chnum, "type=%d, subid=%02d", type, subid);
487            name   = chnum;
488       }
489
490    if (db0)
491       {
492       sprintf (chnum, "%4d : ", sh_indice);
493       cout <<  chnum;
494       for (int nro=1; nro<sh_level; nro++) cout << " | ";
495       cout <<  name;
496
497       if (type == TopAbs_VERTEX)
498          {
499          TopoDS_Vertex gver = TopoDS::Vertex (shape);
500          gp_Pnt      gpoint = BRep_Tool::Pnt (gver);
501
502          cout << " = (" << gpoint.X()
503               << ","    << gpoint.Y()
504               << ","    << gpoint.Z() << ")";
505          }
506       cout << endl;
507       }
508 }
509 // ===================================================== updateShape
510 int NewShape::updateShape ()
511 {
512    if (shape_defined)
513       return HOK;
514
515    if (NOT brep_defined)
516       return HERR;
517
518    shape_defined = true;
519    geom_brep2shape (geo_brep, geo_shape);
520    cout <<  " ------------------- updateShape " << el_name << endl;
521    parseShape (geo_shape);
522    return HOK;
523 }
524 // ===================================================== updateBrep
525 int NewShape::updateBrep ()
526 {
527    if (brep_defined)
528       return HOK;
529
530    if (NOT shape_defined)
531       return HERR;
532
533    brep_defined = true;
534    geom_make_brep (geo_shape, geo_brep);
535    return HOK;
536 }
537 END_NAMESPACE_HEXA
538
539 #else
540
541 // ====================================================== ===================
542 BEGIN_NAMESPACE_HEXA
543 NewShape::NewShape (Document* dad) : EltBase  (dad, EL_SHAPE) {}
544 void      NewShape::setShape (const TopoDS_Shape& shape)      {}
545 void      NewShape::saveXml  (XmlWriter* xml)                 {}
546 SubShape* NewShape::findSubShape (int shid)             { return NULL; }
547 SubShape* NewShape::findVertex   (int shid)             { return NULL; }
548 SubShape* NewShape::findEdge     (int shid)             { return NULL; }
549 SubShape* NewShape::findFace     (int shid)             { return NULL; }
550
551 int NewShape::getVertex (int nro)     { return 0 ; }
552 int NewShape::getEdge   (int nro)     { return 0 ; }
553 int NewShape::getFace   (int nro)     { return 0 ; }
554
555 cpchar NewShape::getNameVertex  (int nro)     { return "Nothing" ; }
556 cpchar NewShape::getNameEdge    (int nro)     { return "Nothing" ; }
557 cpchar NewShape::getNameFace    (int nro)     { return "Nothing" ; }
558
559 END_NAMESPACE_HEXA
560 #endif