1 // SMESH SMESH : implementaion of SMESH idl descriptions
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 // File : SMESH_Mesh.cxx
25 // Author : Paul RASCLE, EDF
29 #include "SMESH_Mesh.hxx"
30 #include "SMESH_subMesh.hxx"
31 #include "SMESH_Gen.hxx"
32 #include "SMESH_Hypothesis.hxx"
33 #include "SMESH_Group.hxx"
34 #include "SMESH_HypoFilter.hxx"
35 #include "SMESHDS_Group.hxx"
36 #include "SMESHDS_Script.hxx"
37 #include "SMESHDS_GroupOnGeom.hxx"
38 #include "SMDS_MeshVolume.hxx"
40 #include "utilities.h"
42 #include "DriverMED_W_SMESHDS_Mesh.h"
43 #include "DriverDAT_W_SMDS_Mesh.h"
44 #include "DriverUNV_W_SMDS_Mesh.h"
45 #include "DriverSTL_W_SMDS_Mesh.h"
47 #include "DriverMED_R_SMESHDS_Mesh.h"
48 #include "DriverUNV_R_SMDS_Mesh.h"
49 #include "DriverSTL_R_SMDS_Mesh.h"
51 #include <BRepTools_WireExplorer.hxx>
52 #include <BRepPrimAPI_MakeBox.hxx>
53 #include <BRep_Builder.hxx>
56 #include <TCollection_AsciiString.hxx>
58 #include <TopTools_ListOfShape.hxx>
59 #include <TopTools_Array1OfShape.hxx>
60 #include <TopTools_ListIteratorOfListOfShape.hxx>
61 #include <TopTools_MapOfShape.hxx>
65 #include "Utils_ExceptHandlers.hxx"
67 // maximum stored group name length in MED file
68 #define MAX_MED_GROUP_NAME_LENGTH 80
71 static int MYDEBUG = 0;
73 static int MYDEBUG = 0;
76 #define cSMESH_Hyp(h) static_cast<const SMESH_Hypothesis*>(h)
78 typedef SMESH_HypoFilter THypType;
80 //=============================================================================
84 //=============================================================================
86 SMESH_Mesh::SMESH_Mesh(int theLocalId,
89 bool theIsEmbeddedMode,
90 SMESHDS_Document* theDocument):
93 MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
95 _studyId = theStudyId;
97 _myDocument = theDocument;
98 _idDoc = theDocument->NewMesh(theIsEmbeddedMode);
99 _myMeshDS = theDocument->GetMesh(_idDoc);
100 _isShapeToMesh = false;
101 _myMeshDS->ShapeToMesh( PseudoShape() );
104 //=============================================================================
108 //=============================================================================
110 SMESH_Mesh::~SMESH_Mesh()
112 INFOS("SMESH_Mesh::~SMESH_Mesh");
115 map < int, SMESH_Group * >::iterator itg;
116 for (itg = _mapGroup.begin(); itg != _mapGroup.end(); itg++) {
117 SMESH_Group *aGroup = (*itg).second;
122 //=============================================================================
124 * \brief Set geometry to be meshed
126 //=============================================================================
128 void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
130 if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh");
132 if ( !aShape.IsNull() && _isShapeToMesh )
133 throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
135 // clear current data
136 if ( !_myMeshDS->ShapeToMesh().IsNull() )
138 // removal of a shape to mesh, delete objects referring to sub-shapes:
140 map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.begin();
141 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
144 // - groups on geometry
145 map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
146 while ( i_gr != _mapGroup.end() ) {
147 if ( dynamic_cast<SMESHDS_GroupOnGeom*>( i_gr->second->GetGroupDS() )) {
148 _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() );
150 _mapGroup.erase( i_gr++ );
155 _mapAncestors.Clear();
158 TopoDS_Shape aNullShape;
159 _myMeshDS->ShapeToMesh( aNullShape );
162 // set a new geometry
163 if ( !aShape.IsNull() )
165 _myMeshDS->ShapeToMesh(aShape);
166 _isShapeToMesh = true;
168 // fill _mapAncestors
169 int desType, ancType;
170 for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
171 for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
172 TopExp::MapShapesAndAncestors ( aShape,
173 (TopAbs_ShapeEnum) desType,
174 (TopAbs_ShapeEnum) ancType,
179 //=======================================================================
181 * \brief Return geometry to be meshed. (It may be a PseudoShape()!)
183 //=======================================================================
185 TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const
187 return _myMeshDS->ShapeToMesh();
190 //=======================================================================
192 * \brief Return a solid which is returned by GetShapeToMesh() if
193 * a real geometry to be meshed was not set
195 //=======================================================================
197 const TopoDS_Solid& SMESH_Mesh::PseudoShape()
199 static TopoDS_Solid aSolid;
200 if ( aSolid.IsNull() )
202 aSolid = BRepPrimAPI_MakeBox(1,1,1);
207 //=======================================================================
208 //function : UNVToMesh
210 //=======================================================================
212 int SMESH_Mesh::UNVToMesh(const char* theFileName)
214 if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<<theFileName);
216 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
217 _isShapeToMesh = true;
218 DriverUNV_R_SMDS_Mesh myReader;
219 myReader.SetMesh(_myMeshDS);
220 myReader.SetFile(theFileName);
221 myReader.SetMeshId(-1);
224 MESSAGE("UNVToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
225 MESSAGE("UNVToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
226 MESSAGE("UNVToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
227 MESSAGE("UNVToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
229 SMDS_MeshGroup* aGroup = (SMDS_MeshGroup*) myReader.GetGroup();
231 TGroupNamesMap aGroupNames = myReader.GetGroupNamesMap();
232 //const TGroupIdMap& aGroupId = myReader.GetGroupIdMap();
233 aGroup->InitSubGroupsIterator();
234 while (aGroup->MoreSubGroups()) {
235 SMDS_MeshGroup* aSubGroup = (SMDS_MeshGroup*) aGroup->NextSubGroup();
236 std::string aName = aGroupNames[aSubGroup];
239 SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId );
241 if(MYDEBUG) MESSAGE("UNVToMesh - group added: "<<aName);
242 SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aSMESHGroup->GetGroupDS() );
244 aGroupDS->SetStoreName(aName.c_str());
245 aSubGroup->InitIterator();
246 const SMDS_MeshElement* aElement = 0;
247 while (aSubGroup->More()) {
248 aElement = aSubGroup->Next();
250 aGroupDS->SMDSGroup().Add(aElement);
254 aGroupDS->SetType(aElement->GetType());
262 //=======================================================================
263 //function : MEDToMesh
265 //=======================================================================
267 int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
269 if(MYDEBUG) MESSAGE("MEDToMesh - theFileName = "<<theFileName<<", mesh name = "<<theMeshName);
271 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
272 _isShapeToMesh = true;
273 DriverMED_R_SMESHDS_Mesh myReader;
274 myReader.SetMesh(_myMeshDS);
275 myReader.SetMeshId(-1);
276 myReader.SetFile(theFileName);
277 myReader.SetMeshName(theMeshName);
278 Driver_Mesh::Status status = myReader.Perform();
280 MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
281 MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
282 MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
283 MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
286 // Reading groups (sub-meshes are out of scope of MED import functionality)
287 list<TNameAndType> aGroupNames = myReader.GetGroupNamesAndTypes();
288 if(MYDEBUG) MESSAGE("MEDToMesh - Nb groups = "<<aGroupNames.size());
290 list<TNameAndType>::iterator name_type = aGroupNames.begin();
291 for ( ; name_type != aGroupNames.end(); name_type++ ) {
292 SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str(), anId );
294 if(MYDEBUG) MESSAGE("MEDToMesh - group added: "<<name_type->first.c_str());
295 SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
297 aGroupDS->SetStoreName( name_type->first.c_str() );
298 myReader.GetGroup( aGroupDS );
305 //=======================================================================
306 //function : STLToMesh
308 //=======================================================================
310 int SMESH_Mesh::STLToMesh(const char* theFileName)
312 if(MYDEBUG) MESSAGE("STLToMesh - theFileName = "<<theFileName);
314 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
315 _isShapeToMesh = true;
316 DriverSTL_R_SMDS_Mesh myReader;
317 myReader.SetMesh(_myMeshDS);
318 myReader.SetFile(theFileName);
319 myReader.SetMeshId(-1);
322 MESSAGE("STLToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
323 MESSAGE("STLToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
324 MESSAGE("STLToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
325 MESSAGE("STLToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
330 //=============================================================================
334 //=============================================================================
336 SMESH_Hypothesis::Hypothesis_Status
337 SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
338 int anHypId ) throw(SALOME_Exception)
340 Unexpect aCatch(SalomeException);
341 if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis");
343 SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
344 if ( !subMesh || !subMesh->GetId())
345 return SMESH_Hypothesis::HYP_BAD_SUBSHAPE;
347 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
348 if ( subMeshDS && subMeshDS->IsComplexSubmesh() ) // group of sub-shapes and maybe of not sub-
350 MESSAGE("AddHypothesis() to complex submesh");
351 // return the worst but not fatal state of all group memebers
352 SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
353 aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
354 aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
355 for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
357 if ( !GetMeshDS()->ShapeToIndex( itS.Value() ))
358 continue; // not sub-shape
359 ret = AddHypothesis( itS.Value(), anHypId );
360 if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
361 aWorstNotFatal = ret;
362 if ( ret < aBestRet )
365 // bind hypotheses to a group just to know
366 SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId];
367 GetMeshDS()->AddHypothesis( aSubShape, anHyp );
369 if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
371 return aWorstNotFatal;
374 StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
375 if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
377 if(MYDEBUG) MESSAGE("Hypothesis ID does not give an hypothesis");
382 throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
385 SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
386 MESSAGE( "SMESH_Mesh::AddHypothesis " << anHyp->GetName() );
388 bool isGlobalHyp = IsMainShape( aSubShape );
390 // NotConformAllowed can be only global
393 string hypName = anHyp->GetName();
394 if ( hypName == "NotConformAllowed" )
396 if(MYDEBUG) MESSAGE( "Hypotesis <NotConformAllowed> can be only global" );
397 return SMESH_Hypothesis::HYP_INCOMPATIBLE;
403 bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
404 int event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
406 SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
409 if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
410 anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
412 event = isAlgo ? SMESH_subMesh::ADD_FATHER_ALGO : SMESH_subMesh::ADD_FATHER_HYP;
414 SMESH_Hypothesis::Hypothesis_Status ret2 =
415 subMesh->SubMeshesAlgoStateEngine(event, anHyp);
419 // check concurent hypotheses on ansestors
420 if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
422 SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
423 while ( smIt->more() ) {
424 SMESH_subMesh* sm = smIt->next();
425 if ( sm->IsApplicableHypotesis( anHyp )) {
426 ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
436 if(MYDEBUG) subMesh->DumpAlgoState(true);
441 //=============================================================================
445 //=============================================================================
447 SMESH_Hypothesis::Hypothesis_Status
448 SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
449 int anHypId)throw(SALOME_Exception)
451 Unexpect aCatch(SalomeException);
452 if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis");
454 SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
455 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
456 if ( subMeshDS && subMeshDS->IsComplexSubmesh() )
458 // return the worst but not fatal state of all group memebers
459 SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
460 aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
461 aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
462 for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
464 if ( !GetMeshDS()->ShapeToIndex( itS.Value() ))
465 continue; // not sub-shape
466 ret = RemoveHypothesis( itS.Value(), anHypId );
467 if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
468 aWorstNotFatal = ret;
469 if ( ret < aBestRet )
472 SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId];
473 GetMeshDS()->RemoveHypothesis( aSubShape, anHyp );
475 if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
477 return aWorstNotFatal;
480 StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
481 if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
482 throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
484 SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
485 int hypType = anHyp->GetType();
486 if(MYDEBUG) SCRUTE(hypType);
490 bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
491 int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
493 SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
495 // there may appear concurrent hyps that were covered by the removed hyp
496 if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
497 subMesh->IsApplicableHypotesis( anHyp ) &&
498 subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
499 ret = SMESH_Hypothesis::HYP_CONCURENT;
502 if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
503 anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is removed from father
505 event = isAlgo ? SMESH_subMesh::REMOVE_FATHER_ALGO : SMESH_subMesh::REMOVE_FATHER_HYP;
507 SMESH_Hypothesis::Hypothesis_Status ret2 =
508 subMesh->SubMeshesAlgoStateEngine(event, anHyp);
509 if (ret2 > ret) // more severe
512 // check concurent hypotheses on ansestors
513 if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
515 SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
516 while ( smIt->more() ) {
517 SMESH_subMesh* sm = smIt->next();
518 if ( sm->IsApplicableHypotesis( anHyp )) {
519 ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
529 if(MYDEBUG) subMesh->DumpAlgoState(true);
530 if(MYDEBUG) SCRUTE(ret);
534 //=============================================================================
538 //=============================================================================
540 const list<const SMESHDS_Hypothesis*>&
541 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
542 throw(SALOME_Exception)
544 Unexpect aCatch(SalomeException);
545 return _myMeshDS->GetHypothesis(aSubShape);
548 //=======================================================================
550 * \brief Return the hypothesis assigned to the shape
551 * \param aSubShape - the shape to check
552 * \param aFilter - the hypothesis filter
553 * \param andAncestors - flag to check hypos assigned to ancestors of the shape
554 * \retval SMESH_Hypothesis* - the first hypo passed through aFilter
556 //=======================================================================
558 const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubShape,
559 const SMESH_HypoFilter& aFilter,
560 const bool andAncestors) const
563 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
564 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
565 for ( ; hyp != hypList.end(); hyp++ ) {
566 const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
567 if ( aFilter.IsOk( h, aSubShape))
573 TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
574 for (; it.More(); it.Next() )
576 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
577 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
578 for ( ; hyp != hypList.end(); hyp++ ) {
579 const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
580 if (aFilter.IsOk( h, it.Value() ))
588 //================================================================================
590 * \brief Return hypothesis assigned to the shape
591 * \param aSubShape - the shape to check
592 * \param aFilter - the hypothesis filter
593 * \param aHypList - the list of the found hypotheses
594 * \param andAncestors - flag to check hypos assigned to ancestors of the shape
595 * \retval int - number of unique hypos in aHypList
597 //================================================================================
599 int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape,
600 const SMESH_HypoFilter& aFilter,
601 list <const SMESHDS_Hypothesis * >& aHypList,
602 const bool andAncestors) const
604 set<string> hypTypes; // to exclude same type hypos from the result list
607 // only one main hypothesis is allowed
608 bool mainHypFound = false;
611 list<const SMESHDS_Hypothesis*>::const_iterator hyp;
612 for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) {
613 if ( hypTypes.insert( (*hyp)->GetName() ).second )
615 if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
619 // get hypos from aSubShape
621 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
622 for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
623 if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) &&
624 ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
625 hypTypes.insert( (*hyp)->GetName() ).second )
627 aHypList.push_back( *hyp );
629 if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
634 // get hypos from ancestors of aSubShape
637 TopTools_MapOfShape map;
638 TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
639 for (; it.More(); it.Next() )
641 if ( !map.Add( it.Value() ))
643 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
644 for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
645 if (aFilter.IsOk( cSMESH_Hyp( *hyp ), it.Value() ) &&
646 ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
647 hypTypes.insert( (*hyp)->GetName() ).second )
649 aHypList.push_back( *hyp );
651 if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
659 //=============================================================================
663 //=============================================================================
665 const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
667 Unexpect aCatch(SalomeException);
668 if(MYDEBUG) MESSAGE("SMESH_Mesh::GetLog");
669 return _myMeshDS->GetScript()->GetCommands();
672 //=============================================================================
676 //=============================================================================
677 void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
679 Unexpect aCatch(SalomeException);
680 if(MYDEBUG) MESSAGE("SMESH_Mesh::ClearLog");
681 _myMeshDS->GetScript()->Clear();
684 //=============================================================================
686 * Get or Create the SMESH_subMesh object implementation
688 //=============================================================================
690 SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
691 throw(SALOME_Exception)
693 Unexpect aCatch(SalomeException);
694 SMESH_subMesh *aSubMesh;
695 int index = _myMeshDS->ShapeToIndex(aSubShape);
697 // for submeshes on GEOM Group
698 if ( !index && aSubShape.ShapeType() == TopAbs_COMPOUND ) {
699 TopoDS_Iterator it( aSubShape );
701 index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
704 // return NULL; // neither sub-shape nor a group
706 map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(index);
707 if ( i_sm != _mapSubMesh.end())
709 aSubMesh = i_sm->second;
713 aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
714 _mapSubMesh[index] = aSubMesh;
719 //=============================================================================
721 * Get the SMESH_subMesh object implementation. Dont create it, return null
722 * if it does not exist.
724 //=============================================================================
726 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
727 throw(SALOME_Exception)
729 Unexpect aCatch(SalomeException);
730 SMESH_subMesh *aSubMesh = NULL;
732 int index = _myMeshDS->ShapeToIndex(aSubShape);
734 map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(index);
735 if ( i_sm != _mapSubMesh.end())
736 aSubMesh = i_sm->second;
741 //=============================================================================
743 * Get the SMESH_subMesh object implementation. Dont create it, return null
744 * if it does not exist.
746 //=============================================================================
748 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID)
749 throw(SALOME_Exception)
751 Unexpect aCatch(SalomeException);
753 map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(aShapeID);
754 if (i_sm == _mapSubMesh.end())
759 //=======================================================================
760 //function : IsUsedHypothesis
761 //purpose : Return True if anHyp is used to mesh aSubShape
762 //=======================================================================
764 bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
765 const SMESH_subMesh* aSubMesh)
767 SMESH_Hypothesis* hyp = static_cast<SMESH_Hypothesis*>(anHyp);
769 // check if anHyp can be used to mesh aSubMesh
770 if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp ))
773 const TopoDS_Shape & aSubShape = const_cast<SMESH_subMesh*>( aSubMesh )->GetSubShape();
775 SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape );
778 if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
779 return ( anHyp == algo );
781 // algorithm parameter
784 // look trough hypotheses used by algo
785 SMESH_HypoFilter hypoKind;
786 if ( algo->InitCompatibleHypoFilter( hypoKind, !hyp->IsAuxiliary() )) {
787 list <const SMESHDS_Hypothesis * > usedHyps;
788 if ( GetHypotheses( aSubShape, hypoKind, usedHyps, true ))
789 return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() );
793 // look through all assigned hypotheses
794 //SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp ));
795 return false; //GetHypothesis( aSubShape, filter, true );
798 //=============================================================================
802 //=============================================================================
804 const list < SMESH_subMesh * >&
805 SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
806 throw(SALOME_Exception)
808 Unexpect aCatch(SalomeException);
809 if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis");
810 map < int, SMESH_subMesh * >::iterator itsm;
811 _subMeshesUsingHypothesisList.clear();
812 for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
814 SMESH_subMesh *aSubMesh = (*itsm).second;
815 if ( IsUsedHypothesis ( anHyp, aSubMesh ))
816 _subMeshesUsingHypothesisList.push_back(aSubMesh);
818 return _subMeshesUsingHypothesisList;
821 //=======================================================================
822 //function : NotifySubMeshesHypothesisModification
823 //purpose : Say all submeshes using theChangedHyp that it has been modified
824 //=======================================================================
826 void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp)
828 Unexpect aCatch(SalomeException);
830 const SMESH_Algo *foundAlgo = 0;
831 SMESH_HypoFilter algoKind, compatibleHypoKind;
832 list <const SMESHDS_Hypothesis * > usedHyps;
835 map < int, SMESH_subMesh * >::iterator itsm;
836 for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
838 SMESH_subMesh *aSubMesh = (*itsm).second;
839 if ( aSubMesh->IsApplicableHypotesis( hyp ))
841 const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
843 if ( !foundAlgo ) // init filter for algo search
844 algoKind.Init( THypType::IsAlgo() ).And( THypType::IsApplicableTo( aSubShape ));
846 const SMESH_Algo *algo = static_cast<const SMESH_Algo*>
847 ( GetHypothesis( aSubShape, algoKind, true ));
851 bool sameAlgo = ( algo == foundAlgo );
852 if ( !sameAlgo && foundAlgo )
853 sameAlgo = ( strcmp( algo->GetName(), foundAlgo->GetName() ) == 0);
855 if ( !sameAlgo ) { // init filter for used hypos search
856 if ( !algo->InitCompatibleHypoFilter( compatibleHypoKind, !hyp->IsAuxiliary() ))
857 continue; // algo does not use any hypothesis
861 // check if hyp is used by algo
863 if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) &&
864 find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
866 aSubMesh->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
867 const_cast< SMESH_Hypothesis*>( hyp ));
874 //=============================================================================
876 * To store mesh contents on disk in different formats.
878 //=============================================================================
880 bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
882 set<string> aGroupNames;
883 for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
884 SMESH_Group* aGroup = it->second;
885 string aGroupName = aGroup->GetName();
886 aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
887 if (!aGroupNames.insert(aGroupName).second)
894 void SMESH_Mesh::ExportMED(const char *file,
895 const char* theMeshName,
898 throw(SALOME_Exception)
900 Unexpect aCatch(SalomeException);
902 DriverMED_W_SMESHDS_Mesh myWriter;
903 myWriter.SetFile ( file, MED::EVersion(theVersion) );
904 myWriter.SetMesh ( _myMeshDS );
906 myWriter.SetMeshId ( _idDoc );
908 myWriter.SetMeshId ( -1 );
909 myWriter.SetMeshName( theMeshName );
912 if ( theAutoGroups ) {
913 myWriter.AddGroupOfNodes();
914 myWriter.AddGroupOfEdges();
915 myWriter.AddGroupOfFaces();
916 myWriter.AddGroupOfVolumes();
919 // Pass groups to writer. Provide unique group names.
920 set<string> aGroupNames;
922 int maxNbIter = 10000; // to guarantee cycle finish
923 for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
924 SMESH_Group* aGroup = it->second;
925 SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
927 string aGroupName0 = aGroup->GetName();
928 aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH);
929 string aGroupName = aGroupName0;
930 for (int i = 1; !aGroupNames.insert(aGroupName).second && i < maxNbIter; i++) {
931 sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str());
932 aGroupName = aString;
933 aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
935 aGroupDS->SetStoreName( aGroupName.c_str() );
936 myWriter.AddGroup( aGroupDS );
944 void SMESH_Mesh::ExportDAT(const char *file) throw(SALOME_Exception)
946 Unexpect aCatch(SalomeException);
947 DriverDAT_W_SMDS_Mesh myWriter;
948 myWriter.SetFile(string(file));
949 myWriter.SetMesh(_myMeshDS);
950 myWriter.SetMeshId(_idDoc);
954 void SMESH_Mesh::ExportUNV(const char *file) throw(SALOME_Exception)
956 Unexpect aCatch(SalomeException);
957 DriverUNV_W_SMDS_Mesh myWriter;
958 myWriter.SetFile(string(file));
959 myWriter.SetMesh(_myMeshDS);
960 myWriter.SetMeshId(_idDoc);
961 // myWriter.SetGroups(_mapGroup);
963 for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
964 SMESH_Group* aGroup = it->second;
965 SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
967 string aGroupName = aGroup->GetName();
968 aGroupDS->SetStoreName( aGroupName.c_str() );
969 myWriter.AddGroup( aGroupDS );
975 void SMESH_Mesh::ExportSTL(const char *file, const bool isascii) throw(SALOME_Exception)
977 Unexpect aCatch(SalomeException);
978 DriverSTL_W_SMDS_Mesh myWriter;
979 myWriter.SetFile(string(file));
980 myWriter.SetIsAscii( isascii );
981 myWriter.SetMesh(_myMeshDS);
982 myWriter.SetMeshId(_idDoc);
986 //================================================================================
988 * \brief Return number of nodes in the mesh
990 //================================================================================
992 int SMESH_Mesh::NbNodes() throw(SALOME_Exception)
994 Unexpect aCatch(SalomeException);
995 return _myMeshDS->NbNodes();
998 //================================================================================
1000 * \brief Return number of edges of given order in the mesh
1002 //================================================================================
1004 int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
1006 Unexpect aCatch(SalomeException);
1007 return _myMeshDS->GetMeshInfo().NbEdges(order);
1010 //================================================================================
1012 * \brief Return number of faces of given order in the mesh
1014 //================================================================================
1016 int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
1018 Unexpect aCatch(SalomeException);
1019 return _myMeshDS->GetMeshInfo().NbFaces(order);
1022 //================================================================================
1024 * \brief Return the number of faces in the mesh
1026 //================================================================================
1028 int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
1030 Unexpect aCatch(SalomeException);
1031 return _myMeshDS->GetMeshInfo().NbTriangles(order);
1034 //================================================================================
1036 * \brief Return the number nodes faces in the mesh
1038 //================================================================================
1040 int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
1042 Unexpect aCatch(SalomeException);
1043 return _myMeshDS->GetMeshInfo().NbQuadrangles(order);
1046 //================================================================================
1048 * \brief Return the number of polygonal faces in the mesh
1050 //================================================================================
1052 int SMESH_Mesh::NbPolygons() throw(SALOME_Exception)
1054 Unexpect aCatch(SalomeException);
1055 return _myMeshDS->GetMeshInfo().NbPolygons();
1058 //================================================================================
1060 * \brief Return number of volumes of given order in the mesh
1062 //================================================================================
1064 int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
1066 Unexpect aCatch(SalomeException);
1067 return _myMeshDS->GetMeshInfo().NbVolumes(order);
1070 //================================================================================
1072 * \brief Return number of tetrahedrons of given order in the mesh
1074 //================================================================================
1076 int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
1078 Unexpect aCatch(SalomeException);
1079 return _myMeshDS->GetMeshInfo().NbTetras(order);
1082 //================================================================================
1084 * \brief Return number of hexahedrons of given order in the mesh
1086 //================================================================================
1088 int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
1090 Unexpect aCatch(SalomeException);
1091 return _myMeshDS->GetMeshInfo().NbHexas(order);
1094 //================================================================================
1096 * \brief Return number of pyramids of given order in the mesh
1098 //================================================================================
1100 int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
1102 Unexpect aCatch(SalomeException);
1103 return _myMeshDS->GetMeshInfo().NbPyramids(order);
1106 //================================================================================
1108 * \brief Return number of prisms (penthahedrons) of given order in the mesh
1110 //================================================================================
1112 int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
1114 Unexpect aCatch(SalomeException);
1115 return _myMeshDS->GetMeshInfo().NbPrisms(order);
1118 //================================================================================
1120 * \brief Return number of polyhedrons in the mesh
1122 //================================================================================
1124 int SMESH_Mesh::NbPolyhedrons() throw(SALOME_Exception)
1126 Unexpect aCatch(SalomeException);
1127 return _myMeshDS->GetMeshInfo().NbPolyhedrons();
1130 //================================================================================
1132 * \brief Return number of submeshes in the mesh
1134 //================================================================================
1136 int SMESH_Mesh::NbSubMesh() throw(SALOME_Exception)
1138 Unexpect aCatch(SalomeException);
1139 return _myMeshDS->NbSubMesh();
1142 //=======================================================================
1143 //function : IsNotConformAllowed
1144 //purpose : check if a hypothesis alowing notconform mesh is present
1145 //=======================================================================
1147 bool SMESH_Mesh::IsNotConformAllowed() const
1149 if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed");
1151 static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" ));
1152 return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false );
1155 //=======================================================================
1156 //function : IsMainShape
1158 //=======================================================================
1160 bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const
1162 return theShape.IsSame(_myMeshDS->ShapeToMesh() );
1165 //=============================================================================
1169 //=============================================================================
1171 SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
1172 const char* theName,
1174 const TopoDS_Shape& theShape)
1176 if (_mapGroup.find(_groupId) != _mapGroup.end())
1179 SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape);
1180 GetMeshDS()->AddGroup( aGroup->GetGroupDS() );
1181 _mapGroup[_groupId++] = aGroup;
1185 //=============================================================================
1189 //=============================================================================
1191 SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID)
1193 if (_mapGroup.find(theGroupID) == _mapGroup.end())
1195 return _mapGroup[theGroupID];
1199 //=============================================================================
1203 //=============================================================================
1205 list<int> SMESH_Mesh::GetGroupIds()
1208 for ( map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
1209 anIds.push_back( it->first );
1215 //=============================================================================
1219 //=============================================================================
1221 void SMESH_Mesh::RemoveGroup (const int theGroupID)
1223 if (_mapGroup.find(theGroupID) == _mapGroup.end())
1225 GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() );
1226 delete _mapGroup[theGroupID];
1227 _mapGroup.erase (theGroupID);
1230 //=======================================================================
1231 //function : GetAncestors
1232 //purpose : return list of ancestors of theSubShape in the order
1233 // that lower dimention shapes come first.
1234 //=======================================================================
1236 const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) const
1238 if ( _mapAncestors.Contains( theS ) )
1239 return _mapAncestors.FindFromKey( theS );
1241 static TopTools_ListOfShape emptyList;
1245 //=======================================================================
1247 //purpose : dumps contents of mesh to stream [ debug purposes ]
1248 //=======================================================================
1250 ostream& SMESH_Mesh::Dump(ostream& save)
1253 save << "========================== Dump contents of mesh ==========================" << endl << endl;
1254 save << ++clause << ") Total number of nodes: \t" << NbNodes() << endl;
1255 save << ++clause << ") Total number of edges: \t" << NbEdges() << endl;
1256 save << ++clause << ") Total number of faces: \t" << NbFaces() << endl;
1257 save << ++clause << ") Total number of polygons:\t" << NbPolygons() << endl;
1258 save << ++clause << ") Total number of volumes:\t" << NbVolumes() << endl;
1259 save << ++clause << ") Total number of polyhedrons:\t" << NbPolyhedrons() << endl << endl;
1260 for ( int isQuadratic = 0; isQuadratic < 2; ++isQuadratic )
1262 string orderStr = isQuadratic ? "quadratic" : "linear";
1263 SMDSAbs_ElementOrder order = isQuadratic ? ORDER_QUADRATIC : ORDER_LINEAR;
1265 save << ++clause << ") Total number of " << orderStr << " edges:\t" << NbEdges(order) << endl;
1266 save << ++clause << ") Total number of " << orderStr << " faces:\t" << NbFaces(order) << endl;
1267 if ( NbFaces(order) > 0 ) {
1268 int nb3 = NbTriangles(order);
1269 int nb4 = NbQuadrangles(order);
1270 save << clause << ".1) Number of " << orderStr << " triangles: \t" << nb3 << endl;
1271 save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl;
1272 if ( nb3 + nb4 != NbFaces(order) ) {
1273 map<int,int> myFaceMap;
1274 SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
1275 while( itFaces->more( ) ) {
1276 int nbNodes = itFaces->next()->NbNodes();
1277 if ( myFaceMap.find( nbNodes ) == myFaceMap.end() )
1278 myFaceMap[ nbNodes ] = 0;
1279 myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1;
1281 save << clause << ".3) Faces in detail: " << endl;
1282 map <int,int>::iterator itF;
1283 for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++)
1284 save << "--> nb nodes: " << itF->first << " - nb elemens:\t" << itF->second << endl;
1287 save << ++clause << ") Total number of " << orderStr << " volumes:\t" << NbVolumes(order) << endl;
1288 if ( NbVolumes(order) > 0 ) {
1289 int nb8 = NbHexas(order);
1290 int nb4 = NbTetras(order);
1291 int nb5 = NbPyramids(order);
1292 int nb6 = NbPrisms(order);
1293 save << clause << ".1) Number of " << orderStr << " hexahedrons:\t" << nb8 << endl;
1294 save << clause << ".2) Number of " << orderStr << " tetrahedrons:\t" << nb4 << endl;
1295 save << clause << ".3) Number of " << orderStr << " prisms: \t" << nb6 << endl;
1296 save << clause << ".4) Number of " << orderStr << " pyramids:\t" << nb5 << endl;
1297 if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) {
1298 map<int,int> myVolumesMap;
1299 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
1300 while( itVolumes->more( ) ) {
1301 int nbNodes = itVolumes->next()->NbNodes();
1302 if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() )
1303 myVolumesMap[ nbNodes ] = 0;
1304 myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1;
1306 save << clause << ".5) Volumes in detail: " << endl;
1307 map <int,int>::iterator itV;
1308 for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++)
1309 save << "--> nb nodes: " << itV->first << " - nb elemens:\t" << itV->second << endl;
1314 save << "===========================================================================" << endl;
1318 //=======================================================================
1319 //function : GetElementType
1320 //purpose : Returns type of mesh element with certain id
1321 //=======================================================================
1323 SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem )
1325 return _myMeshDS->GetElementType( id, iselem );