Salome HOME
Add support for tetra, pyramid and prism
[modules/smesh.git] / src / SMESH / SMESH_Gen.cxx
1 //  SMESH SMESH : implementaion of SMESH idl descriptions
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_Gen.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESH_Gen.hxx"
30 #include "SMESH_subMesh.hxx"
31 #include "SMDS_MeshElement.hxx"
32 #include "SMDS_MeshNode.hxx"
33
34 #include <gp_Pnt.hxx>
35 #include <BRep_Tool.hxx>
36
37 #include "utilities.h"
38 #include "OpUtil.hxx"
39
40 //=============================================================================
41 /*!
42  *  default constructor:
43  */
44 //=============================================================================
45
46 SMESH_Gen::SMESH_Gen()
47 {
48         MESSAGE("SMESH_Gen::SMESH_Gen");
49         _localId = 0;
50         _hypothesisFactory.SetGen(this);
51 }
52
53 //=============================================================================
54 /*!
55  * 
56  */
57 //=============================================================================
58
59 SMESH_Gen::~SMESH_Gen()
60 {
61         MESSAGE("SMESH_Gen::~SMESH_Gen");
62 }
63
64 //=============================================================================
65 /*!
66  * 
67  */
68 //=============================================================================
69
70 SMESH_Hypothesis *SMESH_Gen::CreateHypothesis(const char *anHyp, int studyId)
71         throw(SALOME_Exception)
72 {
73
74         MESSAGE("CreateHypothesis("<<anHyp<<","<<studyId<<")");
75         // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document
76
77         StudyContextStruct *myStudyContext = GetStudyContext(studyId);
78
79         // create a new hypothesis object, store its ref. in studyContext
80
81         SMESH_Hypothesis *myHypothesis = _hypothesisFactory.Create(anHyp, studyId);
82         int hypId = myHypothesis->GetID();
83         myStudyContext->mapHypothesis[hypId] = myHypothesis;
84         SCRUTE(studyId);
85         SCRUTE(hypId);
86
87         // store hypothesis in SMESHDS document
88
89         myStudyContext->myDocument->AddHypothesis(myHypothesis);
90         return myHypothesis;
91 }
92
93 //=============================================================================
94 /*!
95  * 
96  */
97 //=============================================================================
98
99 SMESH_Mesh *SMESH_Gen::Init(int studyId, const TopoDS_Shape & aShape)
100 throw(SALOME_Exception)
101 {
102         MESSAGE("SMESH_Gen::Init");
103 //   if (aShape.ShapeType() == TopAbs_COMPOUND)
104 //     {
105 //       INFOS("Mesh Compound not yet implemented!");
106 //       throw(SALOME_Exception(LOCALIZED("Mesh Compound not yet implemented!")));
107 //     }
108
109         // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document
110
111         StudyContextStruct *myStudyContext = GetStudyContext(studyId);
112
113         // create a new SMESH_mesh object 
114
115         SMESH_Mesh *mesh = new SMESH_Mesh(_localId++,
116                 studyId,
117                 this,
118                 myStudyContext->myDocument);
119         myStudyContext->mapMesh[_localId] = mesh;
120
121         // associate a TopoDS_Shape to the mesh
122
123         mesh->ShapeToMesh(aShape);
124         return mesh;
125 }
126
127 //=============================================================================
128 /*!
129  * 
130  */
131 //=============================================================================
132
133 bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
134 throw(SALOME_Exception)
135 {
136         MESSAGE("SMESH_Gen::Compute");
137 //   bool isDone = false;
138 /* 
139 Algo : s'appuie ou non sur une geometrie
140 Si geometrie:
141 Vertex : rien à faire (range le point)
142 Edge, Wire, collection d'edge et wire : 1D
143 Face, Shell, collection de Face et Shells : 2D
144 Solid, Collection de Solid : 3D
145 */
146 // *** corriger commentaires
147         // check hypothesis associated to the mesh :
148         // - only one algo : type compatible with the type of the shape
149         // - hypothesis = compatible with algo
150         //    - check if hypothesis are applicable to this algo
151         //    - check contradictions within hypothesis
152         //    (test if enough hypothesis is done further)
153
154         bool ret = true;
155
156         SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
157 //   SCRUTE(sm);
158         SMESH_subMesh *smToCompute = sm->GetFirstToCompute();
159         while (smToCompute)
160         {
161                 TopoDS_Shape subShape = smToCompute->GetSubShape();
162                 int dim = GetShapeDim(subShape);
163                 //SCRUTE(dim);
164                 if (dim > 0)
165                 {
166                         bool ret1 = smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE);
167                         ret = ret && ret1;
168                 }
169                 else
170                 {
171                         ASSERT(dim == 0);
172                         ASSERT(smToCompute->_vertexSet == false);
173                         TopoDS_Vertex V1 = TopoDS::Vertex(subShape);
174                         gp_Pnt P1 = BRep_Tool::Pnt(V1);
175                         SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
176                         //MESSAGE("point "<<nodeId<<" "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z());
177                         SMDS_MeshNode * node = meshDS->AddNode(P1.X(), P1.Y(), P1.Z());
178                         meshDS->SetNodeOnVertex(node, V1);
179                         smToCompute->GetSubMeshDS();
180                         smToCompute->_vertexSet = true;
181                         smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE);
182                 }
183                 smToCompute = sm->GetFirstToCompute();
184         }
185
186         return ret;
187 }
188
189 //=============================================================================
190 /*!
191  * 
192  */
193 //=============================================================================
194
195 SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
196 {
197         //MESSAGE("SMESH_Gen::GetAlgo");
198
199         const SMESHDS_Hypothesis *theHyp = NULL;
200         SMESH_Algo *algo = NULL;
201         const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
202         int hypType;
203         int hypId;
204         int algoDim;
205
206         // try shape first, then main shape
207
208         TopoDS_Shape mainShape = meshDS->ShapeToMesh();
209         const TopoDS_Shape *shapeToTry[2] = { &aShape, &mainShape };
210
211         for (int iShape = 0; iShape < 2; iShape++)
212         {
213                 TopoDS_Shape tryShape = (*shapeToTry[iShape]);
214
215                 const list<const SMESHDS_Hypothesis*>& listHyp =
216                         meshDS->GetHypothesis(tryShape);
217                 list<const SMESHDS_Hypothesis*>::const_iterator it=listHyp.begin();
218                 
219                 int nb_algo = 0;
220                 int shapeDim = GetShapeDim(aShape);
221                 int typeOfShape = aShape.ShapeType();
222
223                 while (it!=listHyp.end())
224                 {
225                         const SMESHDS_Hypothesis *anHyp = *it;
226                         hypType = anHyp->GetType();
227                         //SCRUTE(hypType);
228                         if (hypType > SMESHDS_Hypothesis::PARAM_ALGO)
229                         {
230                                 switch (hypType)
231                                 {
232                                 case SMESHDS_Hypothesis::ALGO_1D:
233                                         algoDim = 1;
234                                         break;
235                                 case SMESHDS_Hypothesis::ALGO_2D:
236                                         algoDim = 2;
237                                         break;
238                                 case SMESHDS_Hypothesis::ALGO_3D:
239                                         algoDim = 3;
240                                         break;
241                                 default:
242                                         algoDim = 0;
243                                         break;
244                                 }
245                                 //SCRUTE(algoDim);
246                                 //SCRUTE(shapeDim);
247                                 //SCRUTE(typeOfShape);
248                                 if (shapeDim == algoDim)        // count only algos of shape dim.
249                                 {                               // discard algos for subshapes
250                                         hypId = anHyp->GetID(); // (of lower dim.)
251                                         ASSERT(_mapAlgo.find(hypId) != _mapAlgo.end());
252                                         SMESH_Algo *anAlgo = _mapAlgo[hypId];
253                                         //SCRUTE(anAlgo->GetShapeType());
254                                         //if (anAlgo->GetShapeType() == typeOfShape)
255                                         if ((anAlgo->GetShapeType()) & (1 << typeOfShape))
256                                         {                       // only specific TopoDS_Shape
257                                                 nb_algo++;
258                                                 theHyp = anHyp;
259                                         }
260                                 }
261                         }
262                         if (nb_algo > 1) return NULL;   // more than one algo
263                         it++;
264                 }
265                 if (nb_algo == 1)               // one algo found : OK
266                         break;                          // do not try a parent shape
267         }
268
269         if (!theHyp)
270                 return NULL;                    // no algo found
271
272         hypType = theHyp->GetType();
273         hypId = theHyp->GetID();
274
275         ASSERT(_mapAlgo.find(hypId) != _mapAlgo.end());
276         algo = _mapAlgo[hypId];
277         //MESSAGE("Algo found " << algo->GetName() << " Id " << hypId);
278         return algo;
279 }
280
281 //=============================================================================
282 /*!
283  * 
284  */
285 //=============================================================================
286
287 StudyContextStruct *SMESH_Gen::GetStudyContext(int studyId)
288 {
289         // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document
290
291         if (_mapStudyContext.find(studyId) == _mapStudyContext.end())
292         {
293                 _mapStudyContext[studyId] = new StudyContextStruct;
294                 _mapStudyContext[studyId]->myDocument = new SMESHDS_Document(studyId);
295         }
296         StudyContextStruct *myStudyContext = _mapStudyContext[studyId];
297 //   ASSERT(_mapStudyContext.find(studyId) != _mapStudyContext.end());
298         return myStudyContext;
299 }
300
301 //=============================================================================
302 /*!
303  * 
304  */
305 //=============================================================================
306
307 void SMESH_Gen::Save(int studyId, const char *aUrlOfFile)
308 {
309 }
310
311 //=============================================================================
312 /*!
313  * 
314  */
315 //=============================================================================
316
317 void SMESH_Gen::Load(int studyId, const char *aUrlOfFile)
318 {
319 }
320
321 //=============================================================================
322 /*!
323  * 
324  */
325 //=============================================================================
326
327 void SMESH_Gen::Close(int studyId)
328 {
329 }
330
331 //=============================================================================
332 /*!
333  * 
334  */
335 //=============================================================================
336
337 const char *SMESH_Gen::ComponentDataType()
338 {
339 }
340
341 //=============================================================================
342 /*!
343  * 
344  */
345 //=============================================================================
346
347 const char *SMESH_Gen::IORToLocalPersistentID(const char *IORString,
348         bool & IsAFile)
349 {
350 }
351
352 //=============================================================================
353 /*!
354  * 
355  */
356 //=============================================================================
357
358 const char *SMESH_Gen::LocalPersistentIDToIOR(const char *aLocalPersistentID)
359 {
360 }
361
362 //=============================================================================
363 /*!
364  * 
365  */
366 //=============================================================================
367
368 int SMESH_Gen::GetShapeDim(const TopoDS_Shape & aShape)
369 {
370         int shapeDim = -1;                      // Shape dimension: 0D, 1D, 2D, 3D
371         int type = aShape.ShapeType();
372         switch (type)
373         {
374 //     case TopAbs_COMPOUND:
375 //       {
376 //  break;
377 //       }
378         case TopAbs_COMPOUND:
379         case TopAbs_COMPSOLID:
380         case TopAbs_SOLID:
381         case TopAbs_SHELL:
382         {
383                 shapeDim = 3;
384                 break;
385         }
386                 //    case TopAbs_SHELL:
387         case TopAbs_FACE:
388         {
389                 shapeDim = 2;
390                 break;
391         }
392         case TopAbs_WIRE:
393         case TopAbs_EDGE:
394         {
395                 shapeDim = 1;
396                 break;
397         }
398         case TopAbs_VERTEX:
399         {
400                 shapeDim = 0;
401                 break;
402         }
403         }
404 //   SCRUTE(shapeDim);
405         return shapeDim;
406 }