Salome HOME
9a3e6aa61ca0c730a751737aa55cf187eaef6e0d
[plugins/blsurfplugin.git] / src / BLSURFPlugin / BLSURFPlugin_BLSURF.cxx
1 //  BLSURFPlugin : C++ implementation
2 //
3 //  Copyright (C) 2006  OPEN CASCADE, CEA/DEN, EDF R&D
4 // 
5 //  This library is free software; you can redistribute it and/or 
6 //  modify it under the terms of the GNU Lesser General Public 
7 //  License as published by the Free Software Foundation; either 
8 //  version 2.1 of the License. 
9 // 
10 //  This library is distributed in the hope that it will be useful, 
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
13 //  Lesser General Public License for more details. 
14 // 
15 //  You should have received a copy of the GNU Lesser General Public 
16 //  License along with this library; if not, write to the Free Software 
17 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
18 // 
19 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
20 //
21 //
22 // File    : BLSURFPlugin_BLSURF.cxx
23 // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA)
24 // Date    : 20/03/2006
25 // Project : SALOME
26 //=============================================================================
27 using namespace std;
28
29 #include "BLSURFPlugin_BLSURF.hxx"
30 #include "BLSURFPlugin_Hypothesis.hxx"
31
32 #include <SMESH_Gen.hxx>
33 #include <SMESH_Mesh.hxx>
34 #include <SMESH_ControlsDef.hxx>
35
36 #include <SMESHDS_Mesh.hxx>
37 #include <SMDS_MeshElement.hxx>
38 #include <SMDS_MeshNode.hxx>
39
40 #include <utilities.h>
41
42 #include <list>
43 #include <vector>
44
45 #include <BRep_Tool.hxx>
46 #include <TopExp.hxx>
47 #include <TopExp_Explorer.hxx>
48 #include <TopoDS.hxx>
49 #include <NCollection_Map.hxx>
50
51 #include <cad_occ.h>
52
53 //=============================================================================
54 /*!
55  *  
56  */
57 //=============================================================================
58
59 BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, int studyId,
60                                                SMESH_Gen* gen)
61   : SMESH_2D_Algo(hypId, studyId, gen)
62 {
63   MESSAGE("BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF");
64
65   _name = "BLSURF";
66   _shapeType = (1 << TopAbs_FACE); // 1 bit /shape type
67   _compatibleHypothesis.push_back("BLSURF_Parameters");
68   _requireDescretBoundary = false;
69   _onlyUnaryInput = false;
70   _hypothesis = NULL;
71 }
72
73 //=============================================================================
74 /*!
75  *  
76  */
77 //=============================================================================
78
79 BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF()
80 {
81   MESSAGE("BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF");
82 }
83
84 //=============================================================================
85 /*!
86  *  
87  */
88 //=============================================================================
89
90 bool BLSURFPlugin_BLSURF::CheckHypothesis
91                          (SMESH_Mesh&                          aMesh,
92                           const TopoDS_Shape&                  aShape,
93                           SMESH_Hypothesis::Hypothesis_Status& aStatus)
94 {
95   _hypothesis = NULL;
96
97   list<const SMESHDS_Hypothesis*>::const_iterator itl;
98   const SMESHDS_Hypothesis* theHyp;
99
100   const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
101   int nbHyp = hyps.size();
102   if (!nbHyp)
103   {
104     aStatus = SMESH_Hypothesis::HYP_OK;
105     return true;  // can work with no hypothesis
106   }
107
108   itl = hyps.begin();
109   theHyp = (*itl); // use only the first hypothesis
110
111   string hypName = theHyp->GetName();
112
113   if (hypName == "BLSURF_Parameters")
114   {
115     _hypothesis = static_cast<const BLSURFPlugin_Hypothesis*> (theHyp);
116     ASSERT(_hypothesis);
117     aStatus = SMESH_Hypothesis::HYP_OK;
118   }
119   else
120     aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
121
122   return aStatus == SMESH_Hypothesis::HYP_OK;
123 }
124
125 //=============================================================================
126 /*!
127  * Pass parameters to BLSURF
128  */
129 //=============================================================================
130
131 void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp) {
132   if (hyp) {
133     MESSAGE("BLSURFPlugin_BLSURF::SetParameters");
134     _physicalMesh = (int) hyp->GetPhysicalMesh();
135     _phySize = hyp->GetPhySize();
136     _geometricMesh = (int) hyp->GetGeometricMesh();
137     _angleMeshS = hyp->GetAngleMeshS();
138     _gradation = hyp->GetGradation();
139     _quadAllowed = hyp->GetQuadAllowed();
140     _decimesh = hyp->GetDecimesh();
141   }
142
143   bool BlsurfEnvFile = true;
144
145   if ( BlsurfEnvFile ) {
146     TCollection_AsciiString SalomeExecDir;
147
148     char * Dir = getenv("PWD");
149     SalomeExecDir = Dir;
150     SalomeExecDir += "/blsurf.env";
151
152     ofstream theBlsurfEnv  ( SalomeExecDir.ToCString()  , ios::out);
153     theBlsurfEnv << "verb 10"                          << endl;
154     theBlsurfEnv << "hphy_flag "     << _physicalMesh  << endl;
155     theBlsurfEnv << "hphydef "       << _phySize       << endl;
156     theBlsurfEnv << "hgeo_flag "     << _geometricMesh << endl;
157     theBlsurfEnv << "angle_meshs "   << _angleMeshS    << endl;
158     theBlsurfEnv << "gradation "     << _gradation     << endl;
159     theBlsurfEnv << "topo_points 1"                    << endl;
160     theBlsurfEnv << "topo_project 1"                   << endl;
161     theBlsurfEnv << "topo_curves 1"                    << endl;
162     theBlsurfEnv << "surforient 1"                     << endl;
163     theBlsurfEnv << "decim "         << _decimesh      << endl;
164     theBlsurfEnv.close();
165   }
166 }
167
168 //=============================================================================
169 /*!
170  *
171  */
172 //=============================================================================
173
174 bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) {
175
176   SetParameters(_hypothesis);
177
178   MESSAGE("BLSURFPlugin_BLSURF::Compute");
179
180   if (aShape.ShapeType() == TopAbs_COMPOUND) {
181     cout << "  the shape is a COMPOUND" << endl;
182   }
183   else {
184     cout << "  the shape is UNKNOWN" << endl;
185   };
186
187   int i=0;
188   if (1) {
189     for (TopExp_Explorer expf(aShape, TopAbs_FACE); expf.More(); expf.Next()) {
190       const TopoDS_Shape& face = expf.Current();
191       i++;
192       int j=0;
193       for (TopExp_Explorer expe(face, TopAbs_EDGE); expe.More(); expe.Next()) {
194         const TopoDS_Shape& edge = expe.Current();
195         j++;
196         int k=0;
197         for (TopExp_Explorer expv(edge, TopAbs_VERTEX); expv.More(); expv.Next()) {
198           k++;
199         }
200         // cout << "  face " << i << " and its edge " << j << " has " << k << " vertices" << endl;
201       }
202       // cout << "  face " << i << " has " << j << " edges" << endl;
203     }
204     // cout << "  total number of faces = " << i << endl;
205   }
206
207   BL_SURF mesh;
208   blw_* blw;
209
210   cout << endl;
211   cout << "Beginning of Surface Mesh generation" << endl;
212   cout << endl;
213   if (!mesh.init(aShape))
214     return(false);
215   cout << endl;
216   cout << "End of Surface Mesh generation" << endl;
217   cout << endl;
218   mesh.get_blw(blw);
219
220   SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
221
222   if ( !_decimesh ) {
223     /* cf. export_mesh_all */
224     int j, ip, ic, nptri, is, oriented, iF, nF, idom, ndom, v[5], verb;
225     double centre[3];
226     char element[8];
227
228     verb = blw->env.verb;
229     blw->env.verb = 0;
230     assign_bls_mesh_num(blw);
231     blw->env.verb = verb;
232   
233     FOR (j, 0, 2) {
234       centre[j] = (blw->bls_glo.xyzmin[j] + blw->bls_glo.xyzmax[j]) * 0.5;
235       cout << "centre[" << j << "] : " << centre[j] << endl;
236     }
237
238     /* points sommets des edges et des triangles */
239     nptri = blw->bls_mesh_num.number_of_nodes;
240     if (blw->env.verb >= 10)
241       fprintf(blw->out, "export_salome: surface mesh contains %d vertices\n", nptri);
242     SMDS_MeshNode** nodes = new SMDS_MeshNode*[nptri+1];
243     j = 0;
244     FOR (ip, 1, nptri) {
245       if (blw->bls_glo.vertices_xyz[3*ip-3] == BLHUGE) {
246         if (++j <= 10) {
247               fprintf(blw->out, "export_salome: unconnected vertex %d\n", ip);
248               if (j == 10) fprintf(blw->out, "export_salome: ...\n");
249         }
250         nodes[ip] = meshDS->AddNode(centre[0], centre[1], centre[2]);
251       }
252       else {
253         double floatVal = blw->bls_glo.vertices_xyz[3*ip-3];
254         // cout << "j : " << j << " node nmuber : " << ip << " --> first coordinate = " << floatVal << " != " << BLHUGE << endl;
255         nodes[ip] = meshDS->AddNode(blw->bls_glo.vertices_xyz[3*ip-3], blw->bls_glo.vertices_xyz[3*ip-2], blw->bls_glo.vertices_xyz[3*ip-1]);
256         // cout << "nodes[" << ip << "] : " << blw->bls_glo.vertices_xyz[3*ip-3] << ", "
257         //                                  << blw->bls_glo.vertices_xyz[3*ip-2] << ", "
258         //                                  << blw->bls_glo.vertices_xyz[3*ip-1] << endl;
259       }
260     }
261
262     /* edges */
263     int nbEdges = C3D.number_of_curves;
264     cout << "Number Of Edges : " << nbEdges << endl;
265     FOR (ic, 1, C3D.number_of_curves) {
266       //TopoDS_Edge topo_edge = mesh.all_edges[ic-1]->topology;
267       int np = C3D.TC[ic].number_of_points;
268       cout << "Number Of Nodes for edge " << ic << " : " << np << endl;
269       FOR (ip, 1, np-1) {
270         meshDS->AddEdge(nodes[C3D.TC[ic].iglopc[ip]], nodes[C3D.TC[ic].iglopc[ip+1]]);
271       }
272     }
273
274     /* faces (triangles or quadrilaterals) */ 
275     SMDS_MeshFace* face;
276     if (blw->bls_glo.number_of_patches <= 0) {
277       strcpy(element, "p1");
278     }
279     else {
280       strcpy(element, TC2D[1].ms2d.element);
281     }
282     cout << endl;
283     cout << "Number_of_patches    : " << blw->bls_glo.number_of_patches << endl;
284     cout << "Element              : " << element << endl;
285     cout << "TC2D[1].ms2d.element : " << TC2D[1].ms2d.element << endl;
286     cout << endl;
287     if (STREQUAL(element, "p1")) {
288       if (blw->env.verb >= 10)
289         fprintf(blw->out, "export_salome: surface mesh contains %d triangles\n", blw->bls_mesh_num.ntri);
290       FOR (is, 1, blw->bls_glo.number_of_patches) {
291         TopoDS_Face topo_face = mesh.surfaces[is-1]->topology;
292         oriented = (TC2D[is].surforient >= 0);
293         // cout << endl;
294         // cout << "TC2D[is].surforient : " << TC2D[is].surforient << " --> oriented : " << oriented << endl;
295         nF = TC2D[is].ms2d.jmax_F;
296         ndom = TC2D[is].ms2d.ndom;
297         // cout << "nF   : " << nF   << endl;
298         // cout << "ndom : " << ndom << endl;
299         // cout << endl;
300         FOR (iF, 1, nF) {
301           idom = TC2D[is].ms2d.FRef[iF];
302           if (!(1 <= idom && idom <= ndom))
303             continue;
304           v[0] = TC2D[is].iglops[TC2D[is].ms2d.F[3*iF-3]];
305           v[1] = TC2D[is].iglops[TC2D[is].ms2d.F[3*iF-2]];
306           v[2] = TC2D[is].iglops[TC2D[is].ms2d.F[3*iF-1]];
307           if (v[0]==v[1] || v[1]==v[2] || v[2]==v[0])
308             continue;                                                 /* triangle degenere */
309           // cout << "Triangle " << iF << " of face " << is;
310           if ( oriented) {
311             // cout << " doesn't need to be re-oriented" << endl;
312             face = meshDS->AddFace(nodes[v[2]], nodes[v[1]], nodes[v[0]]);
313           }
314           else {
315             // cout << " needs to be re-oriented" << endl;
316             face = meshDS->AddFace(nodes[v[0]], nodes[v[1]], nodes[v[2]]);
317           }
318               meshDS->SetMeshElementOnShape(face, topo_face);
319         }
320       }
321     }
322     delete nodes;
323   }
324   else {
325     cout << "decimesh is started"  << endl;
326     system("decimesh");
327     cout << "decimesh is finished" << endl;
328
329     FILE* fic = fopen("x_h100.mesh", "r");
330     char buf[200];
331     do {
332       fscanf(fic, "%s\n", buf);
333     }
334     while (strcmp(buf, "Vertices")!=0);
335     int n_vtx;
336     fscanf(fic, "%d\n", &n_vtx);
337     cout << "number of vertices: " << n_vtx << endl;
338
339     SMDS_MeshNode** nodes = new SMDS_MeshNode*[n_vtx+1];
340     double coo_x, coo_y, coo_z;
341     for (int i=1; i<=n_vtx; i++) {
342       fscanf(fic, "%lf %lf %lf %*d\n", &coo_x, &coo_y, &coo_z);
343       nodes[i] = meshDS->AddNode(coo_x, coo_y, coo_z);
344     }
345     cout << "nodes are updated" << endl;
346
347     fscanf(fic, "%*s\n");
348     int n_tri, n1, n2, n3, iFace;
349     SMDS_MeshFace* face;
350     fscanf(fic, "%d\n", &n_tri);
351     cout << "number of triangles: " << n_tri << endl;
352     for (int i=0; i<n_tri; i++) {
353       fscanf(fic, "%d %d %d %d\n", &n1, &n2, &n3, &iFace);
354       face = meshDS->AddFace(nodes[n3], nodes[n2], nodes[n1]);
355     }
356     cout << "triangles are updated" << endl;
357
358     char *keyWord;
359     fscanf(fic, "%s\n", keyWord);
360     cout << "keyWord : " << keyWord << endl;
361     int n_edges;
362     SMDS_MeshEdge* edge;
363     fscanf(fic, "%d\n", &n_edges);
364     cout << "number of edges: " << n_edges << endl;
365     for (int i=0; i<n_edges; i++) {
366       fscanf(fic, "%d %d %*d\n", &n1, &n2);
367       edge = meshDS->AddEdge(nodes[n1], nodes[n2]);
368       //meshDS->SetMeshElementOnShape(edge, topo_edge);
369     }
370     cout << "edges are updated, and finished" << endl;
371
372     fscanf(fic, "%s\n", keyWord); cout << "keyWord : " << keyWord << endl;
373     fscanf(fic, "%s\n", keyWord); cout << "keyWord : " << keyWord << endl;
374     fscanf(fic, "%s\n", keyWord); cout << "keyWord : " << keyWord << endl;
375     fscanf(fic, "%s\n", keyWord); cout << "keyWord : " << keyWord << endl;
376     fscanf(fic, "%s\n", keyWord); cout << "keyWord : " << keyWord << endl;
377     fscanf(fic, "%s\n", keyWord); cout << "keyWord : " << keyWord << endl;
378
379     int number = fscanf(fic, "%lf %lf %*lf\n", &coo_x, &coo_y);
380     cout << "coo_x  : " << coo_x << endl;
381     cout << "coo_y  : " << coo_y << endl;
382     cout << "number : " << number << endl;
383
384     fclose(fic);
385   }
386
387   bool b = mesh.end();
388   return(b);
389 }
390
391 //=============================================================================
392 /*!
393  *  
394  */
395 //=============================================================================
396
397 ostream & BLSURFPlugin_BLSURF::SaveTo(ostream & save)
398 {
399   return save;
400 }
401
402 //=============================================================================
403 /*!
404  *  
405  */
406 //=============================================================================
407
408 istream & BLSURFPlugin_BLSURF::LoadFrom(istream & load)
409 {
410   return load;
411 }
412
413 //=============================================================================
414 /*!
415  *  
416  */
417 //=============================================================================
418
419 ostream & operator << (ostream & save, BLSURFPlugin_BLSURF & hyp)
420 {
421   return hyp.SaveTo( save );
422 }
423
424 //=============================================================================
425 /*!
426  *  
427  */
428 //=============================================================================
429
430 istream & operator >> (istream & load, BLSURFPlugin_BLSURF & hyp)
431 {
432   return hyp.LoadFrom( load );
433 }