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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
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 <BRep_Builder.hxx>
55 #include <TCollection_AsciiString.hxx>
57 #include <TopTools_ListOfShape.hxx>
58 #include <TopTools_Array1OfShape.hxx>
59 #include <TopTools_ListIteratorOfListOfShape.hxx>
60 #include <TopTools_MapOfShape.hxx>
64 #include "Utils_ExceptHandlers.hxx"
67 static int MYDEBUG = 0;
69 static int MYDEBUG = 0;
73 //=============================================================================
77 //=============================================================================
79 SMESH_Mesh::SMESH_Mesh(int localId, int studyId, SMESH_Gen * gen, SMESHDS_Document * myDocument)
82 INFOS("SMESH_Mesh::SMESH_Mesh(int localId)");
86 _myDocument = myDocument;
87 _idDoc = _myDocument->NewMesh();
88 _myMeshDS = _myDocument->GetMesh(_idDoc);
89 _isShapeToMesh = false;
92 //=============================================================================
96 //=============================================================================
98 SMESH_Mesh::~SMESH_Mesh()
100 INFOS("SMESH_Mesh::~SMESH_Mesh");
103 map < int, SMESH_Group * >::iterator itg;
104 for (itg = _mapGroup.begin(); itg != _mapGroup.end(); itg++) {
105 SMESH_Group *aGroup = (*itg).second;
110 //=============================================================================
114 //=============================================================================
116 void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
118 if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh");
120 if ( !_myMeshDS->ShapeToMesh().IsNull() && aShape.IsNull() )
122 // removal of a shape to mesh, delete objects referring to sub-shapes:
124 map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.begin();
125 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
128 // - groups on geometry
129 map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
130 while ( i_gr != _mapGroup.end() ) {
131 if ( dynamic_cast<SMESHDS_GroupOnGeom*>( i_gr->second->GetGroupDS() )) {
132 _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() );
134 _mapGroup.erase( i_gr++ );
139 _mapPropagationChains.Clear();
144 throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
146 _isShapeToMesh = true;
147 _myMeshDS->ShapeToMesh(aShape);
149 // fill _mapAncestors
150 _mapAncestors.Clear();
151 int desType, ancType;
152 for ( desType = TopAbs_EDGE; desType > TopAbs_COMPOUND; desType-- )
153 for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
154 TopExp::MapShapesAndAncestors ( aShape,
155 (TopAbs_ShapeEnum) desType,
156 (TopAbs_ShapeEnum) ancType,
160 //EAP: 1/9/04 TopExp::MapShapes(aShape, _subShapes); USE the same map of _myMeshDS
163 //=======================================================================
164 //function : UNVToMesh
166 //=======================================================================
168 int SMESH_Mesh::UNVToMesh(const char* theFileName)
170 if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<<theFileName);
172 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
173 _isShapeToMesh = true;
174 DriverUNV_R_SMDS_Mesh myReader;
175 myReader.SetMesh(_myMeshDS);
176 myReader.SetFile(theFileName);
177 myReader.SetMeshId(-1);
180 MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
181 MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
182 MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
183 MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
188 //=======================================================================
189 //function : MEDToMesh
191 //=======================================================================
193 int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
195 if(MYDEBUG) MESSAGE("MEDToMesh - theFileName = "<<theFileName<<", mesh name = "<<theMeshName);
197 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
198 _isShapeToMesh = true;
199 DriverMED_R_SMESHDS_Mesh myReader;
200 myReader.SetMesh(_myMeshDS);
201 myReader.SetMeshId(-1);
202 myReader.SetFile(theFileName);
203 myReader.SetMeshName(theMeshName);
204 Driver_Mesh::Status status = myReader.Perform();
206 MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
207 MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
208 MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
209 MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
212 // Reading groups (sub-meshes are out of scope of MED import functionality)
213 list<string> aGroupNames = myReader.GetGroupNames();
214 if(MYDEBUG) MESSAGE("MEDToMesh - Nb groups = "<<aGroupNames.size());
216 for ( list<string>::iterator it = aGroupNames.begin(); it != aGroupNames.end(); it++ ) {
217 SMESH_Group* aGroup = AddGroup( SMDSAbs_All, it->c_str(), anId );
219 if(MYDEBUG) MESSAGE("MEDToMesh - group added: "<<it->c_str());
220 SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
222 aGroupDS->SetStoreName( it->c_str() );
223 myReader.GetGroup( aGroupDS );
230 //=======================================================================
231 //function : STLToMesh
233 //=======================================================================
235 int SMESH_Mesh::STLToMesh(const char* theFileName)
237 if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<<theFileName);
239 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
240 _isShapeToMesh = true;
241 DriverSTL_R_SMDS_Mesh myReader;
242 myReader.SetMesh(_myMeshDS);
243 myReader.SetFile(theFileName);
244 myReader.SetMeshId(-1);
247 MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
248 MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
249 MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
250 MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
255 //=============================================================================
259 //=============================================================================
261 SMESH_Hypothesis::Hypothesis_Status
262 SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
263 int anHypId ) throw(SALOME_Exception)
265 Unexpect aCatch(SalomeException);
266 if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis");
268 SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
269 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
270 if ( subMeshDS && subMeshDS->IsComplexSubmesh() ) // group of sub-shapes and maybe of not sub-
272 MESSAGE("AddHypothesis() to complex submesh");
273 // return the worst but not fatal state of all group memebers
274 SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
275 aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
276 aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
277 for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
279 if ( !GetMeshDS()->ShapeToIndex( itS.Value() ))
280 continue; // not sub-shape
281 ret = AddHypothesis( itS.Value(), anHypId );
282 if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
283 aWorstNotFatal = ret;
284 if ( ret < aBestRet )
287 if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
289 return aWorstNotFatal;
292 StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
293 if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
295 if(MYDEBUG) MESSAGE("Hypothesis ID does not give an hypothesis");
300 throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
303 SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
304 MESSAGE( "SMESH_Mesh::AddHypothesis " << anHyp->GetName() );
306 bool isGlobalHyp = IsMainShape( aSubShape );
308 // NotConformAllowed can be only global
311 string hypName = anHyp->GetName();
312 if ( hypName == "NotConformAllowed" )
314 if(MYDEBUG) MESSAGE( "Hypotesis <NotConformAllowed> can be only global" );
315 return SMESH_Hypothesis::HYP_INCOMPATIBLE;
322 if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
323 event = SMESH_subMesh::ADD_HYP;
325 event = SMESH_subMesh::ADD_ALGO;
326 SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
329 if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
330 !subMesh->IsApplicableHypotesis( anHyp )) // is added on father
332 if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
333 event = SMESH_subMesh::ADD_FATHER_HYP;
335 event = SMESH_subMesh::ADD_FATHER_ALGO;
336 SMESH_Hypothesis::Hypothesis_Status ret2 =
337 subMesh->SubMeshesAlgoStateEngine(event, anHyp);
341 // check concurent hypotheses on ansestors
342 if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
344 const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
345 map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
346 for ( ; smIt != smMap.end(); smIt++ ) {
347 if ( smIt->second->IsApplicableHypotesis( anHyp )) {
348 ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
358 if(MYDEBUG) subMesh->DumpAlgoState(true);
363 //=============================================================================
367 //=============================================================================
369 SMESH_Hypothesis::Hypothesis_Status
370 SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
371 int anHypId)throw(SALOME_Exception)
373 Unexpect aCatch(SalomeException);
374 if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis");
376 SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
377 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
378 if ( subMeshDS && subMeshDS->IsComplexSubmesh() )
380 // return the worst but not fatal state of all group memebers
381 SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
382 aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
383 aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
384 for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
386 if ( !GetMeshDS()->ShapeToIndex( itS.Value() ))
387 continue; // not sub-shape
388 ret = RemoveHypothesis( itS.Value(), anHypId );
389 if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
390 aWorstNotFatal = ret;
391 if ( ret < aBestRet )
394 if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
396 return aWorstNotFatal;
399 StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
400 if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
401 throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
403 SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
404 int hypType = anHyp->GetType();
405 if(MYDEBUG) SCRUTE(hypType);
410 if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
411 event = SMESH_subMesh::REMOVE_HYP;
413 event = SMESH_subMesh::REMOVE_ALGO;
414 SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
416 // there may appear concurrent hyps that were covered by the removed hyp
417 if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
418 subMesh->IsApplicableHypotesis( anHyp ) &&
419 subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
420 ret = SMESH_Hypothesis::HYP_CONCURENT;
423 if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
424 !subMesh->IsApplicableHypotesis( anHyp )) // is removed from father
426 if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
427 event = SMESH_subMesh::REMOVE_FATHER_HYP;
429 event = SMESH_subMesh::REMOVE_FATHER_ALGO;
430 SMESH_Hypothesis::Hypothesis_Status ret2 =
431 subMesh->SubMeshesAlgoStateEngine(event, anHyp);
432 if (ret2 > ret) // more severe
435 // check concurent hypotheses on ansestors
436 if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
438 const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
439 map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
440 for ( ; smIt != smMap.end(); smIt++ ) {
441 if ( smIt->second->IsApplicableHypotesis( anHyp )) {
442 ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
452 if(MYDEBUG) subMesh->DumpAlgoState(true);
453 if(MYDEBUG) SCRUTE(ret);
457 //=============================================================================
461 //=============================================================================
463 SMESHDS_Mesh * SMESH_Mesh::GetMeshDS()
468 //=============================================================================
472 //=============================================================================
474 const list<const SMESHDS_Hypothesis*>&
475 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
476 throw(SALOME_Exception)
478 Unexpect aCatch(SalomeException);
479 return _myMeshDS->GetHypothesis(aSubShape);
482 //=======================================================================
483 //function : GetHypothesis
485 //=======================================================================
487 const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubShape,
488 const SMESH_HypoFilter& aFilter,
489 const bool andAncestors) const
492 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
493 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
494 for ( ; hyp != hypList.end(); hyp++ ) {
495 const SMESH_Hypothesis * h = static_cast<const SMESH_Hypothesis*>( *hyp );
496 if ( aFilter.IsOk( h, aSubShape))
502 TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
503 for (; it.More(); it.Next() )
505 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
506 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
507 for ( ; hyp != hypList.end(); hyp++ ) {
508 const SMESH_Hypothesis * h = static_cast<const SMESH_Hypothesis*>( *hyp );
509 if (aFilter.IsOk( h, it.Value() ))
517 //=======================================================================
518 //function : GetHypotheses
520 //=======================================================================
522 bool SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape,
523 const SMESH_HypoFilter& aFilter,
524 list <const SMESHDS_Hypothesis * >& aHypList,
525 const bool andAncestors) const
529 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
530 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
531 for ( ; hyp != hypList.end(); hyp++ )
532 if ( aFilter.IsOk (static_cast<const SMESH_Hypothesis*>( *hyp ), aSubShape)) {
533 aHypList.push_back( *hyp );
537 // get hypos from shape of one type only: if any hypo is found on edge, do
538 // not look up on faces
539 if ( !nbHyp && andAncestors )
541 TopTools_MapOfShape map;
542 TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
543 int shapeType = it.More() ? it.Value().ShapeType() : TopAbs_SHAPE;
544 for (; it.More(); it.Next() )
546 if ( nbHyp && shapeType != it.Value().ShapeType() )
548 shapeType = it.Value().ShapeType();
549 if ( !map.Add( it.Value() ))
551 const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
552 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
553 for ( ; hyp != hypList.end(); hyp++ )
554 if (aFilter.IsOk( static_cast<const SMESH_Hypothesis*>( *hyp ), it.Value() )) {
555 aHypList.push_back( *hyp );
563 //=============================================================================
567 //=============================================================================
569 const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
571 Unexpect aCatch(SalomeException);
572 if(MYDEBUG) MESSAGE("SMESH_Mesh::GetLog");
573 return _myMeshDS->GetScript()->GetCommands();
576 //=============================================================================
580 //=============================================================================
581 void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
583 Unexpect aCatch(SalomeException);
584 if(MYDEBUG) MESSAGE("SMESH_Mesh::ClearLog");
585 _myMeshDS->GetScript()->Clear();
588 //=============================================================================
592 //=============================================================================
594 int SMESH_Mesh::GetId()
596 if(MYDEBUG) MESSAGE("SMESH_Mesh::GetId");
600 //=============================================================================
604 //=============================================================================
606 SMESH_Gen *SMESH_Mesh::GetGen()
611 //=============================================================================
613 * Get or Create the SMESH_subMesh object implementation
615 //=============================================================================
617 SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
618 throw(SALOME_Exception)
620 Unexpect aCatch(SalomeException);
621 SMESH_subMesh *aSubMesh;
622 int index = _myMeshDS->ShapeToIndex(aSubShape);
624 // for submeshes on GEOM Group
625 if ( !index && aSubShape.ShapeType() == TopAbs_COMPOUND ) {
626 TopoDS_Iterator it( aSubShape );
628 index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
631 if (_mapSubMesh.find(index) != _mapSubMesh.end())
633 aSubMesh = _mapSubMesh[index];
637 aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
638 _mapSubMesh[index] = aSubMesh;
643 //=============================================================================
645 * Get the SMESH_subMesh object implementation. Dont create it, return null
646 * if it does not exist.
648 //=============================================================================
650 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
651 throw(SALOME_Exception)
653 Unexpect aCatch(SalomeException);
654 bool isFound = false;
655 SMESH_subMesh *aSubMesh = NULL;
657 int index = _myMeshDS->ShapeToIndex(aSubShape);
658 if (_mapSubMesh.find(index) != _mapSubMesh.end())
660 aSubMesh = _mapSubMesh[index];
668 //=============================================================================
670 * Get the SMESH_subMesh object implementation. Dont create it, return null
671 * if it does not exist.
673 //=============================================================================
675 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID)
676 throw(SALOME_Exception)
678 Unexpect aCatch(SalomeException);
680 map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(aShapeID);
681 if (i_sm == _mapSubMesh.end())
686 //=======================================================================
687 //function : IsUsedHypothesis
688 //purpose : Return True if anHyp is used to mesh aSubShape
689 //=======================================================================
691 bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
692 const TopoDS_Shape & aSubShape)
694 SMESH_Hypothesis* hyp = static_cast<SMESH_Hypothesis*>(anHyp);
695 // check if anHyp is applicable to aSubShape
696 SMESH_subMesh * subMesh = GetSubMeshContaining( aSubShape );
697 if ( !subMesh || !subMesh->IsApplicableHypotesis( hyp ))
700 SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape);
703 if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
704 return ( anHyp == algo );
706 // algorithm parameter
709 // look trough hypotheses used by algo
710 const list <const SMESHDS_Hypothesis * >&usedHyps =
711 algo->GetUsedHypothesis(*this, aSubShape);
712 return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() );
715 // look through all assigned hypotheses
716 SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp ));
717 return GetHypothesis( aSubShape, filter, true );
721 //=============================================================================
725 //=============================================================================
727 const list < SMESH_subMesh * >&
728 SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
729 throw(SALOME_Exception)
731 Unexpect aCatch(SalomeException);
732 if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis");
733 map < int, SMESH_subMesh * >::iterator itsm;
734 _subMeshesUsingHypothesisList.clear();
735 for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
737 SMESH_subMesh *aSubMesh = (*itsm).second;
738 if ( IsUsedHypothesis ( anHyp, aSubMesh->GetSubShape() ))
739 _subMeshesUsingHypothesisList.push_back(aSubMesh);
741 return _subMeshesUsingHypothesisList;
744 //=============================================================================
748 //=============================================================================
750 void SMESH_Mesh::ExportMED(const char *file,
751 const char* theMeshName,
754 throw(SALOME_Exception)
756 Unexpect aCatch(SalomeException);
757 DriverMED_W_SMESHDS_Mesh myWriter;
758 myWriter.SetFile ( file, MED::EVersion(theVersion) );
759 myWriter.SetMesh ( _myMeshDS );
761 myWriter.SetMeshId ( _idDoc );
763 myWriter.SetMeshId ( -1 );
764 myWriter.SetMeshName( theMeshName );
767 if ( theAutoGroups ) {
768 myWriter.AddGroupOfNodes();
769 myWriter.AddGroupOfEdges();
770 myWriter.AddGroupOfFaces();
771 myWriter.AddGroupOfVolumes();
774 for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
775 SMESH_Group* aGroup = it->second;
776 SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
778 aGroupDS->SetStoreName( aGroup->GetName() );
779 myWriter.AddGroup( aGroupDS );
786 void SMESH_Mesh::ExportDAT(const char *file) throw(SALOME_Exception)
788 Unexpect aCatch(SalomeException);
789 DriverDAT_W_SMDS_Mesh myWriter;
790 myWriter.SetFile(string(file));
791 myWriter.SetMesh(_myMeshDS);
792 myWriter.SetMeshId(_idDoc);
796 void SMESH_Mesh::ExportUNV(const char *file) throw(SALOME_Exception)
798 Unexpect aCatch(SalomeException);
799 DriverUNV_W_SMDS_Mesh myWriter;
800 myWriter.SetFile(string(file));
801 myWriter.SetMesh(_myMeshDS);
802 myWriter.SetMeshId(_idDoc);
806 void SMESH_Mesh::ExportSTL(const char *file, const bool isascii) throw(SALOME_Exception)
808 Unexpect aCatch(SalomeException);
809 DriverSTL_W_SMDS_Mesh myWriter;
810 myWriter.SetFile(string(file));
811 myWriter.SetIsAscii( isascii );
812 myWriter.SetMesh(_myMeshDS);
813 myWriter.SetMeshId(_idDoc);
817 //=============================================================================
821 //=============================================================================
822 int SMESH_Mesh::NbNodes() throw(SALOME_Exception)
824 Unexpect aCatch(SalomeException);
825 return _myMeshDS->NbNodes();
828 //=============================================================================
832 //=============================================================================
833 int SMESH_Mesh::NbEdges() throw(SALOME_Exception)
835 Unexpect aCatch(SalomeException);
836 return _myMeshDS->NbEdges();
839 //=============================================================================
843 //=============================================================================
844 int SMESH_Mesh::NbFaces() throw(SALOME_Exception)
846 Unexpect aCatch(SalomeException);
847 return _myMeshDS->NbFaces();
850 ///////////////////////////////////////////////////////////////////////////////
851 /// Return the number of 3 nodes faces in the mesh. This method run in O(n)
852 ///////////////////////////////////////////////////////////////////////////////
853 int SMESH_Mesh::NbTriangles() throw(SALOME_Exception)
855 Unexpect aCatch(SalomeException);
858 SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
859 //while(itFaces->more()) if(itFaces->next()->NbNodes()==3) Nb++;
860 const SMDS_MeshFace * curFace;
861 while (itFaces->more()) {
862 curFace = itFaces->next();
863 if (!curFace->IsPoly() && curFace->NbNodes() == 3) Nb++;
868 ///////////////////////////////////////////////////////////////////////////////
869 /// Return the number of 4 nodes faces in the mesh. This method run in O(n)
870 ///////////////////////////////////////////////////////////////////////////////
871 int SMESH_Mesh::NbQuadrangles() throw(SALOME_Exception)
873 Unexpect aCatch(SalomeException);
876 SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
877 //while(itFaces->more()) if(itFaces->next()->NbNodes()==4) Nb++;
878 const SMDS_MeshFace * curFace;
879 while (itFaces->more()) {
880 curFace = itFaces->next();
881 if (!curFace->IsPoly() && curFace->NbNodes() == 4) Nb++;
886 ///////////////////////////////////////////////////////////////////////////////
887 /// Return the number of polygonal faces in the mesh. This method run in O(n)
888 ///////////////////////////////////////////////////////////////////////////////
889 int SMESH_Mesh::NbPolygons() throw(SALOME_Exception)
891 Unexpect aCatch(SalomeException);
893 SMDS_FaceIteratorPtr itFaces = _myMeshDS->facesIterator();
894 while (itFaces->more())
895 if (itFaces->next()->IsPoly()) Nb++;
899 //=============================================================================
903 //=============================================================================
904 int SMESH_Mesh::NbVolumes() throw(SALOME_Exception)
906 Unexpect aCatch(SalomeException);
907 return _myMeshDS->NbVolumes();
910 int SMESH_Mesh::NbTetras() throw(SALOME_Exception)
912 Unexpect aCatch(SalomeException);
914 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
915 //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==4) Nb++;
916 const SMDS_MeshVolume * curVolume;
917 while (itVolumes->more()) {
918 curVolume = itVolumes->next();
919 if (!curVolume->IsPoly() && curVolume->NbNodes() == 4) Nb++;
924 int SMESH_Mesh::NbHexas() throw(SALOME_Exception)
926 Unexpect aCatch(SalomeException);
928 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
929 //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==8) Nb++;
930 const SMDS_MeshVolume * curVolume;
931 while (itVolumes->more()) {
932 curVolume = itVolumes->next();
933 if (!curVolume->IsPoly() && curVolume->NbNodes() == 8) Nb++;
938 int SMESH_Mesh::NbPyramids() throw(SALOME_Exception)
940 Unexpect aCatch(SalomeException);
942 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
943 //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==5) Nb++;
944 const SMDS_MeshVolume * curVolume;
945 while (itVolumes->more()) {
946 curVolume = itVolumes->next();
947 if (!curVolume->IsPoly() && curVolume->NbNodes() == 5) Nb++;
952 int SMESH_Mesh::NbPrisms() throw(SALOME_Exception)
954 Unexpect aCatch(SalomeException);
956 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
957 //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==6) Nb++;
958 const SMDS_MeshVolume * curVolume;
959 while (itVolumes->more()) {
960 curVolume = itVolumes->next();
961 if (!curVolume->IsPoly() && curVolume->NbNodes() == 6) Nb++;
966 int SMESH_Mesh::NbPolyhedrons() throw(SALOME_Exception)
968 Unexpect aCatch(SalomeException);
970 SMDS_VolumeIteratorPtr itVolumes = _myMeshDS->volumesIterator();
971 while (itVolumes->more())
972 if (itVolumes->next()->IsPoly()) Nb++;
976 //=============================================================================
980 //=============================================================================
981 int SMESH_Mesh::NbSubMesh() throw(SALOME_Exception)
983 Unexpect aCatch(SalomeException);
984 return _myMeshDS->NbSubMesh();
987 //=======================================================================
988 //function : IsNotConformAllowed
989 //purpose : check if a hypothesis alowing notconform mesh is present
990 //=======================================================================
992 bool SMESH_Mesh::IsNotConformAllowed() const
994 if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed");
996 SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" ));
997 return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false );
1000 //=======================================================================
1001 //function : IsMainShape
1003 //=======================================================================
1005 bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const
1007 return theShape.IsSame(_myMeshDS->ShapeToMesh() );
1010 //=============================================================================
1014 //=============================================================================
1016 SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
1017 const char* theName,
1019 const TopoDS_Shape& theShape)
1021 if (_mapGroup.find(_groupId) != _mapGroup.end())
1024 SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape);
1025 GetMeshDS()->AddGroup( aGroup->GetGroupDS() );
1026 _mapGroup[_groupId++] = aGroup;
1030 //=============================================================================
1034 //=============================================================================
1036 SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID)
1038 if (_mapGroup.find(theGroupID) == _mapGroup.end())
1040 return _mapGroup[theGroupID];
1044 //=============================================================================
1048 //=============================================================================
1050 list<int> SMESH_Mesh::GetGroupIds()
1053 for ( map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
1054 anIds.push_back( it->first );
1060 //=============================================================================
1064 //=============================================================================
1066 void SMESH_Mesh::RemoveGroup (const int theGroupID)
1068 if (_mapGroup.find(theGroupID) == _mapGroup.end())
1070 GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() );
1071 _mapGroup.erase (theGroupID);
1072 delete _mapGroup[theGroupID];
1075 //=============================================================================
1077 * IsLocal1DHypothesis
1078 * Returns a local 1D hypothesis used for theEdge
1080 //=============================================================================
1081 const SMESH_Hypothesis* SMESH_Mesh::IsLocal1DHypothesis (const TopoDS_Shape& theEdge)
1083 SMESH_HypoFilter filter( SMESH_HypoFilter::HasDim( 1 ));
1084 filter.AndNot( SMESH_HypoFilter::IsAlgo() );
1085 filter.AndNot( SMESH_HypoFilter::IsGlobal( GetMeshDS()->ShapeToMesh() ));
1087 return GetHypothesis( theEdge, filter, true );
1090 //=============================================================================
1092 * IsPropagationHypothesis
1094 //=============================================================================
1095 bool SMESH_Mesh::IsPropagationHypothesis (const TopoDS_Shape& theEdge)
1097 return _mapPropagationChains.Contains(theEdge);
1100 //=============================================================================
1102 * IsPropagatedHypothesis
1104 //=============================================================================
1105 bool SMESH_Mesh::IsPropagatedHypothesis (const TopoDS_Shape& theEdge,
1106 TopoDS_Shape& theMainEdge)
1108 int nbChains = _mapPropagationChains.Extent();
1109 for (int i = 1; i <= nbChains; i++) {
1110 const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i);
1111 if (aChain.Contains(theEdge)) {
1112 theMainEdge = _mapPropagationChains.FindKey(i);
1119 //=============================================================================
1123 //=============================================================================
1125 bool SMESH_Mesh::IsReversedInChain (const TopoDS_Shape& theEdge,
1126 const TopoDS_Shape& theMainEdge)
1128 if ( !theMainEdge.IsNull() && !theEdge.IsNull() &&
1129 _mapPropagationChains.Contains( theMainEdge ))
1131 const TopTools_IndexedMapOfShape& aChain =
1132 _mapPropagationChains.FindFromKey( theMainEdge );
1133 int index = aChain.FindIndex( theEdge );
1135 return aChain(index).Orientation() == TopAbs_REVERSED;
1140 //=============================================================================
1142 * CleanMeshOnPropagationChain
1144 //=============================================================================
1145 void SMESH_Mesh::CleanMeshOnPropagationChain (const TopoDS_Shape& theMainEdge)
1147 const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromKey(theMainEdge);
1148 int i, nbEdges = aChain.Extent();
1149 for (i = 1; i <= nbEdges; i++) {
1150 TopoDS_Shape anEdge = aChain.FindKey(i);
1151 SMESH_subMesh *subMesh = GetSubMesh(anEdge);
1152 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
1153 if (subMeshDS && subMeshDS->NbElements() > 0) {
1154 subMesh->ComputeStateEngine(SMESH_subMesh::CLEANDEP);
1159 //=============================================================================
1161 * RebuildPropagationChains
1162 * Rebuild all existing propagation chains.
1163 * Have to be used, if 1D hypothesis have been assigned/removed to/from any edge
1165 //=============================================================================
1166 bool SMESH_Mesh::RebuildPropagationChains()
1170 // Clean all chains, because they can be not up-to-date
1171 int i, nbChains = _mapPropagationChains.Extent();
1172 for (i = 1; i <= nbChains; i++) {
1173 TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i);
1174 CleanMeshOnPropagationChain(aMainEdge);
1175 _mapPropagationChains.ChangeFromIndex(i).Clear();
1179 for (i = 1; i <= nbChains; i++) {
1180 TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i);
1181 if (!BuildPropagationChain(aMainEdge))
1183 CleanMeshOnPropagationChain(aMainEdge);
1189 //=============================================================================
1191 * RemovePropagationChain
1192 * Have to be used, if Propagation hypothesis is removed from <theMainEdge>
1194 //=============================================================================
1195 bool SMESH_Mesh::RemovePropagationChain (const TopoDS_Shape& theMainEdge)
1197 if (!_mapPropagationChains.Contains(theMainEdge))
1200 // Clean mesh elements and nodes, built on the chain
1201 CleanMeshOnPropagationChain(theMainEdge);
1204 _mapPropagationChains.ChangeFromKey(theMainEdge).Clear();
1206 // Remove the chain from the map
1207 int i = _mapPropagationChains.FindIndex(theMainEdge);
1208 if ( i == _mapPropagationChains.Extent() )
1209 _mapPropagationChains.RemoveLast();
1211 TopoDS_Vertex anEmptyShape;
1213 BB.MakeVertex(anEmptyShape, gp_Pnt(0,0,0), 0.1);
1214 TopTools_IndexedMapOfShape anEmptyMap;
1215 _mapPropagationChains.Substitute(i, anEmptyShape, anEmptyMap);
1221 //=============================================================================
1223 * BuildPropagationChain
1225 //=============================================================================
1226 bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge)
1228 if (theMainEdge.ShapeType() != TopAbs_EDGE) return true;
1230 // Add new chain, if there is no
1231 if (!_mapPropagationChains.Contains(theMainEdge)) {
1232 TopTools_IndexedMapOfShape aNewChain;
1233 _mapPropagationChains.Add(theMainEdge, aNewChain);
1236 // Check presence of 1D hypothesis to be propagated
1237 const SMESH_Hypothesis* aMainHyp = IsLocal1DHypothesis(theMainEdge);
1239 MESSAGE("Warning: There is no 1D hypothesis to propagate. Please, assign.");
1243 // Edges, on which the 1D hypothesis will be propagated from <theMainEdge>
1244 TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge);
1245 if (aChain.Extent() > 0) {
1246 CleanMeshOnPropagationChain(theMainEdge);
1250 // At first put <theMainEdge> in the chain
1251 aChain.Add(theMainEdge);
1253 // List of edges, added to chain on the previous cycle pass
1254 TopTools_ListOfShape listPrevEdges;
1255 listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD ));
1257 // 5____4____3____4____5____6
1260 // 4____3____2____3____4____5
1261 // | | | | | | Number in the each knot of
1262 // | | | | | | grid indicates cycle pass,
1263 // 3____2____1____2____3____4 on which corresponding edge
1264 // | | | | | | (perpendicular to the plane
1265 // | | | | | | of view) will be found.
1266 // 2____1____0____1____2____3
1269 // 3____2____1____2____3____4
1271 // Collect all edges pass by pass
1272 while (listPrevEdges.Extent() > 0) {
1273 // List of edges, added to chain on this cycle pass
1274 TopTools_ListOfShape listCurEdges;
1276 // Find the next portion of edges
1277 TopTools_ListIteratorOfListOfShape itE (listPrevEdges);
1278 for (; itE.More(); itE.Next()) {
1279 TopoDS_Shape anE = itE.Value();
1281 // Iterate on faces, having edge <anE>
1282 TopTools_ListIteratorOfListOfShape itA (GetAncestors(anE));
1283 for (; itA.More(); itA.Next()) {
1284 TopoDS_Shape aW = itA.Value();
1286 // There are objects of different type among the ancestors of edge
1287 if (aW.ShapeType() == TopAbs_WIRE) {
1288 TopoDS_Shape anOppE;
1290 BRepTools_WireExplorer aWE (TopoDS::Wire(aW));
1291 Standard_Integer nb = 1, found = 0;
1292 TopTools_Array1OfShape anEdges (1,4);
1293 for (; aWE.More(); aWE.Next(), nb++) {
1298 anEdges(nb) = aWE.Current();
1299 if (!_mapAncestors.Contains(anEdges(nb))) {
1300 MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!");
1303 if (anEdges(nb).IsSame(anE)) found = nb;
1306 if (nb == 5 && found > 0) {
1307 // Quadrangle face found, get an opposite edge
1308 Standard_Integer opp = found + 2;
1309 if (opp > 4) opp -= 4;
1310 anOppE = anEdges(opp);
1312 // add anOppE to aChain if ...
1313 if (!aChain.Contains(anOppE)) { // ... anOppE is not in aChain
1314 if (!IsLocal1DHypothesis(anOppE)) { // ... no other 1d hyp on anOppE
1315 TopoDS_Shape aMainEdgeForOppEdge; // ... no other hyp is propagated to anOppE
1316 if (!IsPropagatedHypothesis(anOppE, aMainEdgeForOppEdge))
1318 // Add found edge to the chain oriented so that to
1319 // have it co-directed with a forward MainEdge
1320 TopAbs_Orientation ori = anE.Orientation();
1321 if ( anEdges(opp).Orientation() == anEdges(found).Orientation() )
1322 ori = TopAbs::Reverse( ori );
1323 anOppE.Orientation( ori );
1325 listCurEdges.Append(anOppE);
1329 MESSAGE("Error: Collision between propagated hypotheses");
1330 CleanMeshOnPropagationChain(theMainEdge);
1332 return ( aMainHyp == IsLocal1DHypothesis(aMainEdgeForOppEdge) );
1336 } // if (nb == 5 && found > 0)
1337 } // if (aF.ShapeType() == TopAbs_WIRE)
1338 } // for (; itF.More(); itF.Next())
1339 } // for (; itE.More(); itE.Next())
1341 listPrevEdges = listCurEdges;
1342 } // while (listPrevEdges.Extent() > 0)
1344 CleanMeshOnPropagationChain(theMainEdge);
1348 //=======================================================================
1349 //function : GetAncestors
1350 //purpose : return list of ancestors of theSubShape in the order
1351 // that lower dimention shapes come first.
1352 //=======================================================================
1354 const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) const
1356 if ( _mapAncestors.Contains( theS ) )
1357 return _mapAncestors.FindFromKey( theS );
1359 static TopTools_ListOfShape emptyList;
1363 //=======================================================================
1365 //purpose : dumps contents of mesh to stream [ debug purposes ]
1366 //=======================================================================
1367 ostream& SMESH_Mesh::Dump(ostream& save)
1369 save << "========================== Dump contents of mesh ==========================" << endl;
1370 save << "1) Total number of nodes: " << NbNodes() << endl;
1371 save << "2) Total number of edges: " << NbEdges() << endl;
1372 save << "3) Total number of faces: " << NbFaces() << endl;
1373 if ( NbFaces() > 0 ) {
1374 int nb3 = NbTriangles();
1375 int nb4 = NbQuadrangles();
1376 save << "3.1.) Number of triangles: " << nb3 << endl;
1377 save << "3.2.) Number of quadrangles: " << nb4 << endl;
1378 if ( nb3 + nb4 != NbFaces() ) {
1379 map<int,int> myFaceMap;
1380 SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
1381 while( itFaces->more( ) ) {
1382 int nbNodes = itFaces->next()->NbNodes();
1383 if ( myFaceMap.find( nbNodes ) == myFaceMap.end() )
1384 myFaceMap[ nbNodes ] = 0;
1385 myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1;
1387 save << "3.3.) Faces in detail: " << endl;
1388 map <int,int>::iterator itF;
1389 for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++)
1390 save << "--> nb nodes: " << itF->first << " - nb elemens: " << itF->second << endl;
1393 save << "4) Total number of volumes: " << NbVolumes() << endl;
1394 if ( NbVolumes() > 0 ) {
1395 int nb8 = NbHexas();
1396 int nb4 = NbTetras();
1397 int nb5 = NbPyramids();
1398 int nb6 = NbPrisms();
1399 save << "4.1.) Number of hexahedrons: " << nb8 << endl;
1400 save << "4.2.) Number of tetrahedrons: " << nb4 << endl;
1401 save << "4.3.) Number of prisms: " << nb6 << endl;
1402 save << "4.4.) Number of pyramides: " << nb5 << endl;
1403 if ( nb8 + nb4 + nb5 + nb6 != NbVolumes() ) {
1404 map<int,int> myVolumesMap;
1405 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
1406 while( itVolumes->more( ) ) {
1407 int nbNodes = itVolumes->next()->NbNodes();
1408 if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() )
1409 myVolumesMap[ nbNodes ] = 0;
1410 myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1;
1412 save << "4.5.) Volumes in detail: " << endl;
1413 map <int,int>::iterator itV;
1414 for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++)
1415 save << "--> nb nodes: " << itV->first << " - nb elemens: " << itV->second << endl;
1418 save << "===========================================================================" << endl;