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 "SMESHDS_Group.hxx"
35 #include "SMESHDS_Script.hxx"
36 #include "SMESHDS_GroupOnGeom.hxx"
37 #include "SMDS_MeshVolume.hxx"
39 #include "utilities.h"
41 #include "DriverMED_W_SMESHDS_Mesh.h"
42 #include "DriverDAT_W_SMDS_Mesh.h"
43 #include "DriverUNV_W_SMDS_Mesh.h"
44 #include "DriverSTL_W_SMDS_Mesh.h"
46 #include "DriverMED_R_SMESHDS_Mesh.h"
47 #include "DriverUNV_R_SMDS_Mesh.h"
48 #include "DriverSTL_R_SMDS_Mesh.h"
50 #include <BRepTools_WireExplorer.hxx>
51 #include <BRep_Builder.hxx>
54 #include <TCollection_AsciiString.hxx>
56 #include <TopTools_ListOfShape.hxx>
57 #include <TopTools_Array1OfShape.hxx>
58 #include <TopTools_ListIteratorOfListOfShape.hxx>
62 #include "Utils_ExceptHandlers.hxx"
65 static int MYDEBUG = 0;
67 static int MYDEBUG = 0;
71 //=============================================================================
75 //=============================================================================
77 SMESH_Mesh::SMESH_Mesh(int localId, int studyId, SMESH_Gen * gen, SMESHDS_Document * myDocument)
80 INFOS("SMESH_Mesh::SMESH_Mesh(int localId)");
84 _myDocument = myDocument;
85 _idDoc = _myDocument->NewMesh();
86 _myMeshDS = _myDocument->GetMesh(_idDoc);
87 _isShapeToMesh = false;
90 //=============================================================================
94 //=============================================================================
96 SMESH_Mesh::~SMESH_Mesh()
98 INFOS("SMESH_Mesh::~SMESH_Mesh");
101 map < int, SMESH_Group * >::iterator itg;
102 for (itg = _mapGroup.begin(); itg != _mapGroup.end(); itg++) {
103 SMESH_Group *aGroup = (*itg).second;
108 //=============================================================================
112 //=============================================================================
114 void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
116 if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh");
118 if ( !_myMeshDS->ShapeToMesh().IsNull() && aShape.IsNull() )
120 // removal of a shape to mesh, delete objects referring to sub-shapes:
122 map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.begin();
123 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
126 // - groups on geometry
127 map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
128 while ( i_gr != _mapGroup.end() ) {
129 if ( dynamic_cast<SMESHDS_GroupOnGeom*>( i_gr->second->GetGroupDS() )) {
130 _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() );
132 _mapGroup.erase( i_gr++ );
137 _mapAncestors.Clear();
138 _mapPropagationChains.Clear();
143 throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
145 _isShapeToMesh = true;
146 _myMeshDS->ShapeToMesh(aShape);
148 //EAP: 1/9/04 TopExp::MapShapes(aShape, _subShapes); USE the same map of _myMeshDS
151 //=======================================================================
152 //function : UNVToMesh
154 //=======================================================================
156 int SMESH_Mesh::UNVToMesh(const char* theFileName)
158 if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<<theFileName);
160 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
161 _isShapeToMesh = true;
162 DriverUNV_R_SMDS_Mesh myReader;
163 myReader.SetMesh(_myMeshDS);
164 myReader.SetFile(theFileName);
165 myReader.SetMeshId(-1);
168 MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
169 MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
170 MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
171 MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
176 //=======================================================================
177 //function : MEDToMesh
179 //=======================================================================
181 int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
183 if(MYDEBUG) MESSAGE("MEDToMesh - theFileName = "<<theFileName<<", mesh name = "<<theMeshName);
185 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
186 _isShapeToMesh = true;
187 DriverMED_R_SMESHDS_Mesh myReader;
188 myReader.SetMesh(_myMeshDS);
189 myReader.SetMeshId(-1);
190 myReader.SetFile(theFileName);
191 myReader.SetMeshName(theMeshName);
192 Driver_Mesh::Status status = myReader.Perform();
194 MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
195 MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
196 MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
197 MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
200 // Reading groups (sub-meshes are out of scope of MED import functionality)
201 list<string> aGroupNames = myReader.GetGroupNames();
202 if(MYDEBUG) MESSAGE("MEDToMesh - Nb groups = "<<aGroupNames.size());
204 for ( list<string>::iterator it = aGroupNames.begin(); it != aGroupNames.end(); it++ ) {
205 SMESH_Group* aGroup = AddGroup( SMDSAbs_All, it->c_str(), anId );
207 if(MYDEBUG) MESSAGE("MEDToMesh - group added: "<<it->c_str());
208 SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
210 aGroupDS->SetStoreName( it->c_str() );
211 myReader.GetGroup( aGroupDS );
218 //=======================================================================
219 //function : STLToMesh
221 //=======================================================================
223 int SMESH_Mesh::STLToMesh(const char* theFileName)
225 if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<<theFileName);
227 throw SALOME_Exception(LOCALIZED("a shape to mesh has already been defined"));
228 _isShapeToMesh = true;
229 DriverSTL_R_SMDS_Mesh myReader;
230 myReader.SetMesh(_myMeshDS);
231 myReader.SetFile(theFileName);
232 myReader.SetMeshId(-1);
235 MESSAGE("MEDToMesh - _myMeshDS->NbNodes() = "<<_myMeshDS->NbNodes());
236 MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges());
237 MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces());
238 MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes());
243 //=============================================================================
247 //=============================================================================
249 SMESH_Hypothesis::Hypothesis_Status
250 SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
251 int anHypId ) throw(SALOME_Exception)
253 Unexpect aCatch(SalomeException);
254 if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis");
256 SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
257 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
258 if ( subMeshDS && subMeshDS->IsComplexSubmesh() )
260 // return the worst but not fatal state of all group memebers
261 SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
262 aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
263 aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
264 for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
266 ret = AddHypothesis( itS.Value(), anHypId );
267 if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
268 aWorstNotFatal = ret;
269 if ( ret < aBestRet )
272 if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
274 return aWorstNotFatal;
277 StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
278 if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
280 if(MYDEBUG) MESSAGE("Hypothesis ID does not give an hypothesis");
285 throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
288 SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
289 MESSAGE( "SMESH_Mesh::AddHypothesis " << anHyp->GetName() );
291 bool isGlobalHyp = IsMainShape( aSubShape );
293 // NotConformAllowed can be only global
296 string hypName = anHyp->GetName();
297 if ( hypName == "NotConformAllowed" )
299 if(MYDEBUG) MESSAGE( "Hypotesis <NotConformAllowed> can be only global" );
300 return SMESH_Hypothesis::HYP_INCOMPATIBLE;
307 if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
308 event = SMESH_subMesh::ADD_HYP;
310 event = SMESH_subMesh::ADD_ALGO;
311 SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
314 if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
315 !subMesh->IsApplicableHypotesis( anHyp )) // is added on father
317 if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
318 event = SMESH_subMesh::ADD_FATHER_HYP;
320 event = SMESH_subMesh::ADD_FATHER_ALGO;
321 SMESH_Hypothesis::Hypothesis_Status ret2 =
322 subMesh->SubMeshesAlgoStateEngine(event, anHyp);
326 // check concurent hypotheses on ansestors
327 if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
329 const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
330 map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
331 for ( ; smIt != smMap.end(); smIt++ ) {
332 if ( smIt->second->IsApplicableHypotesis( anHyp )) {
333 ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
343 if(MYDEBUG) subMesh->DumpAlgoState(true);
348 //=============================================================================
352 //=============================================================================
354 SMESH_Hypothesis::Hypothesis_Status
355 SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
356 int anHypId)throw(SALOME_Exception)
358 Unexpect aCatch(SalomeException);
359 if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis");
361 SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
362 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
363 if ( subMeshDS && subMeshDS->IsComplexSubmesh() )
365 // return the worst but not fatal state of all group memebers
366 SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
367 aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
368 aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
369 for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
371 ret = RemoveHypothesis( itS.Value(), anHypId );
372 if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
373 aWorstNotFatal = ret;
374 if ( ret < aBestRet )
377 if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
379 return aWorstNotFatal;
382 StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
383 if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
384 throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
386 SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
387 int hypType = anHyp->GetType();
388 if(MYDEBUG) SCRUTE(hypType);
393 if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
394 event = SMESH_subMesh::REMOVE_HYP;
396 event = SMESH_subMesh::REMOVE_ALGO;
397 SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
399 // there may appear concurrent hyps that were covered by the removed hyp
400 if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
401 subMesh->IsApplicableHypotesis( anHyp ) &&
402 subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
403 ret = SMESH_Hypothesis::HYP_CONCURENT;
406 if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
407 !subMesh->IsApplicableHypotesis( anHyp )) // is removed from father
409 if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
410 event = SMESH_subMesh::REMOVE_FATHER_HYP;
412 event = SMESH_subMesh::REMOVE_FATHER_ALGO;
413 SMESH_Hypothesis::Hypothesis_Status ret2 =
414 subMesh->SubMeshesAlgoStateEngine(event, anHyp);
415 if (ret2 > ret) // more severe
418 // check concurent hypotheses on ansestors
419 if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
421 const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
422 map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
423 for ( ; smIt != smMap.end(); smIt++ ) {
424 if ( smIt->second->IsApplicableHypotesis( anHyp )) {
425 ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
435 if(MYDEBUG) subMesh->DumpAlgoState(true);
436 if(MYDEBUG) SCRUTE(ret);
440 //=============================================================================
444 //=============================================================================
446 SMESHDS_Mesh * SMESH_Mesh::GetMeshDS()
451 //=============================================================================
455 //=============================================================================
457 const list<const SMESHDS_Hypothesis*>&
458 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
459 throw(SALOME_Exception)
461 Unexpect aCatch(SalomeException);
462 return _myMeshDS->GetHypothesis(aSubShape);
465 //=============================================================================
469 //=============================================================================
471 const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
473 Unexpect aCatch(SalomeException);
474 if(MYDEBUG) MESSAGE("SMESH_Mesh::GetLog");
475 return _myMeshDS->GetScript()->GetCommands();
478 //=============================================================================
482 //=============================================================================
483 void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
485 Unexpect aCatch(SalomeException);
486 if(MYDEBUG) MESSAGE("SMESH_Mesh::ClearLog");
487 _myMeshDS->GetScript()->Clear();
490 //=============================================================================
494 //=============================================================================
496 int SMESH_Mesh::GetId()
498 if(MYDEBUG) MESSAGE("SMESH_Mesh::GetId");
502 //=============================================================================
506 //=============================================================================
508 SMESH_Gen *SMESH_Mesh::GetGen()
513 //=============================================================================
515 * Get or Create the SMESH_subMesh object implementation
517 //=============================================================================
519 SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
520 throw(SALOME_Exception)
522 Unexpect aCatch(SalomeException);
523 SMESH_subMesh *aSubMesh;
524 int index = _myMeshDS->ShapeToIndex(aSubShape);
526 // for submeshes on GEOM Group
527 if ( !index && aSubShape.ShapeType() == TopAbs_COMPOUND ) {
528 TopoDS_Iterator it( aSubShape );
530 index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
533 if (_mapSubMesh.find(index) != _mapSubMesh.end())
535 aSubMesh = _mapSubMesh[index];
539 aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
540 _mapSubMesh[index] = aSubMesh;
545 //=============================================================================
547 * Get the SMESH_subMesh object implementation. Dont create it, return null
548 * if it does not exist.
550 //=============================================================================
552 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
553 throw(SALOME_Exception)
555 Unexpect aCatch(SalomeException);
556 bool isFound = false;
557 SMESH_subMesh *aSubMesh = NULL;
559 int index = _myMeshDS->ShapeToIndex(aSubShape);
560 if (_mapSubMesh.find(index) != _mapSubMesh.end())
562 aSubMesh = _mapSubMesh[index];
570 //=======================================================================
571 //function : IsUsedHypothesis
572 //purpose : Return True if anHyp is used to mesh aSubShape
573 //=======================================================================
575 bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
576 const TopoDS_Shape & aSubShape)
578 // check if anHyp is applicable to aSubShape
579 SMESH_subMesh * subMesh = GetSubMeshContaining( aSubShape );
581 !subMesh->IsApplicableHypotesis(static_cast<SMESH_Hypothesis*>(anHyp)))
584 SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape);
587 if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
588 return ( anHyp == algo );
590 // algorithm parameter
593 // look trough hypotheses used by algo
594 const list <const SMESHDS_Hypothesis * >&usedHyps =
595 algo->GetUsedHypothesis(*this, aSubShape);
596 list <const SMESHDS_Hypothesis * >::const_iterator itl;
597 for (itl = usedHyps.begin(); itl != usedHyps.end(); itl++)
603 // look through all assigned hypotheses
605 const list <const SMESHDS_Hypothesis * >&usedHyps =
606 _myMeshDS->GetHypothesis( aSubShape );
607 list <const SMESHDS_Hypothesis * >::const_iterator itl;
608 for (itl = usedHyps.begin(); itl != usedHyps.end(); itl++)
614 TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
615 for (; it.More(); it.Next())
617 const list <const SMESHDS_Hypothesis * >&usedHyps =
618 _myMeshDS->GetHypothesis( aSubShape );
619 list <const SMESHDS_Hypothesis * >::const_iterator itl;
620 for (itl = usedHyps.begin(); itl != usedHyps.end(); itl++)
630 //=============================================================================
634 //=============================================================================
636 const list < SMESH_subMesh * >&
637 SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
638 throw(SALOME_Exception)
640 Unexpect aCatch(SalomeException);
641 if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis");
642 map < int, SMESH_subMesh * >::iterator itsm;
643 _subMeshesUsingHypothesisList.clear();
644 for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++)
646 SMESH_subMesh *aSubMesh = (*itsm).second;
647 if ( IsUsedHypothesis ( anHyp, aSubMesh->GetSubShape() ))
648 _subMeshesUsingHypothesisList.push_back(aSubMesh);
650 return _subMeshesUsingHypothesisList;
653 //=============================================================================
657 //=============================================================================
659 void SMESH_Mesh::ExportMED(const char *file,
660 const char* theMeshName,
663 throw(SALOME_Exception)
665 Unexpect aCatch(SalomeException);
666 DriverMED_W_SMESHDS_Mesh myWriter;
667 myWriter.SetFile ( file, MED::EVersion(theVersion) );
668 myWriter.SetMesh ( _myMeshDS );
670 myWriter.SetMeshId ( _idDoc );
672 myWriter.SetMeshId ( -1 );
673 myWriter.SetMeshName( theMeshName );
676 if ( theAutoGroups ) {
677 myWriter.AddGroupOfNodes();
678 myWriter.AddGroupOfEdges();
679 myWriter.AddGroupOfFaces();
680 myWriter.AddGroupOfVolumes();
683 for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
684 SMESH_Group* aGroup = it->second;
685 SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
687 aGroupDS->SetStoreName( aGroup->GetName() );
688 myWriter.AddGroup( aGroupDS );
695 void SMESH_Mesh::ExportDAT(const char *file) throw(SALOME_Exception)
697 Unexpect aCatch(SalomeException);
698 DriverDAT_W_SMDS_Mesh myWriter;
699 myWriter.SetFile(string(file));
700 myWriter.SetMesh(_myMeshDS);
701 myWriter.SetMeshId(_idDoc);
705 void SMESH_Mesh::ExportUNV(const char *file) throw(SALOME_Exception)
707 Unexpect aCatch(SalomeException);
708 DriverUNV_W_SMDS_Mesh myWriter;
709 myWriter.SetFile(string(file));
710 myWriter.SetMesh(_myMeshDS);
711 myWriter.SetMeshId(_idDoc);
715 void SMESH_Mesh::ExportSTL(const char *file, const bool isascii) throw(SALOME_Exception)
717 Unexpect aCatch(SalomeException);
718 DriverSTL_W_SMDS_Mesh myWriter;
719 myWriter.SetFile(string(file));
720 myWriter.SetIsAscii( isascii );
721 myWriter.SetMesh(_myMeshDS);
722 myWriter.SetMeshId(_idDoc);
726 //=============================================================================
730 //=============================================================================
731 int SMESH_Mesh::NbNodes() throw(SALOME_Exception)
733 Unexpect aCatch(SalomeException);
734 return _myMeshDS->NbNodes();
737 //=============================================================================
741 //=============================================================================
742 int SMESH_Mesh::NbEdges() throw(SALOME_Exception)
744 Unexpect aCatch(SalomeException);
745 return _myMeshDS->NbEdges();
748 //=============================================================================
752 //=============================================================================
753 int SMESH_Mesh::NbFaces() throw(SALOME_Exception)
755 Unexpect aCatch(SalomeException);
756 return _myMeshDS->NbFaces();
759 ///////////////////////////////////////////////////////////////////////////////
760 /// Return the number of 3 nodes faces in the mesh. This method run in O(n)
761 ///////////////////////////////////////////////////////////////////////////////
762 int SMESH_Mesh::NbTriangles() throw(SALOME_Exception)
764 Unexpect aCatch(SalomeException);
767 SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
768 while(itFaces->more()) if(itFaces->next()->NbNodes()==3) Nb++;
772 ///////////////////////////////////////////////////////////////////////////////
773 /// Return the number of 4 nodes faces in the mesh. This method run in O(n)
774 ///////////////////////////////////////////////////////////////////////////////
775 int SMESH_Mesh::NbQuadrangles() throw(SALOME_Exception)
777 Unexpect aCatch(SalomeException);
780 SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
781 while(itFaces->more()) if(itFaces->next()->NbNodes()==4) Nb++;
785 //=============================================================================
789 //=============================================================================
790 int SMESH_Mesh::NbVolumes() throw(SALOME_Exception)
792 Unexpect aCatch(SalomeException);
793 return _myMeshDS->NbVolumes();
796 int SMESH_Mesh::NbTetras() throw(SALOME_Exception)
798 Unexpect aCatch(SalomeException);
800 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
801 while(itVolumes->more()) if(itVolumes->next()->NbNodes()==4) Nb++;
805 int SMESH_Mesh::NbHexas() throw(SALOME_Exception)
807 Unexpect aCatch(SalomeException);
809 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
810 while(itVolumes->more()) if(itVolumes->next()->NbNodes()==8) Nb++;
814 int SMESH_Mesh::NbPyramids() throw(SALOME_Exception)
816 Unexpect aCatch(SalomeException);
818 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
819 while(itVolumes->more()) if(itVolumes->next()->NbNodes()==5) Nb++;
823 int SMESH_Mesh::NbPrisms() throw(SALOME_Exception)
825 Unexpect aCatch(SalomeException);
827 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
828 while(itVolumes->more()) if(itVolumes->next()->NbNodes()==6) Nb++;
832 //=============================================================================
836 //=============================================================================
837 int SMESH_Mesh::NbSubMesh() throw(SALOME_Exception)
839 Unexpect aCatch(SalomeException);
840 return _myMeshDS->NbSubMesh();
843 //=======================================================================
844 //function : IsNotConformAllowed
845 //purpose : check if a hypothesis alowing notconform mesh is present
846 //=======================================================================
848 bool SMESH_Mesh::IsNotConformAllowed() const
850 if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed");
852 const list<const SMESHDS_Hypothesis*>& listHyp =
853 _myMeshDS->GetHypothesis( _myMeshDS->ShapeToMesh() );
854 list<const SMESHDS_Hypothesis*>::const_iterator it=listHyp.begin();
855 while (it!=listHyp.end())
857 const SMESHDS_Hypothesis *aHyp = *it;
858 string hypName = aHyp->GetName();
859 if ( hypName == "NotConformAllowed" )
866 //=======================================================================
867 //function : IsMainShape
869 //=======================================================================
871 bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const
873 return theShape.IsSame(_myMeshDS->ShapeToMesh() );
876 //=============================================================================
880 //=============================================================================
882 SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
885 const TopoDS_Shape& theShape)
887 if (_mapGroup.find(_groupId) != _mapGroup.end())
890 SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape);
891 GetMeshDS()->AddGroup( aGroup->GetGroupDS() );
892 _mapGroup[_groupId++] = aGroup;
896 //=============================================================================
900 //=============================================================================
902 SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID)
904 if (_mapGroup.find(theGroupID) == _mapGroup.end())
906 return _mapGroup[theGroupID];
910 //=============================================================================
914 //=============================================================================
916 list<int> SMESH_Mesh::GetGroupIds()
919 for ( map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
920 anIds.push_back( it->first );
926 //=============================================================================
930 //=============================================================================
932 void SMESH_Mesh::RemoveGroup (const int theGroupID)
934 if (_mapGroup.find(theGroupID) == _mapGroup.end())
936 GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() );
937 _mapGroup.erase (theGroupID);
938 delete _mapGroup[theGroupID];
941 //=============================================================================
943 * IsLocal1DHypothesis
944 * Check, if there is 1D hypothesis assigned directly on <theEdge>
946 //=============================================================================
947 bool SMESH_Mesh::IsLocal1DHypothesis (const TopoDS_Shape& theEdge)
949 const SMESHDS_Mesh* meshDS = GetMeshDS();
950 const list<const SMESHDS_Hypothesis*>& listHyp = meshDS->GetHypothesis(theEdge);
951 list<const SMESHDS_Hypothesis*>::const_iterator it = listHyp.begin();
953 for (; it != listHyp.end(); it++) {
954 const SMESH_Hypothesis * aHyp = static_cast<const SMESH_Hypothesis*>(*it);
955 if (aHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO &&
956 aHyp->GetDim() == 1) { // 1D Hypothesis found
963 //=============================================================================
965 * IsPropagationHypothesis
967 //=============================================================================
968 bool SMESH_Mesh::IsPropagationHypothesis (const TopoDS_Shape& theEdge)
970 return _mapPropagationChains.Contains(theEdge);
973 //=============================================================================
975 * IsPropagatedHypothesis
977 //=============================================================================
978 bool SMESH_Mesh::IsPropagatedHypothesis (const TopoDS_Shape& theEdge,
979 TopoDS_Shape& theMainEdge)
981 int nbChains = _mapPropagationChains.Extent();
982 for (int i = 1; i <= nbChains; i++) {
983 const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i);
984 if (aChain.Contains(theEdge)) {
985 theMainEdge = _mapPropagationChains.FindKey(i);
992 //=============================================================================
996 //=============================================================================
998 bool SMESH_Mesh::IsReversedInChain (const TopoDS_Shape& theEdge,
999 const TopoDS_Shape& theMainEdge)
1001 if ( !theMainEdge.IsNull() && !theEdge.IsNull() &&
1002 _mapPropagationChains.Contains( theMainEdge ))
1004 const TopTools_IndexedMapOfShape& aChain =
1005 _mapPropagationChains.FindFromKey( theMainEdge );
1006 int index = aChain.FindIndex( theEdge );
1008 return aChain(index).Orientation() == TopAbs_REVERSED;
1013 //=============================================================================
1015 * CleanMeshOnPropagationChain
1017 //=============================================================================
1018 void SMESH_Mesh::CleanMeshOnPropagationChain (const TopoDS_Shape& theMainEdge)
1020 const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromKey(theMainEdge);
1021 int i, nbEdges = aChain.Extent();
1022 for (i = 1; i <= nbEdges; i++) {
1023 TopoDS_Shape anEdge = aChain.FindKey(i);
1024 SMESH_subMesh *subMesh = GetSubMesh(anEdge);
1025 SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
1026 if (subMeshDS && subMeshDS->NbElements() > 0) {
1027 subMesh->ComputeStateEngine(SMESH_subMesh::CLEANDEP);
1032 //=============================================================================
1034 * RebuildPropagationChains
1035 * Rebuild all existing propagation chains.
1036 * Have to be used, if 1D hypothesis have been assigned/removed to/from any edge
1038 //=============================================================================
1039 bool SMESH_Mesh::RebuildPropagationChains()
1043 // Clean all chains, because they can be not up-to-date
1044 int i, nbChains = _mapPropagationChains.Extent();
1045 for (i = 1; i <= nbChains; i++) {
1046 TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i);
1047 CleanMeshOnPropagationChain(aMainEdge);
1048 _mapPropagationChains.ChangeFromIndex(i).Clear();
1052 for (i = 1; i <= nbChains; i++) {
1053 TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i);
1054 if (!BuildPropagationChain(aMainEdge))
1056 CleanMeshOnPropagationChain(aMainEdge);
1062 //=============================================================================
1064 * RemovePropagationChain
1065 * Have to be used, if Propagation hypothesis is removed from <theMainEdge>
1067 //=============================================================================
1068 bool SMESH_Mesh::RemovePropagationChain (const TopoDS_Shape& theMainEdge)
1070 if (!_mapPropagationChains.Contains(theMainEdge))
1073 // Clean mesh elements and nodes, built on the chain
1074 CleanMeshOnPropagationChain(theMainEdge);
1077 _mapPropagationChains.ChangeFromKey(theMainEdge).Clear();
1079 // Remove the chain from the map
1080 int i = _mapPropagationChains.FindIndex(theMainEdge);
1081 TopoDS_Vertex anEmptyShape;
1083 BB.MakeVertex(anEmptyShape, gp_Pnt(0,0,0), 0.1);
1084 TopTools_IndexedMapOfShape anEmptyMap;
1085 _mapPropagationChains.Substitute(i, anEmptyShape, anEmptyMap);
1090 //=============================================================================
1092 * BuildPropagationChain
1094 //=============================================================================
1095 bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge)
1097 if (theMainEdge.ShapeType() != TopAbs_EDGE) return true;
1099 // Add new chain, if there is no
1100 if (!_mapPropagationChains.Contains(theMainEdge)) {
1101 TopTools_IndexedMapOfShape aNewChain;
1102 _mapPropagationChains.Add(theMainEdge, aNewChain);
1105 // Check presence of 1D hypothesis to be propagated
1106 if (!IsLocal1DHypothesis(theMainEdge)) {
1107 MESSAGE("Warning: There is no 1D hypothesis to propagate. Please, assign.");
1111 // Edges, on which the 1D hypothesis will be propagated from <theMainEdge>
1112 TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge);
1113 if (aChain.Extent() > 0) {
1114 CleanMeshOnPropagationChain(theMainEdge);
1118 // At first put <theMainEdge> in the chain
1119 aChain.Add(theMainEdge);
1121 // List of edges, added to chain on the previous cycle pass
1122 TopTools_ListOfShape listPrevEdges;
1123 listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD ));
1125 // 5____4____3____4____5____6
1128 // 4____3____2____3____4____5
1129 // | | | | | | Number in the each knot of
1130 // | | | | | | grid indicates cycle pass,
1131 // 3____2____1____2____3____4 on which corresponding edge
1132 // | | | | | | (perpendicular to the plane
1133 // | | | | | | of view) will be found.
1134 // 2____1____0____1____2____3
1137 // 3____2____1____2____3____4
1139 // Collect all edges pass by pass
1140 while (listPrevEdges.Extent() > 0) {
1141 // List of edges, added to chain on this cycle pass
1142 TopTools_ListOfShape listCurEdges;
1144 // Find the next portion of edges
1145 TopTools_ListIteratorOfListOfShape itE (listPrevEdges);
1146 for (; itE.More(); itE.Next()) {
1147 TopoDS_Shape anE = itE.Value();
1149 // Iterate on faces, having edge <anE>
1150 TopTools_ListIteratorOfListOfShape itA (GetAncestors(anE));
1151 for (; itA.More(); itA.Next()) {
1152 TopoDS_Shape aW = itA.Value();
1154 // There are objects of different type among the ancestors of edge
1155 if (aW.ShapeType() == TopAbs_WIRE) {
1156 TopoDS_Shape anOppE;
1158 BRepTools_WireExplorer aWE (TopoDS::Wire(aW));
1159 Standard_Integer nb = 1, found = 0;
1160 TopTools_Array1OfShape anEdges (1,4);
1161 for (; aWE.More(); aWE.Next(), nb++) {
1166 anEdges(nb) = aWE.Current();
1167 if (!_mapAncestors.Contains(anEdges(nb))) {
1168 MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!");
1171 if (anEdges(nb).IsSame(anE)) found = nb;
1174 if (nb == 5 && found > 0) {
1175 // Quadrangle face found, get an opposite edge
1176 Standard_Integer opp = found + 2;
1177 if (opp > 4) opp -= 4;
1178 anOppE = anEdges(opp);
1180 if (!aChain.Contains(anOppE)) {
1181 if (!IsLocal1DHypothesis(anOppE)) {
1182 TopoDS_Shape aMainEdgeForOppEdge;
1183 if (IsPropagatedHypothesis(anOppE, aMainEdgeForOppEdge)) {
1185 MESSAGE("Error: Collision between propagated hypotheses");
1186 CleanMeshOnPropagationChain(theMainEdge);
1190 // Add found edge to the chain oriented so that to
1191 // have it in aChain co-directed with theMainEdge
1192 TopAbs_Orientation ori = anE.Orientation();
1193 if ( anEdges(opp).Orientation() == anEdges(found).Orientation() )
1194 ori = TopAbs::Reverse( ori );
1195 anOppE.Orientation( ori );
1197 listCurEdges.Append(anOppE);
1201 } // if (nb == 5 && found > 0)
1202 } // if (aF.ShapeType() == TopAbs_WIRE)
1203 } // for (; itF.More(); itF.Next())
1204 } // for (; itE.More(); itE.Next())
1206 listPrevEdges = listCurEdges;
1207 } // while (listPrevEdges.Extent() > 0)
1209 CleanMeshOnPropagationChain(theMainEdge);
1213 //=======================================================================
1214 //function : GetAncestors
1215 //purpose : return list of ancestors of theSubShape in the order
1216 // that lower dimention shapes come first.
1217 //=======================================================================
1219 const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS)
1221 if ( _mapAncestors.IsEmpty() )
1223 // fill _mapAncestors
1224 int desType, ancType;
1225 for ( desType = TopAbs_EDGE; desType > TopAbs_COMPOUND; desType-- )
1226 for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
1227 TopExp::MapShapesAndAncestors (_myMeshDS->ShapeToMesh(),
1228 (TopAbs_ShapeEnum) desType,
1229 (TopAbs_ShapeEnum) ancType,
1233 if ( _mapAncestors.Contains( theS ) )
1234 return _mapAncestors.FindFromKey( theS );
1236 static TopTools_ListOfShape emptyList;
1240 //=======================================================================
1242 //purpose : dumps contents of mesh to stream [ debug purposes ]
1243 //=======================================================================
1244 ostream& SMESH_Mesh::Dump(ostream& save)
1246 save << "========================== Dump contents of mesh ==========================" << endl;
1247 save << "1) Total number of nodes: " << NbNodes() << endl;
1248 save << "2) Total number of edges: " << NbEdges() << endl;
1249 save << "3) Total number of faces: " << NbFaces() << endl;
1250 if ( NbFaces() > 0 ) {
1251 int nb3 = NbTriangles();
1252 int nb4 = NbQuadrangles();
1253 save << "3.1.) Number of triangles: " << nb3 << endl;
1254 save << "3.2.) Number of quadrangles: " << nb4 << endl;
1255 if ( nb3 + nb4 != NbFaces() ) {
1256 map<int,int> myFaceMap;
1257 SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
1258 while( itFaces->more( ) ) {
1259 int nbNodes = itFaces->next()->NbNodes();
1260 if ( myFaceMap.find( nbNodes ) == myFaceMap.end() )
1261 myFaceMap[ nbNodes ] = 0;
1262 myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1;
1264 save << "3.3.) Faces in detail: " << endl;
1265 map <int,int>::iterator itF;
1266 for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++)
1267 save << "--> nb nodes: " << itF->first << " - nb elemens: " << itF->second << endl;
1270 save << "4) Total number of volumes: " << NbVolumes() << endl;
1271 if ( NbVolumes() > 0 ) {
1272 int nb8 = NbHexas();
1273 int nb4 = NbTetras();
1274 int nb5 = NbPyramids();
1275 int nb6 = NbPrisms();
1276 save << "4.1.) Number of hexahedrons: " << nb8 << endl;
1277 save << "4.2.) Number of tetrahedrons: " << nb4 << endl;
1278 save << "4.3.) Number of prisms: " << nb6 << endl;
1279 save << "4.4.) Number of pyramides: " << nb5 << endl;
1280 if ( nb8 + nb4 + nb5 + nb6 != NbVolumes() ) {
1281 map<int,int> myVolumesMap;
1282 SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
1283 while( itVolumes->more( ) ) {
1284 int nbNodes = itVolumes->next()->NbNodes();
1285 if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() )
1286 myVolumesMap[ nbNodes ] = 0;
1287 myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1;
1289 save << "4.5.) Volumes in detail: " << endl;
1290 map <int,int>::iterator itV;
1291 for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++)
1292 save << "--> nb nodes: " << itV->first << " - nb elemens: " << itV->second << endl;
1295 save << "===========================================================================" << endl;