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();
156 _mapPropagationChains.Clear();
159 TopoDS_Shape aNullShape;
160 _myMeshDS->ShapeToMesh( aNullShape );
163 // set a new geometry
164 if ( !aShape.IsNull() )
166 _myMeshDS->ShapeToMesh(aShape);
167 _isShapeToMesh = true;
169 // fill _mapAncestors
170 int desType, ancType;
171 for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
172 for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
173 TopExp::MapShapesAndAncestors ( aShape,
174 (TopAbs_ShapeEnum) desType,
175 (TopAbs_ShapeEnum) ancType,
180 //=======================================================================
182 * \brief Return geometry to be meshed. (It may be a PseudoShape()!)
184 //=======================================================================
186 TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const
188 return _myMeshDS->ShapeToMesh();
191 //=======================================================================
193 * \brief Return a solid which is returned by GetShapeToMesh() if
194 * a real geometry to be meshed was not set
196 //=======================================================================
198 const TopoDS_Solid& SMESH_Mesh::PseudoShape()
200 static TopoDS_Solid aSolid;
201 if ( aSolid.IsNull() )
203 aSolid = BRepPrimAPI_MakeBox(1,1,1);
208 //=======================================================================
209 //function : UNVToMesh
211 //=======================================================================
213 int SMESH_Mesh::UNVToMesh(const char* theFileName)
215 if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<<theFileName);
217 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
218 _isShapeToMesh = true;
219 DriverUNV_R_SMDS_Mesh myReader;
220 myReader.SetMesh(_myMeshDS);
221 myReader.SetFile(theFileName);
222 myReader.SetMeshId(-1);
225 MESSAGE("UNVToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
226 MESSAGE("UNVToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
227 MESSAGE("UNVToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
228 MESSAGE("UNVToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
230 SMDS_MeshGroup* aGroup = (SMDS_MeshGroup*) myReader.GetGroup();
232 TGroupNamesMap aGroupNames = myReader.GetGroupNamesMap();
233 //const TGroupIdMap& aGroupId = myReader.GetGroupIdMap();
234 aGroup->InitSubGroupsIterator();
235 while (aGroup->MoreSubGroups()) {
236 SMDS_MeshGroup* aSubGroup = (SMDS_MeshGroup*) aGroup->NextSubGroup();
237 std::string aName = aGroupNames[aSubGroup];
240 SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId );
242 if(MYDEBUG) MESSAGE("UNVToMesh - group added: "<<aName);
243 SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aSMESHGroup->GetGroupDS() );
245 aGroupDS->SetStoreName(aName.c_str());
246 aSubGroup->InitIterator();
247 const SMDS_MeshElement* aElement = 0;
248 while (aSubGroup->More()) {
249 aElement = aSubGroup->Next();
251 aGroupDS->SMDSGroup().Add(aElement);
255 aGroupDS->SetType(aElement->GetType());
263 //=======================================================================
264 //function : MEDToMesh
266 //=======================================================================
268 int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
270 if(MYDEBUG) MESSAGE("MEDToMesh - theFileName = "<<theFileName<<", mesh name = "<<theMeshName);
272 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
273 _isShapeToMesh = true;
274 DriverMED_R_SMESHDS_Mesh myReader;
275 myReader.SetMesh(_myMeshDS);
276 myReader.SetMeshId(-1);
277 myReader.SetFile(theFileName);
278 myReader.SetMeshName(theMeshName);
279 Driver_Mesh::Status status = myReader.Perform();
281 MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
282 MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
283 MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
284 MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
287 // Reading groups (sub-meshes are out of scope of MED import functionality)
288 list<TNameAndType> aGroupNames = myReader.GetGroupNamesAndTypes();
289 if(MYDEBUG) MESSAGE("MEDToMesh - Nb groups = "<<aGroupNames.size());
291 list<TNameAndType>::iterator name_type = aGroupNames.begin();
292 for ( ; name_type != aGroupNames.end(); name_type++ ) {
293 SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str(), anId );
295 if(MYDEBUG) MESSAGE("MEDToMesh - group added: "<<name_type->first.c_str());
296 SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
298 aGroupDS->SetStoreName( name_type->first.c_str() );
299 myReader.GetGroup( aGroupDS );
306 //=======================================================================
307 //function : STLToMesh
309 //=======================================================================
311 int SMESH_Mesh::STLToMesh(const char* theFileName)
313 if(MYDEBUG) MESSAGE("STLToMesh - theFileName = "<<theFileName);
315 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
316 _isShapeToMesh = true;
317 DriverSTL_R_SMDS_Mesh myReader;
318 myReader.SetMesh(_myMeshDS);
319 myReader.SetFile(theFileName);
320 myReader.SetMeshId(-1);
323 MESSAGE("STLToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
324 MESSAGE("STLToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
325 MESSAGE("STLToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
326 MESSAGE("STLToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
331 //=============================================================================
335 //=============================================================================
337 SMESH_Hypothesis::Hypothesis_Status
338 SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
339 int anHypId ) throw(SALOME_Exception)
341 Unexpect aCatch(SalomeException);
342 if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis");
344 SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
345 if ( !subMesh || !subMesh->GetId())
346 return SMESH_Hypothesis::HYP_BAD_SUBSHAPE;
348 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
349 if ( subMeshDS && subMeshDS->IsComplexSubmesh() ) // group of sub-shapes and maybe of not sub-
351 MESSAGE("AddHypothesis() to complex submesh");
352 // return the worst but not fatal state of all group memebers
353 SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
354 aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
355 aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
356 for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
358 if ( !GetMeshDS()->ShapeToIndex( itS.Value() ))
359 continue; // not sub-shape
360 ret = AddHypothesis( itS.Value(), anHypId );
361 if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
362 aWorstNotFatal = ret;
363 if ( ret < aBestRet )
366 // bind hypotheses to a group just to know
367 SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId];
368 GetMeshDS()->AddHypothesis( aSubShape, anHyp );
370 if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
372 return aWorstNotFatal;
375 StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
376 if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
378 if(MYDEBUG) MESSAGE("Hypothesis ID does not give an hypothesis");
383 throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
386 SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
387 MESSAGE( "SMESH_Mesh::AddHypothesis " << anHyp->GetName() );
389 bool isGlobalHyp = IsMainShape( aSubShape );
391 // NotConformAllowed can be only global
394 string hypName = anHyp->GetName();
395 if ( hypName == "NotConformAllowed" )
397 if(MYDEBUG) MESSAGE( "Hypotesis <NotConformAllowed> can be only global" );
398 return SMESH_Hypothesis::HYP_INCOMPATIBLE;
404 bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
405 int event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
407 SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
410 if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
411 anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
413 event = isAlgo ? SMESH_subMesh::ADD_FATHER_ALGO : SMESH_subMesh::ADD_FATHER_HYP;
415 SMESH_Hypothesis::Hypothesis_Status ret2 =
416 subMesh->SubMeshesAlgoStateEngine(event, anHyp);
420 // check concurent hypotheses on ansestors
421 if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
423 SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
424 while ( smIt->more() ) {
425 SMESH_subMesh* sm = smIt->next();
426 if ( sm->IsApplicableHypotesis( anHyp )) {
427 ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
437 if(MYDEBUG) subMesh->DumpAlgoState(true);
442 //=============================================================================
446 //=============================================================================
448 SMESH_Hypothesis::Hypothesis_Status
449 SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
450 int anHypId)throw(SALOME_Exception)
452 Unexpect aCatch(SalomeException);
453 if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis");
455 SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
456 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
457 if ( subMeshDS && subMeshDS->IsComplexSubmesh() )
459 // return the worst but not fatal state of all group memebers
460 SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
461 aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
462 aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
463 for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
465 if ( !GetMeshDS()->ShapeToIndex( itS.Value() ))
466 continue; // not sub-shape
467 ret = RemoveHypothesis( itS.Value(), anHypId );
468 if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
469 aWorstNotFatal = ret;
470 if ( ret < aBestRet )
473 SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId];
474 GetMeshDS()->RemoveHypothesis( aSubShape, anHyp );
476 if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
478 return aWorstNotFatal;
481 StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
482 if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
483 throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
485 SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
486 int hypType = anHyp->GetType();
487 if(MYDEBUG) SCRUTE(hypType);
491 bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
492 int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
494 SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
496 // there may appear concurrent hyps that were covered by the removed hyp
497 if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
498 subMesh->IsApplicableHypotesis( anHyp ) &&
499 subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
500 ret = SMESH_Hypothesis::HYP_CONCURENT;
503 if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
504 anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is removed from father
506 event = isAlgo ? SMESH_subMesh::REMOVE_FATHER_ALGO : SMESH_subMesh::REMOVE_FATHER_HYP;
508 SMESH_Hypothesis::Hypothesis_Status ret2 =
509 subMesh->SubMeshesAlgoStateEngine(event, anHyp);
510 if (ret2 > ret) // more severe
513 // check concurent hypotheses on ansestors
514 if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
516 SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
517 while ( smIt->more() ) {
518 SMESH_subMesh* sm = smIt->next();
519 if ( sm->IsApplicableHypotesis( anHyp )) {
520 ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
530 if(MYDEBUG) subMesh->DumpAlgoState(true);
531 if(MYDEBUG) SCRUTE(ret);
535 //=============================================================================
539 //=============================================================================
541 const list<const SMESHDS_Hypothesis*>&
542 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
543 throw(SALOME_Exception)
545 Unexpect aCatch(SalomeException);
546 return _myMeshDS->GetHypothesis(aSubShape);
549 //=======================================================================
551 * \brief Return the hypothesis assigned to the shape
552 * \param aSubShape - the shape to check
553 * \param aFilter - the hypothesis filter
554 * \param andAncestors - flag to check hypos assigned to ancestors of the shape
555 * \retval SMESH_Hypothesis* - the first hypo passed through aFilter
557 //=======================================================================
559 const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubShape,
560 const SMESH_HypoFilter& aFilter,
561 const bool andAncestors) const
564 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
565 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
566 for ( ; hyp != hypList.end(); hyp++ ) {
567 const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
568 if ( aFilter.IsOk( h, aSubShape))
574 TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
575 for (; it.More(); it.Next() )
577 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
578 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
579 for ( ; hyp != hypList.end(); hyp++ ) {
580 const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
581 if (aFilter.IsOk( h, it.Value() ))
589 //================================================================================
591 * \brief Return hypothesis assigned to the shape
592 * \param aSubShape - the shape to check
593 * \param aFilter - the hypothesis filter
594 * \param aHypList - the list of the found hypotheses
595 * \param andAncestors - flag to check hypos assigned to ancestors of the shape
596 * \retval int - number of unique hypos in aHypList
598 //================================================================================
600 int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape,
601 const SMESH_HypoFilter& aFilter,
602 list <const SMESHDS_Hypothesis * >& aHypList,
603 const bool andAncestors) const
605 set<string> hypTypes; // to exclude same type hypos from the result list
608 // only one main hypothesis is allowed
609 bool mainHypFound = false;
612 list<const SMESHDS_Hypothesis*>::const_iterator hyp;
613 for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) {
614 if ( hypTypes.insert( (*hyp)->GetName() ).second )
616 if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
620 // get hypos from aSubShape
622 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
623 for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
624 if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) &&
625 ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
626 hypTypes.insert( (*hyp)->GetName() ).second )
628 aHypList.push_back( *hyp );
630 if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
635 // get hypos from ancestors of aSubShape
638 TopTools_MapOfShape map;
639 TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
640 for (; it.More(); it.Next() )
642 if ( !map.Add( it.Value() ))
644 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
645 for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
646 if (aFilter.IsOk( cSMESH_Hyp( *hyp ), it.Value() ) &&
647 ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
648 hypTypes.insert( (*hyp)->GetName() ).second )
650 aHypList.push_back( *hyp );
652 if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
660 //=============================================================================
664 //=============================================================================
666 const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
668 Unexpect aCatch(SalomeException);
669 if(MYDEBUG) MESSAGE("SMESH_Mesh::GetLog");
670 return _myMeshDS->GetScript()->GetCommands();
673 //=============================================================================
677 //=============================================================================
678 void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
680 Unexpect aCatch(SalomeException);
681 if(MYDEBUG) MESSAGE("SMESH_Mesh::ClearLog");
682 _myMeshDS->GetScript()->Clear();
685 //=============================================================================
687 * Get or Create the SMESH_subMesh object implementation
689 //=============================================================================
691 SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
692 throw(SALOME_Exception)
694 Unexpect aCatch(SalomeException);
695 SMESH_subMesh *aSubMesh;
696 int index = _myMeshDS->ShapeToIndex(aSubShape);
698 // for submeshes on GEOM Group
699 if ( !index && aSubShape.ShapeType() == TopAbs_COMPOUND ) {
700 TopoDS_Iterator it( aSubShape );
702 index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
705 // return NULL; // neither sub-shape nor a group
707 map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(index);
708 if ( i_sm != _mapSubMesh.end())
710 aSubMesh = i_sm->second;
714 aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
715 _mapSubMesh[index] = aSubMesh;
720 //=============================================================================
722 * Get the SMESH_subMesh object implementation. Dont create it, return null
723 * if it does not exist.
725 //=============================================================================
727 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
728 throw(SALOME_Exception)
730 Unexpect aCatch(SalomeException);
731 SMESH_subMesh *aSubMesh = NULL;
733 int index = _myMeshDS->ShapeToIndex(aSubShape);
735 map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(index);
736 if ( i_sm != _mapSubMesh.end())
737 aSubMesh = i_sm->second;
742 //=============================================================================
744 * Get the SMESH_subMesh object implementation. Dont create it, return null
745 * if it does not exist.
747 //=============================================================================
749 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID)
750 throw(SALOME_Exception)
752 Unexpect aCatch(SalomeException);
754 map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(aShapeID);
755 if (i_sm == _mapSubMesh.end())
760 //=======================================================================
761 //function : IsUsedHypothesis
762 //purpose : Return True if anHyp is used to mesh aSubShape
763 //=======================================================================
765 bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
766 const SMESH_subMesh* aSubMesh)
768 SMESH_Hypothesis* hyp = static_cast<SMESH_Hypothesis*>(anHyp);
770 // check if anHyp can be used to mesh aSubMesh
771 if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp ))
774 const TopoDS_Shape & aSubShape = const_cast<SMESH_subMesh*>( aSubMesh )->GetSubShape();
776 SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape );
779 if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
780 return ( anHyp == algo );
782 // algorithm parameter
785 // look trough hypotheses used by algo
786 SMESH_HypoFilter hypoKind;
787 if ( algo->InitCompatibleHypoFilter( hypoKind, !hyp->IsAuxiliary() )) {
788 list <const SMESHDS_Hypothesis * > usedHyps;
789 if ( GetHypotheses( aSubShape, hypoKind, usedHyps, true ))
790 return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() );
794 // look through all assigned hypotheses
795 //SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp ));
796 return false; //GetHypothesis( aSubShape, filter, true );
799 //=============================================================================
803 //=============================================================================
805 const list < SMESH_subMesh * >&
806 SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
807 throw(SALOME_Exception)
809 Unexpect aCatch(SalomeException);
810 if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis");
811 map < int, SMESH_subMesh * >::iterator itsm;
812 _subMeshesUsingHypothesisList.clear();
813 for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
815 SMESH_subMesh *aSubMesh = (*itsm).second;
816 if ( IsUsedHypothesis ( anHyp, aSubMesh ))
817 _subMeshesUsingHypothesisList.push_back(aSubMesh);
819 return _subMeshesUsingHypothesisList;
822 //=======================================================================
823 //function : NotifySubMeshesHypothesisModification
824 //purpose : Say all submeshes using theChangedHyp that it has been modified
825 //=======================================================================
827 void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp)
829 Unexpect aCatch(SalomeException);
831 const SMESH_Algo *foundAlgo = 0;
832 SMESH_HypoFilter algoKind, compatibleHypoKind;
833 list <const SMESHDS_Hypothesis * > usedHyps;
836 map < int, SMESH_subMesh * >::iterator itsm;
837 for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
839 SMESH_subMesh *aSubMesh = (*itsm).second;
840 if ( aSubMesh->IsApplicableHypotesis( hyp ))
842 const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
844 if ( !foundAlgo ) // init filter for algo search
845 algoKind.Init( THypType::IsAlgo() ).And( THypType::IsApplicableTo( aSubShape ));
847 const SMESH_Algo *algo = static_cast<const SMESH_Algo*>
848 ( GetHypothesis( aSubShape, algoKind, true ));
852 bool sameAlgo = ( algo == foundAlgo );
853 if ( !sameAlgo && foundAlgo )
854 sameAlgo = ( strcmp( algo->GetName(), foundAlgo->GetName() ) == 0);
856 if ( !sameAlgo ) { // init filter for used hypos search
857 if ( !algo->InitCompatibleHypoFilter( compatibleHypoKind, !hyp->IsAuxiliary() ))
858 continue; // algo does not use any hypothesis
862 // check if hyp is used by algo
864 if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) &&
865 find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
867 aSubMesh->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
868 const_cast< SMESH_Hypothesis*>( hyp ));
870 if ( algo->GetDim() == 1 && IsPropagationHypothesis( aSubShape ))
871 CleanMeshOnPropagationChain( aSubShape );
878 //=============================================================================
880 * To store mesh contents on disk in different formats.
882 //=============================================================================
884 bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
886 set<string> aGroupNames;
887 for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
888 SMESH_Group* aGroup = it->second;
889 string aGroupName = aGroup->GetName();
890 aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
891 if (!aGroupNames.insert(aGroupName).second)
898 void SMESH_Mesh::ExportMED(const char *file,
899 const char* theMeshName,
902 throw(SALOME_Exception)
904 Unexpect aCatch(SalomeException);
906 DriverMED_W_SMESHDS_Mesh myWriter;
907 myWriter.SetFile ( file, MED::EVersion(theVersion) );
908 myWriter.SetMesh ( _myMeshDS );
910 myWriter.SetMeshId ( _idDoc );
912 myWriter.SetMeshId ( -1 );
913 myWriter.SetMeshName( theMeshName );
916 if ( theAutoGroups ) {
917 myWriter.AddGroupOfNodes();
918 myWriter.AddGroupOfEdges();
919 myWriter.AddGroupOfFaces();
920 myWriter.AddGroupOfVolumes();
923 // Pass groups to writer. Provide unique group names.
924 set<string> aGroupNames;
926 int maxNbIter = 10000; // to guarantee cycle finish
927 for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
928 SMESH_Group* aGroup = it->second;
929 SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
931 string aGroupName0 = aGroup->GetName();
932 aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH);
933 string aGroupName = aGroupName0;
934 for (int i = 1; !aGroupNames.insert(aGroupName).second && i < maxNbIter; i++) {
935 sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str());
936 aGroupName = aString;
937 aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
939 aGroupDS->SetStoreName( aGroupName.c_str() );
940 myWriter.AddGroup( aGroupDS );
948 void SMESH_Mesh::ExportDAT(const char *file) throw(SALOME_Exception)
950 Unexpect aCatch(SalomeException);
951 DriverDAT_W_SMDS_Mesh myWriter;
952 myWriter.SetFile(string(file));
953 myWriter.SetMesh(_myMeshDS);
954 myWriter.SetMeshId(_idDoc);
958 void SMESH_Mesh::ExportUNV(const char *file) throw(SALOME_Exception)
960 Unexpect aCatch(SalomeException);
961 DriverUNV_W_SMDS_Mesh myWriter;
962 myWriter.SetFile(string(file));
963 myWriter.SetMesh(_myMeshDS);
964 myWriter.SetMeshId(_idDoc);
965 // myWriter.SetGroups(_mapGroup);
967 for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
968 SMESH_Group* aGroup = it->second;
969 SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
971 string aGroupName = aGroup->GetName();
972 aGroupDS->SetStoreName( aGroupName.c_str() );
973 myWriter.AddGroup( aGroupDS );
979 void SMESH_Mesh::ExportSTL(const char *file, const bool isascii) throw(SALOME_Exception)
981 Unexpect aCatch(SalomeException);
982 DriverSTL_W_SMDS_Mesh myWriter;
983 myWriter.SetFile(string(file));
984 myWriter.SetIsAscii( isascii );
985 myWriter.SetMesh(_myMeshDS);
986 myWriter.SetMeshId(_idDoc);
990 //=============================================================================
994 //=============================================================================
995 int SMESH_Mesh::NbNodes() throw(SALOME_Exception)
997 Unexpect aCatch(SalomeException);
998 return _myMeshDS->NbNodes();
1001 //=============================================================================
1005 //=============================================================================
1006 int SMESH_Mesh::NbEdges(ElementOrder order) throw(SALOME_Exception)
1008 Unexpect aCatch(SalomeException);
1009 if (order == ORDER_ANY)
1010 return _myMeshDS->NbEdges();
1013 SMDS_EdgeIteratorPtr it = _myMeshDS->edgesIterator();
1014 while (it->more()) {
1015 const SMDS_MeshEdge* cur = it->next();
1016 if ( order == ORDER_LINEAR && !cur->IsQuadratic() ||
1017 order == ORDER_QUADRATIC && cur->IsQuadratic() )
1023 //=============================================================================
1027 //=============================================================================
1028 int SMESH_Mesh::NbFaces(ElementOrder order) throw(SALOME_Exception)
1030 Unexpect aCatch(SalomeException);
1031 if (order == ORDER_ANY)
1032 return _myMeshDS->NbFaces();
1035 SMDS_FaceIteratorPtr it = _myMeshDS->facesIterator();
1036 while (it->more()) {
1037 const SMDS_MeshFace* cur = it->next();
1038 if ( order == ORDER_LINEAR && !cur->IsQuadratic() ||
1039 order == ORDER_QUADRATIC && cur->IsQuadratic() )
1045 ///////////////////////////////////////////////////////////////////////////////
1046 /// Return the number of 3 nodes faces in the mesh. This method run in O(n)
1047 ///////////////////////////////////////////////////////////////////////////////
1048 int SMESH_Mesh::NbTriangles(ElementOrder order) throw(SALOME_Exception)
1050 Unexpect aCatch(SalomeException);
1053 SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
1054 while (itFaces->more()) {
1055 const SMDS_MeshFace* curFace = itFaces->next();
1056 int nbnod = curFace->NbNodes();
1057 if ( !curFace->IsPoly() &&
1058 ( order == ORDER_ANY && (nbnod==3 || nbnod==6) ||
1059 order == ORDER_LINEAR && nbnod==3 ||
1060 order == ORDER_QUADRATIC && nbnod==6 ) )
1066 ///////////////////////////////////////////////////////////////////////////////
1067 /// Return the number of 4 nodes faces in the mesh. This method run in O(n)
1068 ///////////////////////////////////////////////////////////////////////////////
1069 int SMESH_Mesh::NbQuadrangles(ElementOrder order) throw(SALOME_Exception)
1071 Unexpect aCatch(SalomeException);
1074 SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
1075 while (itFaces->more()) {
1076 const SMDS_MeshFace* curFace = itFaces->next();
1077 int nbnod = curFace->NbNodes();
1078 if ( !curFace->IsPoly() &&
1079 ( order == ORDER_ANY && (nbnod==4 || nbnod==8) ||
1080 order == ORDER_LINEAR && nbnod==4 ||
1081 order == ORDER_QUADRATIC && nbnod==8 ) )
1087 ///////////////////////////////////////////////////////////////////////////////
1088 /// Return the number of polygonal faces in the mesh. This method run in O(n)
1089 ///////////////////////////////////////////////////////////////////////////////
1090 int SMESH_Mesh::NbPolygons() throw(SALOME_Exception)
1092 Unexpect aCatch(SalomeException);
1094 SMDS_FaceIteratorPtr itFaces = _myMeshDS->facesIterator();
1095 while (itFaces->more())
1096 if (itFaces->next()->IsPoly()) Nb++;
1100 //=============================================================================
1104 //=============================================================================
1105 int SMESH_Mesh::NbVolumes(ElementOrder order) throw(SALOME_Exception)
1107 Unexpect aCatch(SalomeException);
1108 if (order == ORDER_ANY)
1109 return _myMeshDS->NbVolumes();
1112 SMDS_VolumeIteratorPtr it = _myMeshDS->volumesIterator();
1113 while (it->more()) {
1114 const SMDS_MeshVolume* cur = it->next();
1115 if ( order == ORDER_LINEAR && !cur->IsQuadratic() ||
1116 order == ORDER_QUADRATIC && cur->IsQuadratic() )
1122 int SMESH_Mesh::NbTetras(ElementOrder order) throw(SALOME_Exception)
1124 Unexpect aCatch(SalomeException);
1126 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
1127 while (itVolumes->more()) {
1128 const SMDS_MeshVolume* curVolume = itVolumes->next();
1129 int nbnod = curVolume->NbNodes();
1130 if ( !curVolume->IsPoly() &&
1131 ( order == ORDER_ANY && (nbnod==4 || nbnod==10) ||
1132 order == ORDER_LINEAR && nbnod==4 ||
1133 order == ORDER_QUADRATIC && nbnod==10 ) )
1139 int SMESH_Mesh::NbHexas(ElementOrder order) throw(SALOME_Exception)
1141 Unexpect aCatch(SalomeException);
1143 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
1144 while (itVolumes->more()) {
1145 const SMDS_MeshVolume* curVolume = itVolumes->next();
1146 int nbnod = curVolume->NbNodes();
1147 if ( !curVolume->IsPoly() &&
1148 ( order == ORDER_ANY && (nbnod==8 || nbnod==20) ||
1149 order == ORDER_LINEAR && nbnod==8 ||
1150 order == ORDER_QUADRATIC && nbnod==20 ) )
1156 int SMESH_Mesh::NbPyramids(ElementOrder order) throw(SALOME_Exception)
1158 Unexpect aCatch(SalomeException);
1160 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
1161 while (itVolumes->more()) {
1162 const SMDS_MeshVolume* curVolume = itVolumes->next();
1163 int nbnod = curVolume->NbNodes();
1164 if ( !curVolume->IsPoly() &&
1165 ( order == ORDER_ANY && (nbnod==5 || nbnod==13) ||
1166 order == ORDER_LINEAR && nbnod==5 ||
1167 order == ORDER_QUADRATIC && nbnod==13 ) )
1173 int SMESH_Mesh::NbPrisms(ElementOrder order) throw(SALOME_Exception)
1175 Unexpect aCatch(SalomeException);
1177 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
1178 while (itVolumes->more()) {
1179 const SMDS_MeshVolume* curVolume = itVolumes->next();
1180 int nbnod = curVolume->NbNodes();
1181 if ( !curVolume->IsPoly() &&
1182 ( order == ORDER_ANY && (nbnod==6 || nbnod==15) ||
1183 order == ORDER_LINEAR && nbnod==6 ||
1184 order == ORDER_QUADRATIC && nbnod==15 ) )
1190 int SMESH_Mesh::NbPolyhedrons() throw(SALOME_Exception)
1192 Unexpect aCatch(SalomeException);
1194 SMDS_VolumeIteratorPtr itVolumes = _myMeshDS->volumesIterator();
1195 while (itVolumes->more())
1196 if (itVolumes->next()->IsPoly()) Nb++;
1200 //=============================================================================
1204 //=============================================================================
1205 int SMESH_Mesh::NbSubMesh() throw(SALOME_Exception)
1207 Unexpect aCatch(SalomeException);
1208 return _myMeshDS->NbSubMesh();
1211 //=======================================================================
1212 //function : IsNotConformAllowed
1213 //purpose : check if a hypothesis alowing notconform mesh is present
1214 //=======================================================================
1216 bool SMESH_Mesh::IsNotConformAllowed() const
1218 if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed");
1220 SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" ));
1221 return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false );
1224 //=======================================================================
1225 //function : IsMainShape
1227 //=======================================================================
1229 bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const
1231 return theShape.IsSame(_myMeshDS->ShapeToMesh() );
1234 //=============================================================================
1238 //=============================================================================
1240 SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
1241 const char* theName,
1243 const TopoDS_Shape& theShape)
1245 if (_mapGroup.find(_groupId) != _mapGroup.end())
1248 SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape);
1249 GetMeshDS()->AddGroup( aGroup->GetGroupDS() );
1250 _mapGroup[_groupId++] = aGroup;
1254 //=============================================================================
1258 //=============================================================================
1260 SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID)
1262 if (_mapGroup.find(theGroupID) == _mapGroup.end())
1264 return _mapGroup[theGroupID];
1268 //=============================================================================
1272 //=============================================================================
1274 list<int> SMESH_Mesh::GetGroupIds()
1277 for ( map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
1278 anIds.push_back( it->first );
1284 //=============================================================================
1288 //=============================================================================
1290 void SMESH_Mesh::RemoveGroup (const int theGroupID)
1292 if (_mapGroup.find(theGroupID) == _mapGroup.end())
1294 GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() );
1295 delete _mapGroup[theGroupID];
1296 _mapGroup.erase (theGroupID);
1299 //=============================================================================
1301 * IsLocal1DHypothesis
1302 * Returns a local 1D hypothesis used for theEdge
1304 //=============================================================================
1305 const SMESH_Hypothesis* SMESH_Mesh::IsLocal1DHypothesis (const TopoDS_Shape& theEdge)
1307 SMESH_HypoFilter hypo ( SMESH_HypoFilter::HasDim( 1 ));
1308 hypo.AndNot( hypo.IsAlgo() ).AndNot( hypo.IsAssignedTo( GetMeshDS()->ShapeToMesh() ));
1310 return GetHypothesis( theEdge, hypo, true );
1313 //=============================================================================
1315 * IsPropagationHypothesis
1317 //=============================================================================
1318 bool SMESH_Mesh::IsPropagationHypothesis (const TopoDS_Shape& theEdge)
1320 return _mapPropagationChains.Contains(theEdge);
1323 //=============================================================================
1325 * IsPropagatedHypothesis
1327 //=============================================================================
1328 bool SMESH_Mesh::IsPropagatedHypothesis (const TopoDS_Shape& theEdge,
1329 TopoDS_Shape& theMainEdge)
1331 int nbChains = _mapPropagationChains.Extent();
1332 for (int i = 1; i <= nbChains; i++) {
1333 //const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i);
1334 const SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i);
1335 if (aChain.Contains(theEdge)) {
1336 theMainEdge = _mapPropagationChains.FindKey(i);
1343 //=============================================================================
1347 //=============================================================================
1349 bool SMESH_Mesh::IsReversedInChain (const TopoDS_Shape& theEdge,
1350 const TopoDS_Shape& theMainEdge)
1352 if ( !theMainEdge.IsNull() && !theEdge.IsNull() &&
1353 _mapPropagationChains.Contains( theMainEdge ))
1355 const SMESH_IndexedMapOfShape& aChain =
1356 _mapPropagationChains.FindFromKey( theMainEdge );
1357 int index = aChain.FindIndex( theEdge );
1359 return aChain(index).Orientation() == TopAbs_REVERSED;
1364 //=============================================================================
1366 * CleanMeshOnPropagationChain
1368 //=============================================================================
1369 void SMESH_Mesh::CleanMeshOnPropagationChain (const TopoDS_Shape& theMainEdge)
1371 const SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromKey(theMainEdge);
1372 int i, nbEdges = aChain.Extent();
1373 for (i = 1; i <= nbEdges; i++) {
1374 TopoDS_Shape anEdge = aChain.FindKey(i);
1375 SMESH_subMesh *subMesh = GetSubMesh(anEdge);
1376 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
1377 if (subMeshDS && subMeshDS->NbElements() > 0) {
1378 subMesh->ComputeStateEngine(SMESH_subMesh::CLEAN);
1383 //=============================================================================
1385 * RebuildPropagationChains
1386 * Rebuild all existing propagation chains.
1387 * Have to be used, if 1D hypothesis have been assigned/removed to/from any edge
1389 //=============================================================================
1390 bool SMESH_Mesh::RebuildPropagationChains()
1394 // Clean all chains, because they can be not up-to-date
1395 int i, nbChains = _mapPropagationChains.Extent();
1396 for (i = 1; i <= nbChains; i++) {
1397 TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i);
1398 CleanMeshOnPropagationChain(aMainEdge);
1399 _mapPropagationChains.ChangeFromIndex(i).Clear();
1403 for (i = 1; i <= nbChains; i++) {
1404 TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i);
1405 if (!BuildPropagationChain(aMainEdge))
1407 CleanMeshOnPropagationChain(aMainEdge);
1413 //=============================================================================
1415 * RemovePropagationChain
1416 * Have to be used, if Propagation hypothesis is removed from <theMainEdge>
1418 //=============================================================================
1419 bool SMESH_Mesh::RemovePropagationChain (const TopoDS_Shape& theMainEdge)
1421 if (!_mapPropagationChains.Contains(theMainEdge))
1424 // Clean mesh elements and nodes, built on the chain
1425 CleanMeshOnPropagationChain(theMainEdge);
1428 _mapPropagationChains.ChangeFromKey(theMainEdge).Clear();
1430 // Remove the chain from the map
1431 int i = _mapPropagationChains.FindIndex(theMainEdge);
1432 if ( i == _mapPropagationChains.Extent() )
1433 _mapPropagationChains.RemoveLast();
1435 TopoDS_Vertex anEmptyShape;
1437 BB.MakeVertex(anEmptyShape, gp_Pnt(0,0,0), 0.1);
1438 SMESH_IndexedMapOfShape anEmptyMap;
1439 _mapPropagationChains.Substitute(i, anEmptyShape, anEmptyMap);
1445 //=============================================================================
1447 * BuildPropagationChain
1449 //=============================================================================
1450 bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge)
1452 if (theMainEdge.ShapeType() != TopAbs_EDGE) return true;
1454 // Add new chain, if there is no
1455 if (!_mapPropagationChains.Contains(theMainEdge)) {
1456 SMESH_IndexedMapOfShape aNewChain;
1457 _mapPropagationChains.Add(theMainEdge, aNewChain);
1460 // Check presence of 1D hypothesis to be propagated
1461 const SMESH_Hypothesis* aMainHyp = IsLocal1DHypothesis(theMainEdge);
1463 MESSAGE("Warning: There is no 1D hypothesis to propagate. Please, assign.");
1467 // Edges, on which the 1D hypothesis will be propagated from <theMainEdge>
1468 SMESH_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge);
1469 if (aChain.Extent() > 0) {
1470 CleanMeshOnPropagationChain(theMainEdge);
1474 // At first put <theMainEdge> in the chain
1475 aChain.Add(theMainEdge);
1477 // List of edges, added to chain on the previous cycle pass
1478 TopTools_ListOfShape listPrevEdges;
1479 listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD ));
1481 // 5____4____3____4____5____6
1484 // 4____3____2____3____4____5
1485 // | | | | | | Number in the each knot of
1486 // | | | | | | grid indicates cycle pass,
1487 // 3____2____1____2____3____4 on which corresponding edge
1488 // | | | | | | (perpendicular to the plane
1489 // | | | | | | of view) will be found.
1490 // 2____1____0____1____2____3
1493 // 3____2____1____2____3____4
1495 // Collect all edges pass by pass
1496 while (listPrevEdges.Extent() > 0) {
1497 // List of edges, added to chain on this cycle pass
1498 TopTools_ListOfShape listCurEdges;
1500 // Find the next portion of edges
1501 TopTools_ListIteratorOfListOfShape itE (listPrevEdges);
1502 for (; itE.More(); itE.Next()) {
1503 TopoDS_Shape anE = itE.Value();
1505 // Iterate on faces, having edge <anE>
1506 TopTools_ListIteratorOfListOfShape itA (GetAncestors(anE));
1507 for (; itA.More(); itA.Next()) {
1508 TopoDS_Shape aW = itA.Value();
1510 // There are objects of different type among the ancestors of edge
1511 if (aW.ShapeType() == TopAbs_WIRE) {
1512 TopoDS_Shape anOppE;
1514 BRepTools_WireExplorer aWE (TopoDS::Wire(aW));
1515 Standard_Integer nb = 1, found = 0;
1516 TopTools_Array1OfShape anEdges (1,4);
1517 for (; aWE.More(); aWE.Next(), nb++) {
1522 anEdges(nb) = aWE.Current();
1523 if (!_mapAncestors.Contains(anEdges(nb))) {
1524 MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!");
1527 if (anEdges(nb).IsSame(anE)) found = nb;
1530 if (nb == 5 && found > 0) {
1531 // Quadrangle face found, get an opposite edge
1532 Standard_Integer opp = found + 2;
1533 if (opp > 4) opp -= 4;
1534 anOppE = anEdges(opp);
1536 // add anOppE to aChain if ...
1537 if (!aChain.Contains(anOppE)) { // ... anOppE is not in aChain
1538 if (!IsLocal1DHypothesis(anOppE)) { // ... no other 1d hyp on anOppE
1539 TopoDS_Shape aMainEdgeForOppEdge; // ... no other hyp is propagated to anOppE
1540 if (!IsPropagatedHypothesis(anOppE, aMainEdgeForOppEdge))
1542 // Add found edge to the chain oriented so that to
1543 // have it co-directed with a forward MainEdge
1544 TopAbs_Orientation ori = anE.Orientation();
1545 if ( anEdges(opp).Orientation() == anEdges(found).Orientation() )
1546 ori = TopAbs::Reverse( ori );
1547 anOppE.Orientation( ori );
1549 listCurEdges.Append(anOppE);
1553 MESSAGE("Error: Collision between propagated hypotheses");
1554 CleanMeshOnPropagationChain(theMainEdge);
1556 return ( aMainHyp == IsLocal1DHypothesis(aMainEdgeForOppEdge) );
1560 } // if (nb == 5 && found > 0)
1561 } // if (aF.ShapeType() == TopAbs_WIRE)
1562 } // for (; itF.More(); itF.Next())
1563 } // for (; itE.More(); itE.Next())
1565 listPrevEdges = listCurEdges;
1566 } // while (listPrevEdges.Extent() > 0)
1568 CleanMeshOnPropagationChain(theMainEdge);
1572 //=======================================================================
1573 //function : GetAncestors
1574 //purpose : return list of ancestors of theSubShape in the order
1575 // that lower dimention shapes come first.
1576 //=======================================================================
1578 const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) const
1580 if ( _mapAncestors.Contains( theS ) )
1581 return _mapAncestors.FindFromKey( theS );
1583 static TopTools_ListOfShape emptyList;
1587 //=======================================================================
1589 //purpose : dumps contents of mesh to stream [ debug purposes ]
1590 //=======================================================================
1591 ostream& SMESH_Mesh::Dump(ostream& save)
1594 save << "========================== Dump contents of mesh ==========================" << endl << endl;
1595 save << ++clause << ") Total number of nodes: \t" << NbNodes() << endl;
1596 save << ++clause << ") Total number of edges: \t" << NbEdges() << endl;
1597 save << ++clause << ") Total number of faces: \t" << NbFaces() << endl;
1598 save << ++clause << ") Total number of polygons:\t" << NbPolygons() << endl;
1599 save << ++clause << ") Total number of volumes:\t" << NbVolumes() << endl;
1600 save << ++clause << ") Total number of polyhedrons:\t" << NbPolyhedrons() << endl << endl;
1601 for ( int isQuadratic = 0; isQuadratic < 2; ++isQuadratic )
1603 string orderStr = isQuadratic ? "quadratic" : "linear";
1604 ElementOrder order = isQuadratic ? ORDER_QUADRATIC : ORDER_LINEAR;
1606 save << ++clause << ") Total number of " << orderStr << " edges:\t" << NbEdges(order) << endl;
1607 save << ++clause << ") Total number of " << orderStr << " faces:\t" << NbFaces(order) << endl;
1608 if ( NbFaces(order) > 0 ) {
1609 int nb3 = NbTriangles(order);
1610 int nb4 = NbQuadrangles(order);
1611 save << clause << ".1) Number of " << orderStr << " triangles: \t" << nb3 << endl;
1612 save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl;
1613 if ( nb3 + nb4 != NbFaces(order) ) {
1614 map<int,int> myFaceMap;
1615 SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
1616 while( itFaces->more( ) ) {
1617 int nbNodes = itFaces->next()->NbNodes();
1618 if ( myFaceMap.find( nbNodes ) == myFaceMap.end() )
1619 myFaceMap[ nbNodes ] = 0;
1620 myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1;
1622 save << clause << ".3) Faces in detail: " << endl;
1623 map <int,int>::iterator itF;
1624 for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++)
1625 save << "--> nb nodes: " << itF->first << " - nb elemens:\t" << itF->second << endl;
1628 save << ++clause << ") Total number of " << orderStr << " volumes:\t" << NbVolumes(order) << endl;
1629 if ( NbVolumes(order) > 0 ) {
1630 int nb8 = NbHexas(order);
1631 int nb4 = NbTetras(order);
1632 int nb5 = NbPyramids(order);
1633 int nb6 = NbPrisms(order);
1634 save << clause << ".1) Number of " << orderStr << " hexahedrons:\t" << nb8 << endl;
1635 save << clause << ".2) Number of " << orderStr << " tetrahedrons:\t" << nb4 << endl;
1636 save << clause << ".3) Number of " << orderStr << " prisms: \t" << nb6 << endl;
1637 save << clause << ".4) Number of " << orderStr << " pyramids:\t" << nb5 << endl;
1638 if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) {
1639 map<int,int> myVolumesMap;
1640 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
1641 while( itVolumes->more( ) ) {
1642 int nbNodes = itVolumes->next()->NbNodes();
1643 if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() )
1644 myVolumesMap[ nbNodes ] = 0;
1645 myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1;
1647 save << clause << ".5) Volumes in detail: " << endl;
1648 map <int,int>::iterator itV;
1649 for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++)
1650 save << "--> nb nodes: " << itV->first << " - nb elemens:\t" << itV->second << endl;
1655 save << "===========================================================================" << endl;
1659 //=======================================================================
1660 //function : GetElementType
1661 //purpose : Returns type of mesh element with certain id
1662 //=======================================================================
1663 SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem )
1665 return _myMeshDS->GetElementType( id, iselem );