]> SALOME platform Git repositories - modules/hexablock.git/blob - src/HEXABLOCK/HexNewShape.cxx
Salome HOME
17ca499cc7ea3abc58188415873329dd4e9d5ca7
[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 // ====================================================== findVertex
295 VertexShape* NewShape::findVertex (double point[])
296 {
297    int nbre = tab_vertex.size ();
298    for (int nro=0 ; nro < nbre ; nro++)
299        {
300        VertexShape* shape = tab_vertex [nro];
301        if (shape->definedBy (point))
302           return shape;
303        }
304    return NULL;
305 }
306 // ====================================================== findEdge
307 EdgeShape* NewShape::findEdge (int shid)
308 {
309    int nbre = tab_edge.size ();
310    for (int nro=0 ; nro < nbre ; nro++)
311        {
312        EdgeShape* shape = tab_edge [nro];
313        if (shape->getIdent() == shid)
314           return shape;
315        }
316    return NULL;
317 }
318 // ====================================================== findEdge
319 EdgeShape* NewShape::findEdge (double p1[], double p2[])
320 {
321    int nbre = tab_edge.size ();
322    for (int nro=0 ; nro < nbre ; nro++)
323        {
324        EdgeShape* shape = tab_edge [nro];
325        if (shape->definedBy (p1, p2))
326           return shape;
327        }
328    return NULL;
329 }
330 // ====================================================== findFace
331 FaceShape* NewShape::findFace (int shid)
332 {
333    int nbre = tab_face.size ();
334    for (int nro=0 ; nro < nbre ; nro++)
335        {
336        FaceShape* shape = tab_face [nro];
337        if (shape->getIdent() == shid)
338           return shape;
339        }
340    return NULL;
341 }
342 // ====================================================== findSubShape
343 SubShape* NewShape::findSubShape (int shid)
344 {
345    SubShape* shape = findEdge (shid);
346    if (shape==NULL)
347        shape = findVertex (shid);
348    if (shape==NULL)
349        shape = findFace (shid);
350
351    return shape;
352 }
353 // ====================================================== getVertex
354 int NewShape::getVertex (int nro)
355 {
356    if (nro <0 || nro >= (int) tab_vertex.size())
357       return 0;
358
359    SubShape* shape = tab_vertex [nro];
360    return shape->getIdent() ;
361 }
362 // ====================================================== getEdge
363 int NewShape::getEdge   (int nro)
364 {
365    if (nro <0 || nro >= (int) tab_edge.size())
366       return 0;
367
368    SubShape* shape = tab_edge [nro];
369    return shape->getIdent() ;
370 }
371 // ====================================================== getFace
372 int NewShape::getFace   (int nro)
373 {
374    if (nro <0 || nro >= (int) tab_face.size())
375       return 0;
376
377    SubShape* shape = tab_face [nro];
378    return shape->getIdent() ;
379 }
380
381 // ====================================================== getNameVertex
382 cpchar NewShape::getNameVertex  (int nro)
383 {
384    if (nro <0 || nro >= (int) tab_vertex.size())
385       return "?";
386
387    SubShape* shape = tab_vertex [nro];
388    return shape->getName() ;
389 }
390 // ====================================================== getNameEdge
391 cpchar NewShape::getNameEdge    (int nro)
392 {
393    if (nro <0 || nro >= (int) tab_edge.size())
394       return "?";
395
396    SubShape* shape = tab_edge [nro];
397    return shape->getName() ;
398 }
399 // ====================================================== getNameFace
400 cpchar NewShape::getNameFace    (int nro)
401 {
402    if (nro <0 || nro >= (int) tab_face.size())
403       return "?";
404
405    SubShape* shape = tab_face [nro];
406    return shape->getName() ;
407 }
408 // ====================================================== getFaceShape
409 FaceShape* NewShape::getFaceShape (int nro)
410 {
411    if (nro <0 || nro >= (int) tab_face.size())
412       return 0;
413
414    FaceShape* shape = tab_face [nro];
415    return shape;
416 }
417 // ====================================================== getEdgeShape
418 EdgeShape* NewShape::getEdgeShape (int nro)
419 {
420    if (nro <0 || nro >= (int) tab_edge.size())
421       return 0;
422
423    EdgeShape* shape = tab_edge [nro];
424    return shape;
425 }
426 // ====================================================== getVertexShape
427 VertexShape* NewShape::getVertexShape (int nro)
428 {
429    if (nro <0 || nro >= (int) tab_vertex.size())
430       return 0;
431
432    VertexShape* shape = tab_vertex [nro];
433    return shape;
434 }
435 // ====================================================== addPoint
436 int NewShape::addPoint (double* point)
437 {
438    char suffix [32];
439    int  subid = tab_vertex.size() + 2;
440
441    sprintf (suffix, ":vertex_%02d", subid);
442    string name = el_name + suffix;
443
444    VertexShape* sub_shape = new VertexShape (this, subid, point);
445    sub_shape->setName (name);
446    tab_vertex.push_back (sub_shape);
447    return subid;
448 }
449 // ===================================================== saveBrep
450 int NewShape::saveBrep ()
451 {
452    string filename = el_name + ".brep";
453
454    int ier   = updateBrep ();
455    if (ier != HOK)
456       return ier;
457
458    pfile fic = fopen (filename.c_str(), "w");
459    if (fic==NULL)
460       return HERR;
461
462    fprintf (fic, "%s\n", geo_brep.c_str());
463    fclose  (fic);
464    return HOK;
465 }
466 // ===================================================== getBrep
467 cpchar NewShape::getBrep ()
468 {
469    int ier   = updateBrep ();
470    if (ier != HOK)
471       return NULL;
472    return geo_brep.c_str();
473 }
474 // ====================================================== saveXml
475 void NewShape::saveXml (XmlWriter* xml)
476 {
477    if (sh_origin==SH_CLOUD)
478       {
479       int nbre = tab_vertex.size();
480       xml->addMark ("Cloud");
481       for (int nro=0 ; nro<nbre ; nro++)
482           tab_vertex[nro]->saveXml (xml);
483       xml->closeMark ();
484       return;
485       }
486
487    char buffer [32];
488    int  ya1brep = updateBrep ();
489
490    xml->openMark     ("Shape");
491    xml->addAttribute ("id",    getName (buffer));
492    xml->addAttribute ("type",  sh_origin);
493    if (el_name!=buffer)
494       xml->addAttribute ("name", el_name);
495
496    if (ya1brep == HOK)
497       {
498       clean_brep (geo_brep);
499       xml->addAttribute ("brep",  geo_brep.c_str());
500       }
501    xml->closeMark ();
502 }
503 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
504 // ===================================================== parseShape
505 void NewShape::parseShape (const TopoDS_Shape& shape)
506 {
507    push_level ();
508    addSubShape (shape);
509
510    TopoDS_Iterator iter (shape);
511    for (; iter.More(); iter.Next())
512        {
513        TopoDS_Shape sub_shape = iter.Value();
514        parseShape (sub_shape);
515        }
516
517    pop_level ();
518 }
519 // ===================================================== addSubShape
520 void NewShape::addSubShape (const TopoDS_Shape& shape)
521 {
522    char chnum [32];
523    string name;
524    sh_indice ++;
525
526    int subid = map_shape.Add (shape);
527    int type  = shape.ShapeType();
528
529    switch (type)
530       {
531       case TopAbs_FACE :
532            sprintf (chnum, ":face_%02d", subid);
533            name = el_name + chnum;
534            if (subid > sh_face_max)
535               {
536               FaceShape* sub_shape = new FaceShape (this, subid);
537               sub_shape->setName (name);
538               tab_face.push_back (sub_shape);
539               sh_face_max = subid;
540               }
541            break;
542       case TopAbs_EDGE  :
543            sprintf (chnum, ":edge_%02d", subid);
544            name = el_name + chnum;
545            if (subid > sh_edge_max)
546               {
547               EdgeShape* sub_shape = new EdgeShape (this, subid);
548               sub_shape->setName (name);
549               tab_edge.push_back (sub_shape);
550               sh_edge_max = subid;
551               }
552            break;
553       case TopAbs_VERTEX :
554            sprintf (chnum, ":vertex_%02d", subid);
555            name = el_name + chnum;
556            if (subid > sh_vertex_max)
557               {
558               VertexShape* sub_shape = new VertexShape (this, subid);
559               sub_shape->setName (name);
560               tab_vertex.push_back (sub_shape);
561               sh_vertex_max = subid;
562               }
563            break;
564       default : ;
565            sprintf (chnum, "type=%d, subid=%02d", type, subid);
566            name   = chnum;
567       }
568
569    if (db0)
570       {
571       sprintf (chnum, "%4d : ", sh_indice);
572       cout <<  chnum;
573       for (int nro=1; nro<sh_level; nro++) cout << " | ";
574       cout <<  name;
575
576       if (type == TopAbs_VERTEX)
577          {
578          TopoDS_Vertex gver = TopoDS::Vertex (shape);
579          gp_Pnt      gpoint = BRep_Tool::Pnt (gver);
580
581          cout << " = (" << gpoint.X()
582               << ","    << gpoint.Y()
583               << ","    << gpoint.Z() << ")";
584          }
585       cout << endl;
586       }
587 }
588 // ===================================================== updateShape
589 int NewShape::updateShape ()
590 {
591    if (shape_defined)
592       return HOK;
593
594    if (NOT brep_defined)
595       return HERR;
596
597    shape_defined = true;
598    geom_brep2shape (geo_brep, geo_shape);
599    cout <<  " ------------------- updateShape " << el_name << endl;
600    parseShape (geo_shape);
601    return HOK;
602 }
603 // ===================================================== updateBrep
604 int NewShape::updateBrep ()
605 {
606    if (brep_defined)
607       return HOK;
608
609    if (NOT shape_defined)
610       return HERR;
611
612    brep_defined = true;
613    geom_make_brep (geo_shape, geo_brep);
614    return HOK;
615 }
616 END_NAMESPACE_HEXA