1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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, or (at your option) any later version.
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
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 // to pass CORBA exception through SMESH_TRY
83 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
85 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
88 static int MYDEBUG = 0;
90 static int MYDEBUG = 0;
94 using SMESH::TPythonDump;
96 int SMESH_Mesh_i::_idGenerator = 0;
98 //=============================================================================
102 //=============================================================================
104 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
106 CORBA::Long studyId )
107 : SALOME::GenericObj_i( thePOA )
109 MESSAGE("SMESH_Mesh_i");
112 _id = _idGenerator++;
115 _previewEditor = NULL;
120 //=============================================================================
124 //=============================================================================
126 SMESH_Mesh_i::~SMESH_Mesh_i()
128 MESSAGE("~SMESH_Mesh_i");
131 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
132 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
133 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
135 aGroup->UnRegister();
136 SMESH::SMESH_GroupBase_var( itGr->second );
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
143 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
145 aSubMesh->UnRegister();
146 SMESH::SMESH_subMesh_var( itSM->second );
148 _mapSubMeshIor.clear();
150 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
151 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
152 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
153 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
154 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
155 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
158 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
162 delete _editor; _editor = NULL;
163 delete _previewEditor; _previewEditor = NULL;
164 delete _impl; _impl = NULL;
165 delete _preMeshInfo; _preMeshInfo = NULL;
168 //=============================================================================
172 * Associates <this> mesh with <theShape> and puts a reference
173 * to <theShape> into the current study;
174 * the previous shape is substituted by the new one.
176 //=============================================================================
178 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
179 throw (SALOME::SALOME_Exception)
181 Unexpect aCatch(SALOME_SalomeException);
183 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
185 catch(SALOME_Exception & S_ex) {
186 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
188 // to track changes of GEOM groups
189 SMESH::SMESH_Mesh_var mesh = _this();
190 addGeomGroupData( theShapeObject, mesh );
191 if ( !CORBA::is_nil( theShapeObject ))
192 _mainShapeTick = theShapeObject->GetTick();
195 //================================================================================
197 * \brief return true if mesh has a shape to build a shape on
199 //================================================================================
201 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
202 throw (SALOME::SALOME_Exception)
204 Unexpect aCatch(SALOME_SalomeException);
207 res = _impl->HasShapeToMesh();
209 catch(SALOME_Exception & S_ex) {
210 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
215 //=======================================================================
216 //function : GetShapeToMesh
218 //=======================================================================
220 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
221 throw (SALOME::SALOME_Exception)
223 Unexpect aCatch(SALOME_SalomeException);
224 GEOM::GEOM_Object_var aShapeObj;
226 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
228 aShapeObj = _gen_i->ShapeToGeomObject( S );
230 catch(SALOME_Exception & S_ex) {
231 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
233 return aShapeObj._retn();
236 //================================================================================
238 * \brief Return false if the mesh is not yet fully loaded from the study file
240 //================================================================================
242 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
244 Unexpect aCatch(SALOME_SalomeException);
245 return !_preMeshInfo;
248 //================================================================================
250 * \brief Load full mesh data from the study file
252 //================================================================================
254 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
256 Unexpect aCatch(SALOME_SalomeException);
258 _preMeshInfo->FullLoadFromFile();
261 //================================================================================
263 * \brief Remove all nodes and elements
265 //================================================================================
267 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
269 Unexpect aCatch(SALOME_SalomeException);
271 _preMeshInfo->ForgetAllData();
275 //CheckGeomGroupModif(); // issue 20145
277 catch(SALOME_Exception & S_ex) {
278 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
280 _impl->GetMeshDS()->Modified();
282 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
285 //================================================================================
287 * \brief Remove all nodes and elements for indicated shape
289 //================================================================================
291 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
292 throw (SALOME::SALOME_Exception)
294 Unexpect aCatch(SALOME_SalomeException);
296 _preMeshInfo->FullLoadFromFile();
299 _impl->ClearSubMesh( ShapeID );
301 catch(SALOME_Exception & S_ex) {
302 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
304 _impl->GetMeshDS()->Modified();
306 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
309 //=============================================================================
311 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
313 //=============================================================================
315 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
317 SMESH::DriverMED_ReadStatus res;
320 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
321 res = SMESH::DRS_OK; break;
322 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
323 res = SMESH::DRS_EMPTY; break;
324 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
325 res = SMESH::DRS_WARN_RENUMBER; break;
326 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
327 res = SMESH::DRS_WARN_SKIP_ELEM; break;
328 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
329 res = SMESH::DRS_WARN_DESCENDING; break;
330 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
332 res = SMESH::DRS_FAIL; break;
337 //=============================================================================
339 * Convert ::SMESH_ComputeError to SMESH::ComputeError
341 //=============================================================================
343 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
345 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
346 errVar->subShapeID = -1;
347 errVar->hasBadMesh = false;
349 if ( !errorPtr || errorPtr->IsOK() )
351 errVar->code = SMESH::COMPERR_OK;
355 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
356 errVar->comment = errorPtr->myComment.c_str();
358 return errVar._retn();
361 //=============================================================================
365 * Imports mesh data from MED file
367 //=============================================================================
369 SMESH::DriverMED_ReadStatus
370 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
371 throw ( SALOME::SALOME_Exception )
373 Unexpect aCatch(SALOME_SalomeException);
376 status = _impl->MEDToMesh( theFileName, theMeshName );
378 catch( SALOME_Exception& S_ex ) {
379 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
382 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
385 CreateGroupServants();
387 int major, minor, release;
388 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
389 major = minor = release = -1;
390 _medFileInfo = new SMESH::MedFileInfo();
391 _medFileInfo->fileName = theFileName;
392 _medFileInfo->fileSize = 0;
393 _medFileInfo->major = major;
394 _medFileInfo->minor = minor;
395 _medFileInfo->release = release;
396 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
398 return ConvertDriverMEDReadStatus(status);
401 //================================================================================
403 * \brief Imports mesh data from the CGNS file
405 //================================================================================
407 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
408 const int theMeshIndex,
409 std::string& theMeshName )
410 throw ( SALOME::SALOME_Exception )
412 Unexpect aCatch(SALOME_SalomeException);
415 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
417 catch( SALOME_Exception& S_ex ) {
418 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
421 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
424 CreateGroupServants();
426 return ConvertDriverMEDReadStatus(status);
429 //================================================================================
431 * \brief Return string representation of a MED file version comprising nbDigits
433 //================================================================================
435 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
437 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
439 return CORBA::string_dup( ver.c_str() );
442 //=============================================================================
446 * Imports mesh data from MED file
448 //=============================================================================
450 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
451 throw ( SALOME::SALOME_Exception )
455 // Read mesh with name = <theMeshName> into SMESH_Mesh
456 _impl->UNVToMesh( theFileName );
458 CreateGroupServants();
460 SMESH_CATCH( SMESH::throwCorbaException );
465 //=============================================================================
469 * Imports mesh data from STL file
471 //=============================================================================
472 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
473 throw ( SALOME::SALOME_Exception )
477 // Read mesh with name = <theMeshName> into SMESH_Mesh
478 _impl->STLToMesh( theFileName );
480 SMESH_CATCH( SMESH::throwCorbaException );
485 //================================================================================
487 * \brief Function used in SMESH_CATCH by ImportGMFFile()
489 //================================================================================
493 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
495 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
499 //================================================================================
501 * \brief Imports data from a GMF file and returns an error description
503 //================================================================================
505 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
506 bool theMakeRequiredGroups )
507 throw (SALOME::SALOME_Exception)
509 SMESH_ComputeErrorPtr error;
512 #define SMESH_CAUGHT error =
515 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
517 SMESH_CATCH( exceptionToComputeError );
521 CreateGroupServants();
523 return ConvertComputeError( error );
526 //=============================================================================
530 //=============================================================================
532 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
534 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
535 (SMESH_Hypothesis::Hypothesis_Status theStatus)
538 RETURNCASE( HYP_OK );
539 RETURNCASE( HYP_MISSING );
540 RETURNCASE( HYP_CONCURENT );
541 RETURNCASE( HYP_BAD_PARAMETER );
542 RETURNCASE( HYP_HIDDEN_ALGO );
543 RETURNCASE( HYP_HIDING_ALGO );
544 RETURNCASE( HYP_UNKNOWN_FATAL );
545 RETURNCASE( HYP_INCOMPATIBLE );
546 RETURNCASE( HYP_NOTCONFORM );
547 RETURNCASE( HYP_ALREADY_EXIST );
548 RETURNCASE( HYP_BAD_DIM );
549 RETURNCASE( HYP_BAD_SUBSHAPE );
550 RETURNCASE( HYP_BAD_GEOMETRY );
551 RETURNCASE( HYP_NEED_SHAPE );
552 RETURNCASE( HYP_INCOMPAT_HYPS );
555 return SMESH::HYP_UNKNOWN_FATAL;
558 //=============================================================================
562 * calls internal addHypothesis() and then adds a reference to <anHyp> under
563 * the SObject actually having a reference to <aSubShape>.
564 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
566 //=============================================================================
568 SMESH::Hypothesis_Status
569 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
570 SMESH::SMESH_Hypothesis_ptr anHyp,
571 CORBA::String_out anErrorText)
572 throw(SALOME::SALOME_Exception)
574 Unexpect aCatch(SALOME_SalomeException);
576 _preMeshInfo->ForgetOrLoad();
579 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
580 anErrorText = error.c_str();
582 SMESH::SMESH_Mesh_var mesh( _this() );
583 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
585 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
586 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
588 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
590 // Update Python script
591 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
592 << aSubShape << ", " << anHyp << " )";
594 return ConvertHypothesisStatus(status);
597 //=============================================================================
601 //=============================================================================
603 SMESH_Hypothesis::Hypothesis_Status
604 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
605 SMESH::SMESH_Hypothesis_ptr anHyp,
606 std::string* anErrorText)
608 if(MYDEBUG) MESSAGE("addHypothesis");
610 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
611 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
613 if (CORBA::is_nil( anHyp ))
614 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
616 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
619 TopoDS_Shape myLocSubShape;
620 //use PseudoShape in case if mesh has no shape
622 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
624 myLocSubShape = _impl->GetShapeToMesh();
626 const int hypId = anHyp->GetId();
628 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
629 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
631 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
633 // assure there is a corresponding submesh
634 if ( !_impl->IsMainShape( myLocSubShape )) {
635 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
636 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
637 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
640 else if ( anErrorText )
642 *anErrorText = error;
645 catch(SALOME_Exception & S_ex)
647 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
652 //=============================================================================
656 //=============================================================================
658 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
659 SMESH::SMESH_Hypothesis_ptr anHyp)
660 throw(SALOME::SALOME_Exception)
662 Unexpect aCatch(SALOME_SalomeException);
664 _preMeshInfo->ForgetOrLoad();
666 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
667 SMESH::SMESH_Mesh_var mesh = _this();
669 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
671 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
672 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
674 // Update Python script
675 if(_impl->HasShapeToMesh())
676 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
677 << aSubShape << ", " << anHyp << " )";
679 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
682 return ConvertHypothesisStatus(status);
685 //=============================================================================
689 //=============================================================================
691 SMESH_Hypothesis::Hypothesis_Status
692 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
693 SMESH::SMESH_Hypothesis_ptr anHyp)
695 if(MYDEBUG) MESSAGE("removeHypothesis()");
697 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
698 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
700 if (CORBA::is_nil( anHyp ))
701 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
703 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
706 TopoDS_Shape myLocSubShape;
707 //use PseudoShape in case if mesh has no shape
708 if( _impl->HasShapeToMesh() )
709 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
711 myLocSubShape = _impl->GetShapeToMesh();
713 const int hypId = anHyp->GetId();
714 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
715 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
717 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
721 catch(SALOME_Exception & S_ex)
723 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
728 //=============================================================================
732 //=============================================================================
734 SMESH::ListOfHypothesis *
735 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
736 throw(SALOME::SALOME_Exception)
738 Unexpect aCatch(SALOME_SalomeException);
739 if (MYDEBUG) MESSAGE("GetHypothesisList");
740 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
741 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
743 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
746 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
747 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
748 myLocSubShape = _impl->GetShapeToMesh();
749 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
750 int i = 0, n = aLocalList.size();
753 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
754 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
755 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
757 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
758 if ( id_hypptr != _mapHypo.end() )
759 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
763 catch(SALOME_Exception & S_ex) {
764 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
767 return aList._retn();
770 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
772 Unexpect aCatch(SALOME_SalomeException);
773 if (MYDEBUG) MESSAGE("GetSubMeshes");
775 SMESH::submesh_array_var aList = new SMESH::submesh_array();
778 TPythonDump aPythonDump;
779 if ( !_mapSubMeshIor.empty() )
783 aList->length( _mapSubMeshIor.size() );
785 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
786 for ( ; it != _mapSubMeshIor.end(); it++ ) {
787 if ( CORBA::is_nil( it->second )) continue;
788 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
790 if (i > 1) aPythonDump << ", ";
791 aPythonDump << it->second;
795 catch(SALOME_Exception & S_ex) {
796 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
799 // Update Python script
800 if ( !_mapSubMeshIor.empty() )
801 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
803 return aList._retn();
806 //=============================================================================
810 //=============================================================================
812 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
813 const char* theName )
814 throw(SALOME::SALOME_Exception)
816 Unexpect aCatch(SALOME_SalomeException);
817 if (CORBA::is_nil(aSubShape))
818 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
820 SMESH::SMESH_subMesh_var subMesh;
821 SMESH::SMESH_Mesh_var aMesh = _this();
823 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
825 //Get or Create the SMESH_subMesh object implementation
827 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
829 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
831 TopoDS_Iterator it( myLocSubShape );
833 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
835 subMesh = getSubMesh( subMeshId );
837 // create a new subMesh object servant if there is none for the shape
838 if ( subMesh->_is_nil() )
839 subMesh = createSubMesh( aSubShape );
840 if ( _gen_i->CanPublishInStudy( subMesh ))
842 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
843 SALOMEDS::SObject_wrap aSO =
844 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
845 if ( !aSO->_is_nil()) {
846 // Update Python script
847 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
848 << aSubShape << ", '" << theName << "' )";
852 catch(SALOME_Exception & S_ex) {
853 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
855 return subMesh._retn();
858 //=============================================================================
862 //=============================================================================
864 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
865 throw (SALOME::SALOME_Exception)
869 if ( theSubMesh->_is_nil() )
872 GEOM::GEOM_Object_var aSubShape;
873 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
874 if ( !aStudy->_is_nil() ) {
875 // Remove submesh's SObject
876 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
877 if ( !anSO->_is_nil() ) {
878 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
879 SALOMEDS::SObject_wrap anObj, aRef;
880 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
881 anObj->ReferencedObject( aRef.inout() ))
883 CORBA::Object_var obj = aRef->GetObject();
884 aSubShape = GEOM::GEOM_Object::_narrow( obj );
886 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
887 // aSubShape = theSubMesh->GetSubShape();
889 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
890 builder->RemoveObjectWithChildren( anSO );
892 // Update Python script
893 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
897 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
899 _preMeshInfo->ForgetOrLoad();
901 SMESH_CATCH( SMESH::throwCorbaException );
904 //=============================================================================
908 //=============================================================================
910 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
911 const char* theName )
912 throw(SALOME::SALOME_Exception)
914 Unexpect aCatch(SALOME_SalomeException);
916 _preMeshInfo->FullLoadFromFile();
918 SMESH::SMESH_Group_var aNewGroup =
919 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
921 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
923 SMESH::SMESH_Mesh_var mesh = _this();
924 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
925 SALOMEDS::SObject_wrap aSO =
926 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
927 if ( !aSO->_is_nil())
928 // Update Python script
929 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
930 << theElemType << ", '" << theName << "' )";
932 return aNewGroup._retn();
935 //=============================================================================
939 //=============================================================================
940 SMESH::SMESH_GroupOnGeom_ptr
941 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
943 GEOM::GEOM_Object_ptr theGeomObj)
944 throw(SALOME::SALOME_Exception)
946 Unexpect aCatch(SALOME_SalomeException);
948 _preMeshInfo->FullLoadFromFile();
950 SMESH::SMESH_GroupOnGeom_var aNewGroup;
952 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
953 if ( !aShape.IsNull() )
956 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
958 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
960 SMESH::SMESH_Mesh_var mesh = _this();
961 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
962 SALOMEDS::SObject_wrap aSO =
963 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
964 if ( !aSO->_is_nil())
965 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
966 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
970 return aNewGroup._retn();
973 //================================================================================
975 * \brief Creates a group whose contents is defined by filter
976 * \param theElemType - group type
977 * \param theName - group name
978 * \param theFilter - the filter
979 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
981 //================================================================================
983 SMESH::SMESH_GroupOnFilter_ptr
984 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
986 SMESH::Filter_ptr theFilter )
987 throw (SALOME::SALOME_Exception)
989 Unexpect aCatch(SALOME_SalomeException);
991 _preMeshInfo->FullLoadFromFile();
993 if ( CORBA::is_nil( theFilter ))
994 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
996 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
998 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1000 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1001 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1004 if ( !aNewGroup->_is_nil() )
1005 aNewGroup->SetFilter( theFilter );
1007 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1009 SMESH::SMESH_Mesh_var mesh = _this();
1010 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1011 SALOMEDS::SObject_wrap aSO =
1012 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1014 if ( !aSO->_is_nil())
1015 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1016 << theElemType << ", '" << theName << "', " << theFilter << " )";
1018 return aNewGroup._retn();
1021 //=============================================================================
1025 //=============================================================================
1027 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1028 throw (SALOME::SALOME_Exception)
1030 if ( theGroup->_is_nil() )
1035 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1039 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1040 if ( !aStudy->_is_nil() )
1042 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1043 if ( !aGroupSO->_is_nil() )
1045 // Update Python script
1046 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1048 // Remove group's SObject
1049 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1050 builder->RemoveObjectWithChildren( aGroupSO );
1054 // Remove the group from SMESH data structures
1055 removeGroup( aGroup->GetLocalID() );
1057 SMESH_CATCH( SMESH::throwCorbaException );
1060 //=============================================================================
1062 * Remove group with its contents
1064 //=============================================================================
1066 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1067 throw (SALOME::SALOME_Exception)
1071 _preMeshInfo->FullLoadFromFile();
1073 if ( theGroup->_is_nil() )
1077 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1078 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1079 while ( elemIt->more() )
1080 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1082 TPythonDump pyDump; // Supress dump from RemoveGroup()
1084 // Update Python script (theGroup must be alive for this)
1085 pyDump << SMESH::SMESH_Mesh_var(_this())
1086 << ".RemoveGroupWithContents( " << theGroup << " )";
1089 RemoveGroup( theGroup );
1091 SMESH_CATCH( SMESH::throwCorbaException );
1094 //================================================================================
1096 * \brief Get the list of groups existing in the mesh
1097 * \retval SMESH::ListOfGroups * - list of groups
1099 //================================================================================
1101 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1103 Unexpect aCatch(SALOME_SalomeException);
1104 if (MYDEBUG) MESSAGE("GetGroups");
1106 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1109 TPythonDump aPythonDump;
1110 if ( !_mapGroups.empty() )
1112 aPythonDump << "[ ";
1114 aList->length( _mapGroups.size() );
1116 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1117 for ( ; it != _mapGroups.end(); it++ ) {
1118 if ( CORBA::is_nil( it->second )) continue;
1119 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1121 if (i > 1) aPythonDump << ", ";
1122 aPythonDump << it->second;
1126 catch(SALOME_Exception & S_ex) {
1127 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1129 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1131 return aList._retn();
1134 //=============================================================================
1136 * Get number of groups existing in the mesh
1138 //=============================================================================
1140 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1142 Unexpect aCatch(SALOME_SalomeException);
1143 return _mapGroups.size();
1146 //=============================================================================
1148 * New group including all mesh elements present in initial groups is created.
1150 //=============================================================================
1152 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1153 SMESH::SMESH_GroupBase_ptr theGroup2,
1154 const char* theName )
1155 throw (SALOME::SALOME_Exception)
1157 SMESH::SMESH_Group_var aResGrp;
1161 _preMeshInfo->FullLoadFromFile();
1163 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1164 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1166 if ( theGroup1->GetType() != theGroup2->GetType() )
1167 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1172 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1173 if ( aResGrp->_is_nil() )
1174 return SMESH::SMESH_Group::_nil();
1176 aResGrp->AddFrom( theGroup1 );
1177 aResGrp->AddFrom( theGroup2 );
1179 // Update Python script
1180 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1181 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1183 SMESH_CATCH( SMESH::throwCorbaException );
1185 return aResGrp._retn();
1188 //=============================================================================
1190 * \brief New group including all mesh elements present in initial groups is created.
1191 * \param theGroups list of groups
1192 * \param theName name of group to be created
1193 * \return pointer to the new group
1195 //=============================================================================
1197 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1198 const char* theName )
1199 throw (SALOME::SALOME_Exception)
1201 SMESH::SMESH_Group_var aResGrp;
1204 _preMeshInfo->FullLoadFromFile();
1207 return SMESH::SMESH_Group::_nil();
1212 SMESH::ElementType aType = SMESH::ALL;
1213 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1215 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1216 if ( CORBA::is_nil( aGrp ) )
1218 if ( aType == SMESH::ALL )
1219 aType = aGrp->GetType();
1220 else if ( aType != aGrp->GetType() )
1221 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1224 if ( aType == SMESH::ALL )
1225 return SMESH::SMESH_Group::_nil();
1230 aResGrp = CreateGroup( aType, theName );
1231 if ( aResGrp->_is_nil() )
1232 return SMESH::SMESH_Group::_nil();
1234 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1235 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1237 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1238 if ( !CORBA::is_nil( aGrp ) )
1240 aResGrp->AddFrom( aGrp );
1241 if ( g > 0 ) pyDump << ", ";
1245 pyDump << " ], '" << theName << "' )";
1247 SMESH_CATCH( SMESH::throwCorbaException );
1249 return aResGrp._retn();
1252 //=============================================================================
1254 * New group is created. All mesh elements that are
1255 * present in both initial groups are added to the new one.
1257 //=============================================================================
1259 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1260 SMESH::SMESH_GroupBase_ptr theGroup2,
1261 const char* theName )
1262 throw (SALOME::SALOME_Exception)
1264 SMESH::SMESH_Group_var aResGrp;
1269 _preMeshInfo->FullLoadFromFile();
1271 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1272 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1274 if ( theGroup1->GetType() != theGroup2->GetType() )
1275 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1279 // Create Intersection
1280 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1281 if ( aResGrp->_is_nil() )
1282 return aResGrp._retn();
1284 SMESHDS_GroupBase* groupDS1 = 0;
1285 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1286 groupDS1 = grp_i->GetGroupDS();
1288 SMESHDS_GroupBase* groupDS2 = 0;
1289 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1290 groupDS2 = grp_i->GetGroupDS();
1292 SMESHDS_Group* resGroupDS = 0;
1293 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1294 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1296 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1298 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1299 while ( elemIt1->more() )
1301 const SMDS_MeshElement* e = elemIt1->next();
1302 if ( groupDS2->Contains( e ))
1303 resGroupDS->SMDSGroup().Add( e );
1306 // Update Python script
1307 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1308 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1310 SMESH_CATCH( SMESH::throwCorbaException );
1312 return aResGrp._retn();
1315 //=============================================================================
1317 \brief Intersect list of groups. New group is created. All mesh elements that
1318 are present in all initial groups simultaneously are added to the new one.
1319 \param theGroups list of groups
1320 \param theName name of group to be created
1321 \return pointer on the group
1323 //=============================================================================
1324 SMESH::SMESH_Group_ptr
1325 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1326 const char* theName )
1327 throw (SALOME::SALOME_Exception)
1329 SMESH::SMESH_Group_var aResGrp;
1334 _preMeshInfo->FullLoadFromFile();
1337 return SMESH::SMESH_Group::_nil();
1339 // check types and get SMESHDS_GroupBase's
1340 SMESH::ElementType aType = SMESH::ALL;
1341 vector< SMESHDS_GroupBase* > groupVec;
1342 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1344 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1345 if ( CORBA::is_nil( aGrp ) )
1347 if ( aType == SMESH::ALL )
1348 aType = aGrp->GetType();
1349 else if ( aType != aGrp->GetType() )
1350 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1353 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1354 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1356 if ( grpDS->IsEmpty() )
1361 groupVec.push_back( grpDS );
1364 if ( aType == SMESH::ALL ) // all groups are nil
1365 return SMESH::SMESH_Group::_nil();
1370 aResGrp = CreateGroup( aType, theName );
1372 SMESHDS_Group* resGroupDS = 0;
1373 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1374 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1375 if ( !resGroupDS || groupVec.empty() )
1376 return aResGrp._retn();
1379 size_t i, nb = groupVec.size();
1380 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1381 while ( elemIt1->more() )
1383 const SMDS_MeshElement* e = elemIt1->next();
1385 for ( i = 1; ( i < nb && inAll ); ++i )
1386 inAll = groupVec[i]->Contains( e );
1389 resGroupDS->SMDSGroup().Add( e );
1392 // Update Python script
1393 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1394 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1396 SMESH_CATCH( SMESH::throwCorbaException );
1398 return aResGrp._retn();
1401 //=============================================================================
1403 * New group is created. All mesh elements that are present in
1404 * a main group but is not present in a tool group are added to the new one
1406 //=============================================================================
1408 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1409 SMESH::SMESH_GroupBase_ptr theGroup2,
1410 const char* theName )
1411 throw (SALOME::SALOME_Exception)
1413 SMESH::SMESH_Group_var aResGrp;
1418 _preMeshInfo->FullLoadFromFile();
1420 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1421 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1423 if ( theGroup1->GetType() != theGroup2->GetType() )
1424 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1428 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1429 if ( aResGrp->_is_nil() )
1430 return aResGrp._retn();
1432 SMESHDS_GroupBase* groupDS1 = 0;
1433 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1434 groupDS1 = grp_i->GetGroupDS();
1436 SMESHDS_GroupBase* groupDS2 = 0;
1437 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1438 groupDS2 = grp_i->GetGroupDS();
1440 SMESHDS_Group* resGroupDS = 0;
1441 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1442 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1444 if ( groupDS1 && groupDS2 && resGroupDS )
1446 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1447 while ( elemIt1->more() )
1449 const SMDS_MeshElement* e = elemIt1->next();
1450 if ( !groupDS2->Contains( e ))
1451 resGroupDS->SMDSGroup().Add( e );
1454 // Update Python script
1455 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1456 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1458 SMESH_CATCH( SMESH::throwCorbaException );
1460 return aResGrp._retn();
1463 //=============================================================================
1465 \brief Cut lists of groups. New group is created. All mesh elements that are
1466 present in main groups but do not present in tool groups are added to the new one
1467 \param theMainGroups list of main groups
1468 \param theToolGroups list of tool groups
1469 \param theName name of group to be created
1470 \return pointer on the group
1472 //=============================================================================
1473 SMESH::SMESH_Group_ptr
1474 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1475 const SMESH::ListOfGroups& theToolGroups,
1476 const char* theName )
1477 throw (SALOME::SALOME_Exception)
1479 SMESH::SMESH_Group_var aResGrp;
1484 _preMeshInfo->FullLoadFromFile();
1487 return SMESH::SMESH_Group::_nil();
1489 // check types and get SMESHDS_GroupBase's
1490 SMESH::ElementType aType = SMESH::ALL;
1491 vector< SMESHDS_GroupBase* > toolGroupVec;
1492 vector< SMDS_ElemIteratorPtr > mainIterVec;
1494 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1496 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1497 if ( CORBA::is_nil( aGrp ) )
1499 if ( aType == SMESH::ALL )
1500 aType = aGrp->GetType();
1501 else if ( aType != aGrp->GetType() )
1502 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1504 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1505 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1506 if ( !grpDS->IsEmpty() )
1507 mainIterVec.push_back( grpDS->GetElements() );
1509 if ( aType == SMESH::ALL ) // all main groups are nil
1510 return SMESH::SMESH_Group::_nil();
1511 if ( mainIterVec.empty() ) // all main groups are empty
1512 return aResGrp._retn();
1514 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1516 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1517 if ( CORBA::is_nil( aGrp ) )
1519 if ( aType != aGrp->GetType() )
1520 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1522 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1523 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1524 toolGroupVec.push_back( grpDS );
1530 aResGrp = CreateGroup( aType, theName );
1532 SMESHDS_Group* resGroupDS = 0;
1533 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1534 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1536 return aResGrp._retn();
1539 size_t i, nb = toolGroupVec.size();
1540 SMDS_ElemIteratorPtr mainElemIt
1541 ( new SMDS_IteratorOnIterators
1542 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1543 while ( mainElemIt->more() )
1545 const SMDS_MeshElement* e = mainElemIt->next();
1547 for ( i = 0; ( i < nb && !isIn ); ++i )
1548 isIn = toolGroupVec[i]->Contains( e );
1551 resGroupDS->SMDSGroup().Add( e );
1554 // Update Python script
1555 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1556 << ".CutListOfGroups( " << theMainGroups << ", "
1557 << theToolGroups << ", '" << theName << "' )";
1559 SMESH_CATCH( SMESH::throwCorbaException );
1561 return aResGrp._retn();
1564 //=============================================================================
1566 \brief Create groups of entities from existing groups of superior dimensions
1568 1) extract all nodes from each group,
1569 2) combine all elements of specified dimension laying on these nodes.
1570 \param theGroups list of source groups
1571 \param theElemType dimension of elements
1572 \param theName name of new group
1573 \return pointer on new group
1577 //=============================================================================
1579 SMESH::SMESH_Group_ptr
1580 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1581 SMESH::ElementType theElemType,
1582 const char* theName )
1583 throw (SALOME::SALOME_Exception)
1585 SMESH::SMESH_Group_var aResGrp;
1589 _preMeshInfo->FullLoadFromFile();
1591 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1593 if ( !theName || !aMeshDS )
1594 return SMESH::SMESH_Group::_nil();
1596 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1602 aResGrp = CreateGroup( theElemType, theName );
1603 if ( aResGrp->_is_nil() )
1604 return SMESH::SMESH_Group::_nil();
1606 SMESHDS_GroupBase* groupBaseDS =
1607 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1608 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1610 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1612 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1613 if ( CORBA::is_nil( aGrp ) )
1616 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1617 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1619 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1621 while ( elIt->more() ) {
1622 const SMDS_MeshElement* el = elIt->next();
1623 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1624 while ( nIt->more() )
1625 resGroupCore.Add( nIt->next() );
1628 else // get elements of theElemType based on nodes of every element of group
1630 while ( elIt->more() )
1632 const SMDS_MeshElement* el = elIt->next(); // an element of group
1633 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1634 TIDSortedElemSet checkedElems;
1635 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1636 while ( nIt->more() )
1638 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1639 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1640 // check nodes of elements of theElemType around el
1641 while ( elOfTypeIt->more() )
1643 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1644 if ( !checkedElems.insert( elOfType ).second ) continue;
1646 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1647 bool allNodesOK = true;
1648 while ( nIt2->more() && allNodesOK )
1649 allNodesOK = elNodes.count( nIt2->next() );
1651 resGroupCore.Add( elOfType );
1658 // Update Python script
1659 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1660 << ".CreateDimGroup( "
1661 << theGroups << ", " << theElemType << ", '" << theName << "' )";
1663 SMESH_CATCH( SMESH::throwCorbaException );
1665 return aResGrp._retn();
1668 //================================================================================
1670 * \brief Remember GEOM group data
1672 //================================================================================
1674 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1675 CORBA::Object_ptr theSmeshObj)
1677 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1680 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1681 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1682 if ( groupSO->_is_nil() )
1685 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1686 GEOM::GEOM_IGroupOperations_wrap groupOp =
1687 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1688 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1691 _geomGroupData.push_back( TGeomGroupData() );
1692 TGeomGroupData & groupData = _geomGroupData.back();
1694 CORBA::String_var entry = groupSO->GetID();
1695 groupData._groupEntry = entry.in();
1697 for ( int i = 0; i < ids->length(); ++i )
1698 groupData._indices.insert( ids[i] );
1700 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1701 // shape index in SMESHDS
1702 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1703 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1706 //================================================================================
1708 * Remove GEOM group data relating to removed smesh object
1710 //================================================================================
1712 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1714 list<TGeomGroupData>::iterator
1715 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1716 for ( ; data != dataEnd; ++data ) {
1717 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1718 _geomGroupData.erase( data );
1724 //================================================================================
1726 * \brief Return new group contents if it has been changed and update group data
1728 //================================================================================
1730 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1732 TopoDS_Shape newShape;
1735 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1736 if ( study->_is_nil() ) return newShape; // means "not changed"
1737 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1738 if ( !groupSO->_is_nil() )
1740 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1741 if ( CORBA::is_nil( groupObj )) return newShape;
1742 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1744 // get indices of group items
1745 set<int> curIndices;
1746 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1747 GEOM::GEOM_IGroupOperations_wrap groupOp =
1748 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1749 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1750 for ( int i = 0; i < ids->length(); ++i )
1751 curIndices.insert( ids[i] );
1753 if ( groupData._indices == curIndices )
1754 return newShape; // group not changed
1757 groupData._indices = curIndices;
1759 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1760 if ( !geomClient ) return newShape;
1761 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1762 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1763 newShape = _gen_i->GeomObjectToShape( geomGroup );
1766 if ( newShape.IsNull() ) {
1767 // geom group becomes empty - return empty compound
1768 TopoDS_Compound compound;
1769 BRep_Builder().MakeCompound(compound);
1770 newShape = compound;
1777 //-----------------------------------------------------------------------------
1779 * \brief Storage of shape and index used in CheckGeomGroupModif()
1781 struct TIndexedShape
1784 TopoDS_Shape _shape;
1785 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1787 //-----------------------------------------------------------------------------
1789 * \brief Data to re-create a group on geometry
1791 struct TGroupOnGeomData
1795 SMDSAbs_ElementType _type;
1797 Quantity_Color _color;
1801 //=============================================================================
1803 * \brief Update data if geometry changes
1807 //=============================================================================
1809 void SMESH_Mesh_i::CheckGeomModif()
1811 if ( !_impl->HasShapeToMesh() ) return;
1813 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1814 if ( study->_is_nil() ) return;
1816 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1817 if ( mainGO->_is_nil() ) return;
1819 if ( mainGO->GetType() == GEOM_GROUP ||
1820 mainGO->GetTick() == _mainShapeTick )
1822 CheckGeomGroupModif();
1826 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1827 if ( !geomClient ) return;
1828 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1829 if ( geomGen->_is_nil() ) return;
1831 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1832 geomClient->RemoveShapeFromBuffer( ior.in() );
1834 // Update data taking into account that
1835 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1838 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1839 if ( newShape.IsNull() )
1842 _mainShapeTick = mainGO->GetTick();
1844 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1846 // store data of groups on geometry
1847 vector< TGroupOnGeomData > groupsData;
1848 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1849 groupsData.reserve( groups.size() );
1850 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1851 for ( ; g != groups.end(); ++g )
1852 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1854 TGroupOnGeomData data;
1855 data._oldID = group->GetID();
1856 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1857 data._type = group->GetType();
1858 data._name = group->GetStoreName();
1859 data._color = group->GetColor();
1860 groupsData.push_back( data );
1862 // store assigned hypotheses
1863 vector< pair< int, THypList > > ids2Hyps;
1864 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
1865 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
1867 const TopoDS_Shape& s = s2hyps.Key();
1868 const THypList& hyps = s2hyps.ChangeValue();
1869 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
1872 // change shape to mesh
1873 int oldNbSubShapes = meshDS->MaxShapeIndex();
1874 _impl->ShapeToMesh( TopoDS_Shape() );
1875 _impl->ShapeToMesh( newShape );
1877 // re-add shapes of geom groups
1878 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
1879 for ( ; data != _geomGroupData.end(); ++data )
1881 TopoDS_Shape newShape = newGroupShape( *data );
1882 if ( !newShape.IsNull() )
1884 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
1886 TopoDS_Compound compound;
1887 BRep_Builder().MakeCompound( compound );
1888 BRep_Builder().Add( compound, newShape );
1889 newShape = compound;
1891 _impl->GetSubMesh( newShape );
1894 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
1895 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
1896 SALOME::INTERNAL_ERROR );
1898 // re-assign hypotheses
1899 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
1901 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
1902 const THypList& hyps = ids2Hyps[i].second;
1903 THypList::const_iterator h = hyps.begin();
1904 for ( ; h != hyps.end(); ++h )
1905 _impl->AddHypothesis( s, (*h)->GetID() );
1909 for ( size_t i = 0; i < groupsData.size(); ++i )
1911 const TGroupOnGeomData& data = groupsData[i];
1913 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
1914 if ( i2g == _mapGroups.end() ) continue;
1916 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
1917 if ( !gr_i ) continue;
1920 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
1921 meshDS->IndexToShape( data._shapeID ));
1924 _mapGroups.erase( i2g );
1928 g->GetGroupDS()->SetColor( data._color );
1929 gr_i->changeLocalId( id );
1930 _mapGroups[ id ] = i2g->second;
1931 if ( data._oldID != id )
1932 _mapGroups.erase( i2g );
1936 // update _mapSubMesh
1937 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
1938 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
1939 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
1943 //=============================================================================
1945 * \brief Update objects depending on changed geom groups
1947 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1948 * issue 0020210: Update of a smesh group after modification of the associated geom group
1950 //=============================================================================
1952 void SMESH_Mesh_i::CheckGeomGroupModif()
1954 if ( !_impl->HasShapeToMesh() ) return;
1956 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1957 if ( study->_is_nil() ) return;
1959 CORBA::Long nbEntities = NbNodes() + NbElements();
1961 // Check if group contents changed
1963 typedef map< string, TopoDS_Shape > TEntry2Geom;
1964 TEntry2Geom newGroupContents;
1966 list<TGeomGroupData>::iterator
1967 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1968 for ( ; data != dataEnd; ++data )
1970 pair< TEntry2Geom::iterator, bool > it_new =
1971 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1972 bool processedGroup = !it_new.second;
1973 TopoDS_Shape& newShape = it_new.first->second;
1974 if ( !processedGroup )
1975 newShape = newGroupShape( *data );
1976 if ( newShape.IsNull() )
1977 continue; // no changes
1980 _preMeshInfo->ForgetOrLoad();
1982 if ( processedGroup ) { // update group indices
1983 list<TGeomGroupData>::iterator data2 = data;
1984 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1985 data->_indices = data2->_indices;
1988 // Update SMESH objects according to new GEOM group contents
1990 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1991 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1993 int oldID = submesh->GetId();
1994 if ( !_mapSubMeshIor.count( oldID ))
1996 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1998 // update hypotheses
1999 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2000 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2001 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2003 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2004 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2006 // care of submeshes
2007 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2008 int newID = newSubmesh->GetId();
2009 if ( newID != oldID ) {
2010 _mapSubMesh [ newID ] = newSubmesh;
2011 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2012 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2013 _mapSubMesh. erase(oldID);
2014 _mapSubMesh_i. erase(oldID);
2015 _mapSubMeshIor.erase(oldID);
2016 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2021 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2022 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2023 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2025 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2027 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2028 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2029 ds->SetShape( newShape );
2034 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2035 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2037 // Remove groups and submeshes basing on removed sub-shapes
2039 TopTools_MapOfShape newShapeMap;
2040 TopoDS_Iterator shapeIt( newShape );
2041 for ( ; shapeIt.More(); shapeIt.Next() )
2042 newShapeMap.Add( shapeIt.Value() );
2044 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2045 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2047 if ( newShapeMap.Contains( shapeIt.Value() ))
2049 TopTools_IndexedMapOfShape oldShapeMap;
2050 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2051 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2053 const TopoDS_Shape& oldShape = oldShapeMap(i);
2054 int oldInd = meshDS->ShapeToIndex( oldShape );
2056 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2057 if ( i_smIor != _mapSubMeshIor.end() ) {
2058 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2061 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2062 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2064 // check if a group bases on oldInd shape
2065 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2066 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2067 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2068 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2070 RemoveGroup( i_grp->second ); // several groups can base on same shape
2071 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2076 // Reassign hypotheses and update groups after setting the new shape to mesh
2078 // collect anassigned hypotheses
2079 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2080 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2081 TShapeHypList assignedHyps;
2082 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2084 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2085 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2086 if ( !hyps.empty() ) {
2087 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2088 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2089 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2092 // collect shapes supporting groups
2093 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2094 TShapeTypeList groupData;
2095 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2096 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2097 for ( ; grIt != groups.end(); ++grIt )
2099 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2101 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2103 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2104 _impl->ShapeToMesh( newShape );
2106 // reassign hypotheses
2107 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2108 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2110 TIndexedShape& geom = indS_hyps->first;
2111 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2112 int oldID = geom._index;
2113 int newID = meshDS->ShapeToIndex( geom._shape );
2114 if ( oldID == 1 ) { // main shape
2116 geom._shape = newShape;
2120 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2121 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2122 // care of submeshes
2123 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2124 if ( newID != oldID ) {
2125 _mapSubMesh [ newID ] = newSubmesh;
2126 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2127 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2128 _mapSubMesh. erase(oldID);
2129 _mapSubMesh_i. erase(oldID);
2130 _mapSubMeshIor.erase(oldID);
2131 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2135 TShapeTypeList::iterator geomType = groupData.begin();
2136 for ( ; geomType != groupData.end(); ++geomType )
2138 const TIndexedShape& geom = geomType->first;
2139 int oldID = geom._index;
2140 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2143 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2144 CORBA::String_var name = groupSO->GetName();
2146 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2148 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2149 group_i->changeLocalId( newID );
2152 break; // everything has been updated
2155 } // loop on group data
2159 CORBA::Long newNbEntities = NbNodes() + NbElements();
2160 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2161 if ( newNbEntities != nbEntities )
2163 // Add all SObjects with icons to soToUpdateIcons
2164 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2166 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2167 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2168 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2170 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2171 i_gr != _mapGroups.end(); ++i_gr ) // groups
2172 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2175 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2176 for ( ; so != soToUpdateIcons.end(); ++so )
2177 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2180 //=============================================================================
2182 * \brief Create standalone group from a group on geometry or filter
2184 //=============================================================================
2186 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2187 throw (SALOME::SALOME_Exception)
2189 SMESH::SMESH_Group_var aGroup;
2194 _preMeshInfo->FullLoadFromFile();
2196 if ( theGroup->_is_nil() )
2197 return aGroup._retn();
2199 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2201 return aGroup._retn();
2203 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2205 const int anId = aGroupToRem->GetLocalID();
2206 if ( !_impl->ConvertToStandalone( anId ) )
2207 return aGroup._retn();
2208 removeGeomGroupData( theGroup );
2210 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2212 // remove old instance of group from own map
2213 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2214 _mapGroups.erase( anId );
2216 SALOMEDS::StudyBuilder_var builder;
2217 SALOMEDS::SObject_wrap aGroupSO;
2218 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2219 if ( !aStudy->_is_nil() ) {
2220 builder = aStudy->NewBuilder();
2221 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2222 if ( !aGroupSO->_is_nil() )
2224 // remove reference to geometry
2225 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2226 for ( ; chItr->More(); chItr->Next() )
2227 // Remove group's child SObject
2228 builder->RemoveObject( chItr->Value() );
2230 // Update Python script
2231 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2232 << ".ConvertToStandalone( " << aGroupSO << " )";
2234 // change icon of Group on Filter
2237 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2238 const int isEmpty = ( elemTypes->length() == 0 );
2241 SALOMEDS::GenericAttribute_wrap anAttr =
2242 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2243 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2244 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2250 // remember new group in own map
2251 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2252 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2254 // register CORBA object for persistence
2255 _gen_i->RegisterObject( aGroup );
2257 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2258 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2259 //aGroup->Register();
2260 aGroupToRem->UnRegister();
2262 SMESH_CATCH( SMESH::throwCorbaException );
2264 return aGroup._retn();
2267 //=============================================================================
2271 //=============================================================================
2273 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2275 if(MYDEBUG) MESSAGE( "createSubMesh" );
2276 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2277 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2278 const int subMeshId = mySubMesh->GetId();
2280 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2281 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2283 _mapSubMesh [subMeshId] = mySubMesh;
2284 _mapSubMesh_i [subMeshId] = subMeshServant;
2285 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2287 subMeshServant->Register();
2289 // register CORBA object for persistence
2290 int nextId = _gen_i->RegisterObject( subMesh );
2291 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2292 else { nextId = 0; } // avoid "unused variable" warning
2294 // to track changes of GEOM groups
2295 addGeomGroupData( theSubShapeObject, subMesh );
2297 return subMesh._retn();
2300 //=======================================================================
2301 //function : getSubMesh
2303 //=======================================================================
2305 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2307 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2308 if ( it == _mapSubMeshIor.end() )
2309 return SMESH::SMESH_subMesh::_nil();
2311 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2314 //=============================================================================
2318 //=============================================================================
2320 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2321 GEOM::GEOM_Object_ptr theSubShapeObject )
2323 bool isHypChanged = false;
2324 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2325 return isHypChanged;
2327 const int subMeshId = theSubMesh->GetId();
2329 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2331 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2333 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2336 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2337 isHypChanged = !hyps.empty();
2338 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2339 for ( ; hyp != hyps.end(); ++hyp )
2340 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2347 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2348 isHypChanged = ( aHypList->length() > 0 );
2349 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2350 removeHypothesis( theSubShapeObject, aHypList[i] );
2353 catch( const SALOME::SALOME_Exception& ) {
2354 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2356 removeGeomGroupData( theSubShapeObject );
2360 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2361 if ( id_smi != _mapSubMesh_i.end() )
2362 id_smi->second->UnRegister();
2364 // remove a CORBA object
2365 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2366 if ( id_smptr != _mapSubMeshIor.end() )
2367 SMESH::SMESH_subMesh_var( id_smptr->second );
2369 _mapSubMesh.erase(subMeshId);
2370 _mapSubMesh_i.erase(subMeshId);
2371 _mapSubMeshIor.erase(subMeshId);
2373 return isHypChanged;
2376 //=============================================================================
2380 //=============================================================================
2382 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2383 const char* theName,
2384 const TopoDS_Shape& theShape,
2385 const SMESH_PredicatePtr& thePredicate )
2387 std::string newName;
2388 if ( !theName || strlen( theName ) == 0 )
2390 std::set< std::string > presentNames;
2391 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2392 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2394 CORBA::String_var name = i_gr->second->GetName();
2395 presentNames.insert( name.in() );
2398 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2399 } while ( !presentNames.insert( newName ).second );
2400 theName = newName.c_str();
2403 SMESH::SMESH_GroupBase_var aGroup;
2404 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2406 SMESH_GroupBase_i* aGroupImpl;
2407 if ( !theShape.IsNull() )
2408 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2409 else if ( thePredicate )
2410 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2412 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2414 aGroup = aGroupImpl->_this();
2415 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2416 aGroupImpl->Register();
2418 // register CORBA object for persistence
2419 int nextId = _gen_i->RegisterObject( aGroup );
2420 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2421 else { nextId = 0; } // avoid "unused variable" warning in release mode
2423 // to track changes of GEOM groups
2424 if ( !theShape.IsNull() ) {
2425 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2426 addGeomGroupData( geom, aGroup );
2429 return aGroup._retn();
2432 //=============================================================================
2434 * SMESH_Mesh_i::removeGroup
2436 * Should be called by ~SMESH_Group_i()
2438 //=============================================================================
2440 void SMESH_Mesh_i::removeGroup( const int theId )
2442 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2443 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2444 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2445 _mapGroups.erase( theId );
2446 removeGeomGroupData( group );
2447 if ( !_impl->RemoveGroup( theId ))
2449 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2450 RemoveGroup( group );
2452 group->UnRegister();
2456 //=============================================================================
2460 //=============================================================================
2462 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2463 throw(SALOME::SALOME_Exception)
2465 SMESH::log_array_var aLog;
2469 _preMeshInfo->FullLoadFromFile();
2471 list < SMESHDS_Command * >logDS = _impl->GetLog();
2472 aLog = new SMESH::log_array;
2474 int lg = logDS.size();
2477 list < SMESHDS_Command * >::iterator its = logDS.begin();
2478 while(its != logDS.end()){
2479 SMESHDS_Command *com = *its;
2480 int comType = com->GetType();
2482 int lgcom = com->GetNumber();
2484 const list < int >&intList = com->GetIndexes();
2485 int inum = intList.size();
2487 list < int >::const_iterator ii = intList.begin();
2488 const list < double >&coordList = com->GetCoords();
2489 int rnum = coordList.size();
2491 list < double >::const_iterator ir = coordList.begin();
2492 aLog[indexLog].commandType = comType;
2493 aLog[indexLog].number = lgcom;
2494 aLog[indexLog].coords.length(rnum);
2495 aLog[indexLog].indexes.length(inum);
2496 for(int i = 0; i < rnum; i++){
2497 aLog[indexLog].coords[i] = *ir;
2498 //MESSAGE(" "<<i<<" "<<ir.Value());
2501 for(int i = 0; i < inum; i++){
2502 aLog[indexLog].indexes[i] = *ii;
2503 //MESSAGE(" "<<i<<" "<<ii.Value());
2512 SMESH_CATCH( SMESH::throwCorbaException );
2514 return aLog._retn();
2518 //=============================================================================
2522 //=============================================================================
2524 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2528 SMESH_CATCH( SMESH::throwCorbaException );
2531 //=============================================================================
2535 //=============================================================================
2537 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2542 //=============================================================================
2546 //=============================================================================
2548 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2553 //=============================================================================
2556 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2557 // issue 0020918: groups removal is caused by hyp modification
2558 // issue 0021208: to forget not loaded mesh data at hyp modification
2559 struct TCallUp_i : public SMESH_Mesh::TCallUp
2561 SMESH_Mesh_i* _mesh;
2562 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2563 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2564 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2565 virtual void Load () { _mesh->Load(); }
2569 //================================================================================
2571 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2573 //================================================================================
2575 void SMESH_Mesh_i::onHypothesisModified()
2578 _preMeshInfo->ForgetOrLoad();
2581 //=============================================================================
2585 //=============================================================================
2587 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2589 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2592 _impl->SetCallUp( new TCallUp_i(this));
2595 //=============================================================================
2599 //=============================================================================
2601 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2603 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2607 //=============================================================================
2609 * Return mesh editor
2611 //=============================================================================
2613 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2614 throw (SALOME::SALOME_Exception)
2616 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2620 _preMeshInfo->FullLoadFromFile();
2622 // Create MeshEditor
2624 _editor = new SMESH_MeshEditor_i( this, false );
2625 aMeshEdVar = _editor->_this();
2627 // Update Python script
2628 TPythonDump() << _editor << " = "
2629 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2631 SMESH_CATCH( SMESH::throwCorbaException );
2633 return aMeshEdVar._retn();
2636 //=============================================================================
2638 * Return mesh edition previewer
2640 //=============================================================================
2642 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2643 throw (SALOME::SALOME_Exception)
2645 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2649 _preMeshInfo->FullLoadFromFile();
2651 if ( !_previewEditor )
2652 _previewEditor = new SMESH_MeshEditor_i( this, true );
2653 aMeshEdVar = _previewEditor->_this();
2655 SMESH_CATCH( SMESH::throwCorbaException );
2657 return aMeshEdVar._retn();
2660 //================================================================================
2662 * \brief Return true if the mesh has been edited since a last total re-compute
2663 * and those modifications may prevent successful partial re-compute
2665 //================================================================================
2667 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2669 Unexpect aCatch(SALOME_SalomeException);
2670 return _impl->HasModificationsToDiscard();
2673 //================================================================================
2675 * \brief Returns a random unique color
2677 //================================================================================
2679 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2681 const int MAX_ATTEMPTS = 100;
2683 double tolerance = 0.5;
2684 SALOMEDS::Color col;
2688 // generate random color
2689 double red = (double)rand() / RAND_MAX;
2690 double green = (double)rand() / RAND_MAX;
2691 double blue = (double)rand() / RAND_MAX;
2692 // check existence in the list of the existing colors
2693 bool matched = false;
2694 std::list<SALOMEDS::Color>::const_iterator it;
2695 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2696 SALOMEDS::Color color = *it;
2697 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2698 matched = tol < tolerance;
2700 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2701 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2709 //=============================================================================
2711 * Sets auto-color mode. If it is on, groups get unique random colors
2713 //=============================================================================
2715 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2717 Unexpect aCatch(SALOME_SalomeException);
2718 _impl->SetAutoColor(theAutoColor);
2720 TPythonDump pyDump; // not to dump group->SetColor() from below code
2721 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2723 std::list<SALOMEDS::Color> aReservedColors;
2724 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2725 for ( ; it != _mapGroups.end(); it++ ) {
2726 if ( CORBA::is_nil( it->second )) continue;
2727 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2728 it->second->SetColor( aColor );
2729 aReservedColors.push_back( aColor );
2733 //=============================================================================
2735 * Returns true if auto-color mode is on
2737 //=============================================================================
2739 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2741 Unexpect aCatch(SALOME_SalomeException);
2742 return _impl->GetAutoColor();
2745 //=============================================================================
2747 * Checks if there are groups with equal names
2749 //=============================================================================
2751 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2753 return _impl->HasDuplicatedGroupNamesMED();
2756 //================================================================================
2758 * \brief Care of a file before exporting mesh into it
2760 //================================================================================
2762 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2764 SMESH_File aFile( file );
2766 if (aFile.exists()) {
2767 // existing filesystem node
2768 if ( !aFile.isDirectory() ) {
2769 if ( aFile.openForWriting() ) {
2770 if ( overwrite && ! aFile.remove()) {
2771 msg << "Can't replace " << aFile.getName();
2774 msg << "Can't write into " << aFile.getName();
2777 msg << "Location " << aFile.getName() << " is not a file";
2781 // nonexisting file; check if it can be created
2782 if ( !aFile.openForWriting() ) {
2783 msg << "You cannot create the file "
2785 << ". Check the directory existance and access rights";
2793 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2797 //================================================================================
2799 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2800 * \param file - file name
2801 * \param overwrite - to erase the file or not
2802 * \retval string - mesh name
2804 //================================================================================
2806 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2807 CORBA::Boolean overwrite)
2810 PrepareForWriting(file, overwrite);
2811 string aMeshName = "Mesh";
2812 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2813 if ( !aStudy->_is_nil() ) {
2814 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2815 if ( !aMeshSO->_is_nil() ) {
2816 CORBA::String_var name = aMeshSO->GetName();
2818 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2819 if ( !aStudy->GetProperties()->IsLocked() )
2821 SALOMEDS::GenericAttribute_wrap anAttr;
2822 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2823 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2824 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2825 ASSERT(!aFileName->_is_nil());
2826 aFileName->SetValue(file);
2827 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2828 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2829 ASSERT(!aFileType->_is_nil());
2830 aFileType->SetValue("FICHIERMED");
2834 // Update Python script
2835 // set name of mesh before export
2836 TPythonDump() << _gen_i << ".SetName("
2837 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2839 // check names of groups
2845 //================================================================================
2847 * \brief Export to med file
2849 //================================================================================
2851 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2852 CORBA::Boolean auto_groups,
2853 SMESH::MED_VERSION theVersion,
2854 CORBA::Boolean overwrite,
2855 CORBA::Boolean autoDimension)
2856 throw(SALOME::SALOME_Exception)
2860 _preMeshInfo->FullLoadFromFile();
2862 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2863 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2865 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2866 << file << "', " << auto_groups << ", "
2867 << theVersion << ", " << overwrite << ", "
2868 << autoDimension << " )";
2870 SMESH_CATCH( SMESH::throwCorbaException );
2873 //================================================================================
2875 * \brief Export a mesh to a med file
2877 //================================================================================
2879 void SMESH_Mesh_i::ExportToMED (const char* file,
2880 CORBA::Boolean auto_groups,
2881 SMESH::MED_VERSION theVersion)
2882 throw(SALOME::SALOME_Exception)
2884 ExportToMEDX(file,auto_groups,theVersion,true);
2887 //================================================================================
2889 * \brief Export a mesh to a med file
2891 //================================================================================
2893 void SMESH_Mesh_i::ExportMED (const char* file,
2894 CORBA::Boolean auto_groups)
2895 throw(SALOME::SALOME_Exception)
2897 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2900 //================================================================================
2902 * \brief Export a mesh to a SAUV file
2904 //================================================================================
2906 void SMESH_Mesh_i::ExportSAUV (const char* file,
2907 CORBA::Boolean auto_groups)
2908 throw(SALOME::SALOME_Exception)
2910 Unexpect aCatch(SALOME_SalomeException);
2912 _preMeshInfo->FullLoadFromFile();
2914 string aMeshName = prepareMeshNameAndGroups(file, true);
2915 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2916 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2917 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2921 //================================================================================
2923 * \brief Export a mesh to a DAT file
2925 //================================================================================
2927 void SMESH_Mesh_i::ExportDAT (const char *file)
2928 throw(SALOME::SALOME_Exception)
2930 Unexpect aCatch(SALOME_SalomeException);
2932 _preMeshInfo->FullLoadFromFile();
2934 // Update Python script
2935 // check names of groups
2937 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2940 PrepareForWriting(file);
2941 _impl->ExportDAT(file);
2944 //================================================================================
2946 * \brief Export a mesh to an UNV file
2948 //================================================================================
2950 void SMESH_Mesh_i::ExportUNV (const char *file)
2951 throw(SALOME::SALOME_Exception)
2953 Unexpect aCatch(SALOME_SalomeException);
2955 _preMeshInfo->FullLoadFromFile();
2957 // Update Python script
2958 // check names of groups
2960 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2963 PrepareForWriting(file);
2964 _impl->ExportUNV(file);
2967 //================================================================================
2969 * \brief Export a mesh to an STL file
2971 //================================================================================
2973 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2974 throw(SALOME::SALOME_Exception)
2976 Unexpect aCatch(SALOME_SalomeException);
2978 _preMeshInfo->FullLoadFromFile();
2980 // Update Python script
2981 // check names of groups
2983 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2984 << ".ExportSTL( r'" << file << "', " << isascii << " )";
2987 PrepareForWriting(file);
2988 _impl->ExportSTL(file, isascii);
2991 //================================================================================
2993 * \brief Export a part of mesh to a med file
2995 //================================================================================
2997 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
2999 CORBA::Boolean auto_groups,
3000 SMESH::MED_VERSION version,
3001 CORBA::Boolean overwrite,
3002 CORBA::Boolean autoDimension,
3003 const GEOM::ListOfFields& fields,
3004 const char* geomAssocFields)
3005 throw (SALOME::SALOME_Exception)
3009 _preMeshInfo->FullLoadFromFile();
3012 bool have0dField = false;
3013 if ( fields.length() > 0 )
3015 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3016 if ( shapeToMesh->_is_nil() )
3017 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3019 for ( size_t i = 0; i < fields.length(); ++i )
3021 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3022 THROW_SALOME_CORBA_EXCEPTION
3023 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3024 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3025 if ( fieldShape->_is_nil() )
3026 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3027 if ( !fieldShape->IsSame( shapeToMesh ) )
3028 THROW_SALOME_CORBA_EXCEPTION
3029 ( "Field defined not on shape", SALOME::BAD_PARAM);
3030 if ( fields[i]->GetDimension() == 0 )
3033 if ( geomAssocFields )
3034 for ( int i = 0; geomAssocFields[i]; ++i )
3035 switch ( geomAssocFields[i] ) {
3036 case 'v':case 'e':case 'f':case 's': break;
3037 case 'V':case 'E':case 'F':case 'S': break;
3038 default: THROW_SALOME_CORBA_EXCEPTION
3039 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3043 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3047 string aMeshName = "Mesh";
3048 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3049 if ( CORBA::is_nil( meshPart ) ||
3050 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3052 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3053 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3054 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3055 meshDS = _impl->GetMeshDS();
3060 _preMeshInfo->FullLoadFromFile();
3062 PrepareForWriting(file, overwrite);
3064 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3065 if ( !aStudy->_is_nil() ) {
3066 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3067 if ( !SO->_is_nil() ) {
3068 CORBA::String_var name = SO->GetName();
3072 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3073 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3074 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3075 meshDS = tmpDSDeleter._obj = partDS;
3080 if ( _impl->HasShapeToMesh() )
3082 DriverMED_W_Field fieldWriter;
3083 fieldWriter.SetFile( file );
3084 fieldWriter.SetMeshName( aMeshName );
3085 fieldWriter.AddODOnVertices( have0dField );
3087 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3091 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3092 goList->length( fields.length() );
3093 for ( size_t i = 0; i < fields.length(); ++i )
3095 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3098 TPythonDump() << _this() << ".ExportPartToMED( "
3099 << meshPart << ", r'" << file << "', "
3100 << auto_groups << ", " << version << ", " << overwrite << ", "
3101 << autoDimension << ", " << goList
3102 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3104 SMESH_CATCH( SMESH::throwCorbaException );
3107 //================================================================================
3109 * Write GEOM fields to MED file
3111 //================================================================================
3113 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3114 SMESHDS_Mesh* meshDS,
3115 const GEOM::ListOfFields& fields,
3116 const char* geomAssocFields)
3118 #define METH "SMESH_Mesh_i::exportMEDFields() "
3120 if (( fields.length() < 1 ) &&
3121 ( !geomAssocFields || !geomAssocFields[0] ))
3124 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3125 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3126 std::vector< int > subIdsByDim[ 4 ];
3127 const double noneDblValue = 0.;
3128 const double noneIntValue = 0;
3130 for ( size_t iF = 0; iF < fields.length(); ++iF )
3134 int dim = fields[ iF ]->GetDimension();
3135 SMDSAbs_ElementType elemType;
3136 TopAbs_ShapeEnum shapeType;
3138 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3139 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3140 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3141 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3143 continue; // skip fields on whole shape
3145 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3146 if ( dataType == GEOM::FDT_String )
3148 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3149 if ( stepIDs->length() < 1 )
3151 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3152 if ( comps->length() < 1 )
3154 CORBA::String_var name = fields[ iF ]->GetName();
3156 if ( !fieldWriter.Set( meshDS,
3160 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3163 for ( size_t iC = 0; iC < comps->length(); ++iC )
3164 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3166 // find sub-shape IDs
3168 std::vector< int >& subIds = subIdsByDim[ dim ];
3169 if ( subIds.empty() )
3170 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3171 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3172 subIds.push_back( id );
3176 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3180 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3182 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3183 if ( step->_is_nil() )
3186 CORBA::Long stamp = step->GetStamp();
3187 CORBA::Long id = step->GetID();
3188 fieldWriter.SetDtIt( int( stamp ), int( id ));
3190 // fill dblVals or intVals
3193 case GEOM::FDT_Double:
3195 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3196 if ( dblStep->_is_nil() ) continue;
3197 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3198 if ( vv->length() != subIds.size() )
3199 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3200 for ( size_t i = 0; i < vv->length(); ++i )
3201 dblVals[ subIds[ i ]] = vv[ i ];
3206 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3207 if ( intStep->_is_nil() ) continue;
3208 GEOM::ListOfLong_var vv = intStep->GetValues();
3209 if ( vv->length() != subIds.size() )
3210 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3211 for ( size_t i = 0; i < vv->length(); ++i )
3212 intVals[ subIds[ i ]] = (int) vv[ i ];
3215 case GEOM::FDT_Bool:
3217 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3218 if ( boolStep->_is_nil() ) continue;
3219 GEOM::short_array_var vv = boolStep->GetValues();
3220 if ( vv->length() != subIds.size() )
3221 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3222 for ( size_t i = 0; i < vv->length(); ++i )
3223 intVals[ subIds[ i ]] = (int) vv[ i ];
3229 // pass values to fieldWriter
3230 elemIt = fieldWriter.GetOrderedElems();
3231 if ( dataType == GEOM::FDT_Double )
3232 while ( elemIt->more() )
3234 const SMDS_MeshElement* e = elemIt->next();
3235 const int shapeID = e->getshapeId();
3236 if ( shapeID < 1 || shapeID >= dblVals.size() )
3237 fieldWriter.AddValue( noneDblValue );
3239 fieldWriter.AddValue( dblVals[ shapeID ]);
3242 while ( elemIt->more() )
3244 const SMDS_MeshElement* e = elemIt->next();
3245 const int shapeID = e->getshapeId();
3246 if ( shapeID < 1 || shapeID >= intVals.size() )
3247 fieldWriter.AddValue( (double) noneIntValue );
3249 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3253 fieldWriter.Perform();
3254 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3255 if ( res && res->IsKO() )
3257 if ( res->myComment.empty() )
3258 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3260 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3266 if ( !geomAssocFields || !geomAssocFields[0] )
3269 // write geomAssocFields
3271 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3272 shapeDim[ TopAbs_COMPOUND ] = 3;
3273 shapeDim[ TopAbs_COMPSOLID ] = 3;
3274 shapeDim[ TopAbs_SOLID ] = 3;
3275 shapeDim[ TopAbs_SHELL ] = 2;
3276 shapeDim[ TopAbs_FACE ] = 2;
3277 shapeDim[ TopAbs_WIRE ] = 1;
3278 shapeDim[ TopAbs_EDGE ] = 1;
3279 shapeDim[ TopAbs_VERTEX ] = 0;
3280 shapeDim[ TopAbs_SHAPE ] = 3;
3282 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3284 std::vector< std::string > compNames;
3285 switch ( geomAssocFields[ iF ]) {
3287 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3288 compNames.push_back( "dim" );
3291 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3294 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3297 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3301 compNames.push_back( "id" );
3302 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3303 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3305 fieldWriter.SetDtIt( -1, -1 );
3307 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3311 if ( compNames.size() == 2 ) // _vertices_
3312 while ( elemIt->more() )
3314 const SMDS_MeshElement* e = elemIt->next();
3315 const int shapeID = e->getshapeId();
3318 fieldWriter.AddValue( (double) -1 );
3319 fieldWriter.AddValue( (double) -1 );
3323 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3324 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3325 fieldWriter.AddValue( (double) shapeID );
3329 while ( elemIt->more() )
3331 const SMDS_MeshElement* e = elemIt->next();
3332 const int shapeID = e->getshapeId();
3334 fieldWriter.AddValue( (double) -1 );
3336 fieldWriter.AddValue( (double) shapeID );
3340 fieldWriter.Perform();
3341 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3342 if ( res && res->IsKO() )
3344 if ( res->myComment.empty() )
3345 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3347 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3350 } // loop on geomAssocFields
3355 //================================================================================
3357 * \brief Export a part of mesh to a DAT file
3359 //================================================================================
3361 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3363 throw (SALOME::SALOME_Exception)
3365 Unexpect aCatch(SALOME_SalomeException);
3367 _preMeshInfo->FullLoadFromFile();
3369 PrepareForWriting(file);
3371 SMESH_MeshPartDS partDS( meshPart );
3372 _impl->ExportDAT(file,&partDS);
3374 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3375 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3377 //================================================================================
3379 * \brief Export a part of mesh to an UNV file
3381 //================================================================================
3383 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3385 throw (SALOME::SALOME_Exception)
3387 Unexpect aCatch(SALOME_SalomeException);
3389 _preMeshInfo->FullLoadFromFile();
3391 PrepareForWriting(file);
3393 SMESH_MeshPartDS partDS( meshPart );
3394 _impl->ExportUNV(file, &partDS);
3396 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3397 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3399 //================================================================================
3401 * \brief Export a part of mesh to an STL file
3403 //================================================================================
3405 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3407 ::CORBA::Boolean isascii)
3408 throw (SALOME::SALOME_Exception)
3410 Unexpect aCatch(SALOME_SalomeException);
3412 _preMeshInfo->FullLoadFromFile();
3414 PrepareForWriting(file);
3416 SMESH_MeshPartDS partDS( meshPart );
3417 _impl->ExportSTL(file, isascii, &partDS);
3419 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3420 << meshPart<< ", r'" << file << "', " << isascii << ")";
3423 //================================================================================
3425 * \brief Export a part of mesh to an STL file
3427 //================================================================================
3429 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3431 CORBA::Boolean overwrite)
3432 throw (SALOME::SALOME_Exception)
3435 Unexpect aCatch(SALOME_SalomeException);
3437 _preMeshInfo->FullLoadFromFile();
3439 PrepareForWriting(file,overwrite);
3441 SMESH_MeshPartDS partDS( meshPart );
3442 _impl->ExportCGNS(file, &partDS);
3444 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3445 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3447 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3451 //================================================================================
3453 * \brief Export a part of mesh to a GMF file
3455 //================================================================================
3457 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3459 bool withRequiredGroups)
3460 throw (SALOME::SALOME_Exception)
3462 Unexpect aCatch(SALOME_SalomeException);
3464 _preMeshInfo->FullLoadFromFile();
3466 PrepareForWriting(file,/*overwrite=*/true);
3468 SMESH_MeshPartDS partDS( meshPart );
3469 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3471 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3472 << meshPart<< ", r'"
3474 << withRequiredGroups << ")";
3477 //=============================================================================
3479 * Return computation progress [0.,1]
3481 //=============================================================================
3483 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3487 return _impl->GetComputeProgress();
3489 SMESH_CATCH( SMESH::doNothing );
3493 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3495 Unexpect aCatch(SALOME_SalomeException);
3497 return _preMeshInfo->NbNodes();
3499 return _impl->NbNodes();
3502 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3504 Unexpect aCatch(SALOME_SalomeException);
3506 return _preMeshInfo->NbElements();
3508 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3511 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3513 Unexpect aCatch(SALOME_SalomeException);
3515 return _preMeshInfo->Nb0DElements();
3517 return _impl->Nb0DElements();
3520 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3522 Unexpect aCatch(SALOME_SalomeException);
3524 return _preMeshInfo->NbBalls();
3526 return _impl->NbBalls();
3529 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3531 Unexpect aCatch(SALOME_SalomeException);
3533 return _preMeshInfo->NbEdges();
3535 return _impl->NbEdges();
3538 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3539 throw(SALOME::SALOME_Exception)
3541 Unexpect aCatch(SALOME_SalomeException);
3543 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3545 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3548 //=============================================================================
3550 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3552 Unexpect aCatch(SALOME_SalomeException);
3554 return _preMeshInfo->NbFaces();
3556 return _impl->NbFaces();
3559 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3561 Unexpect aCatch(SALOME_SalomeException);
3563 return _preMeshInfo->NbTriangles();
3565 return _impl->NbTriangles();
3568 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3570 Unexpect aCatch(SALOME_SalomeException);
3572 return _preMeshInfo->NbBiQuadTriangles();
3574 return _impl->NbBiQuadTriangles();
3577 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3579 Unexpect aCatch(SALOME_SalomeException);
3581 return _preMeshInfo->NbQuadrangles();
3583 return _impl->NbQuadrangles();
3586 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3588 Unexpect aCatch(SALOME_SalomeException);
3590 return _preMeshInfo->NbBiQuadQuadrangles();
3592 return _impl->NbBiQuadQuadrangles();
3595 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3597 Unexpect aCatch(SALOME_SalomeException);
3599 return _preMeshInfo->NbPolygons();
3601 return _impl->NbPolygons();
3604 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3605 throw(SALOME::SALOME_Exception)
3607 Unexpect aCatch(SALOME_SalomeException);
3609 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3611 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3614 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3615 throw(SALOME::SALOME_Exception)
3617 Unexpect aCatch(SALOME_SalomeException);
3619 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3621 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3624 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3625 throw(SALOME::SALOME_Exception)
3627 Unexpect aCatch(SALOME_SalomeException);
3629 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3631 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3634 //=============================================================================
3636 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3638 Unexpect aCatch(SALOME_SalomeException);
3640 return _preMeshInfo->NbVolumes();
3642 return _impl->NbVolumes();
3645 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3647 Unexpect aCatch(SALOME_SalomeException);
3649 return _preMeshInfo->NbTetras();
3651 return _impl->NbTetras();
3654 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3656 Unexpect aCatch(SALOME_SalomeException);
3658 return _preMeshInfo->NbHexas();
3660 return _impl->NbHexas();
3663 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3665 Unexpect aCatch(SALOME_SalomeException);
3667 return _preMeshInfo->NbTriQuadHexas();
3669 return _impl->NbTriQuadraticHexas();
3672 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3674 Unexpect aCatch(SALOME_SalomeException);
3676 return _preMeshInfo->NbPyramids();
3678 return _impl->NbPyramids();
3681 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3683 Unexpect aCatch(SALOME_SalomeException);
3685 return _preMeshInfo->NbPrisms();
3687 return _impl->NbPrisms();
3690 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3692 Unexpect aCatch(SALOME_SalomeException);
3694 return _preMeshInfo->NbHexPrisms();
3696 return _impl->NbHexagonalPrisms();
3699 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3701 Unexpect aCatch(SALOME_SalomeException);
3703 return _preMeshInfo->NbPolyhedrons();
3705 return _impl->NbPolyhedrons();
3708 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3709 throw(SALOME::SALOME_Exception)
3711 Unexpect aCatch(SALOME_SalomeException);
3713 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3715 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3718 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3719 throw(SALOME::SALOME_Exception)
3721 Unexpect aCatch(SALOME_SalomeException);
3723 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3725 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3728 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3729 throw(SALOME::SALOME_Exception)
3731 Unexpect aCatch(SALOME_SalomeException);
3733 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3735 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3738 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3739 throw(SALOME::SALOME_Exception)
3741 Unexpect aCatch(SALOME_SalomeException);
3743 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3745 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3748 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3749 throw(SALOME::SALOME_Exception)
3751 Unexpect aCatch(SALOME_SalomeException);
3753 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3755 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3758 //=============================================================================
3760 * Returns nb of published sub-meshes
3762 //=============================================================================
3764 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3766 Unexpect aCatch(SALOME_SalomeException);
3767 return _mapSubMesh_i.size();
3770 //=============================================================================
3772 * Dumps mesh into a string
3774 //=============================================================================
3776 char* SMESH_Mesh_i::Dump()
3780 return CORBA::string_dup( os.str().c_str() );
3783 //=============================================================================
3785 * Method of SMESH_IDSource interface
3787 //=============================================================================
3789 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3791 return GetElementsId();
3794 //=============================================================================
3796 * Returns ids of all elements
3798 //=============================================================================
3800 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3801 throw (SALOME::SALOME_Exception)
3803 Unexpect aCatch(SALOME_SalomeException);
3805 _preMeshInfo->FullLoadFromFile();
3807 SMESH::long_array_var aResult = new SMESH::long_array();
3808 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3810 if ( aSMESHDS_Mesh == NULL )
3811 return aResult._retn();
3813 long nbElements = NbElements();
3814 aResult->length( nbElements );
3815 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3816 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3817 aResult[i] = anIt->next()->GetID();
3819 return aResult._retn();
3823 //=============================================================================
3825 * Returns ids of all elements of given type
3827 //=============================================================================
3829 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3830 throw (SALOME::SALOME_Exception)
3832 Unexpect aCatch(SALOME_SalomeException);
3834 _preMeshInfo->FullLoadFromFile();
3836 SMESH::long_array_var aResult = new SMESH::long_array();
3837 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3839 if ( aSMESHDS_Mesh == NULL )
3840 return aResult._retn();
3842 long nbElements = NbElements();
3844 // No sense in returning ids of elements along with ids of nodes:
3845 // when theElemType == SMESH::ALL, return node ids only if
3846 // there are no elements
3847 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3848 return GetNodesId();
3850 aResult->length( nbElements );
3854 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3855 while ( i < nbElements && anIt->more() )
3856 aResult[i++] = anIt->next()->GetID();
3858 aResult->length( i );
3860 return aResult._retn();
3863 //=============================================================================
3865 * Returns ids of all nodes
3867 //=============================================================================
3869 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3870 throw (SALOME::SALOME_Exception)
3872 Unexpect aCatch(SALOME_SalomeException);
3874 _preMeshInfo->FullLoadFromFile();
3876 SMESH::long_array_var aResult = new SMESH::long_array();
3877 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3879 if ( aSMESHDS_Mesh == NULL )
3880 return aResult._retn();
3882 long nbNodes = NbNodes();
3883 aResult->length( nbNodes );
3884 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3885 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3886 aResult[i] = anIt->next()->GetID();
3888 return aResult._retn();
3891 //=============================================================================
3895 //=============================================================================
3897 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3898 throw (SALOME::SALOME_Exception)
3900 SMESH::ElementType type;
3904 _preMeshInfo->FullLoadFromFile();
3906 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3908 SMESH_CATCH( SMESH::throwCorbaException );
3913 //=============================================================================
3917 //=============================================================================
3919 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3920 throw (SALOME::SALOME_Exception)
3923 _preMeshInfo->FullLoadFromFile();
3925 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3927 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3929 return ( SMESH::EntityType ) e->GetEntityType();
3932 //=============================================================================
3936 //=============================================================================
3938 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3939 throw (SALOME::SALOME_Exception)
3942 _preMeshInfo->FullLoadFromFile();
3944 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3946 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3948 return ( SMESH::GeometryType ) e->GetGeomType();
3951 //=============================================================================
3953 * Returns ID of elements for given submesh
3955 //=============================================================================
3956 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3957 throw (SALOME::SALOME_Exception)
3959 SMESH::long_array_var aResult = new SMESH::long_array();
3963 _preMeshInfo->FullLoadFromFile();
3965 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3966 if(!SM) return aResult._retn();
3968 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3969 if(!SDSM) return aResult._retn();
3971 aResult->length(SDSM->NbElements());
3973 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3975 while ( eIt->more() ) {
3976 aResult[i++] = eIt->next()->GetID();
3979 SMESH_CATCH( SMESH::throwCorbaException );
3981 return aResult._retn();
3984 //=============================================================================
3986 * Returns ID of nodes for given submesh
3987 * If param all==true - returns all nodes, else -
3988 * returns only nodes on shapes.
3990 //=============================================================================
3992 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3994 throw (SALOME::SALOME_Exception)
3996 SMESH::long_array_var aResult = new SMESH::long_array();
4000 _preMeshInfo->FullLoadFromFile();
4002 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4003 if(!SM) return aResult._retn();
4005 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4006 if(!SDSM) return aResult._retn();
4009 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4010 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4011 while ( nIt->more() ) {
4012 const SMDS_MeshNode* elem = nIt->next();
4013 theElems.insert( elem->GetID() );
4016 else { // all nodes of submesh elements
4017 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4018 while ( eIt->more() ) {
4019 const SMDS_MeshElement* anElem = eIt->next();
4020 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4021 while ( nIt->more() ) {
4022 const SMDS_MeshElement* elem = nIt->next();
4023 theElems.insert( elem->GetID() );
4028 aResult->length(theElems.size());
4029 set<int>::iterator itElem;
4031 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4032 aResult[i++] = *itElem;
4034 SMESH_CATCH( SMESH::throwCorbaException );
4036 return aResult._retn();
4039 //=============================================================================
4041 * Returns type of elements for given submesh
4043 //=============================================================================
4045 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4046 throw (SALOME::SALOME_Exception)
4048 SMESH::ElementType type;
4052 _preMeshInfo->FullLoadFromFile();
4054 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4055 if(!SM) return SMESH::ALL;
4057 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4058 if(!SDSM) return SMESH::ALL;
4060 if(SDSM->NbElements()==0)
4061 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4063 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4064 const SMDS_MeshElement* anElem = eIt->next();
4066 type = ( SMESH::ElementType ) anElem->GetType();
4068 SMESH_CATCH( SMESH::throwCorbaException );
4074 //=============================================================================
4076 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4078 //=============================================================================
4080 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4083 _preMeshInfo->FullLoadFromFile();
4085 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4087 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4092 //=============================================================================
4094 * Get XYZ coordinates of node as list of double
4095 * If there is not node for given ID - returns empty list
4097 //=============================================================================
4099 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4102 _preMeshInfo->FullLoadFromFile();
4104 SMESH::double_array_var aResult = new SMESH::double_array();
4105 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4106 if ( aSMESHDS_Mesh == NULL )
4107 return aResult._retn();
4110 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4112 return aResult._retn();
4116 aResult[0] = aNode->X();
4117 aResult[1] = aNode->Y();
4118 aResult[2] = aNode->Z();
4119 return aResult._retn();
4123 //=============================================================================
4125 * For given node returns list of IDs of inverse elements
4126 * If there is not node for given ID - returns empty list
4128 //=============================================================================
4130 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4133 _preMeshInfo->FullLoadFromFile();
4135 SMESH::long_array_var aResult = new SMESH::long_array();
4136 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4137 if ( aSMESHDS_Mesh == NULL )
4138 return aResult._retn();
4141 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4143 return aResult._retn();
4145 // find inverse elements
4146 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4147 aResult->length( aNode->NbInverseElements() );
4148 for( int i = 0; eIt->more(); ++i )
4150 const SMDS_MeshElement* elem = eIt->next();
4151 aResult[ i ] = elem->GetID();
4153 return aResult._retn();
4156 //=============================================================================
4158 * \brief Return position of a node on shape
4160 //=============================================================================
4162 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4165 _preMeshInfo->FullLoadFromFile();
4167 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4168 aNodePosition->shapeID = 0;
4169 aNodePosition->shapeType = GEOM::SHAPE;
4171 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4172 if ( !mesh ) return aNodePosition;
4174 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4176 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4178 aNodePosition->shapeID = aNode->getshapeId();
4179 switch ( pos->GetTypeOfPosition() ) {
4181 aNodePosition->shapeType = GEOM::EDGE;
4182 aNodePosition->params.length(1);
4183 aNodePosition->params[0] =
4184 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4187 aNodePosition->shapeType = GEOM::FACE;
4188 aNodePosition->params.length(2);
4189 aNodePosition->params[0] =
4190 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4191 aNodePosition->params[1] =
4192 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4194 case SMDS_TOP_VERTEX:
4195 aNodePosition->shapeType = GEOM::VERTEX;
4197 case SMDS_TOP_3DSPACE:
4198 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4199 aNodePosition->shapeType = GEOM::SOLID;
4200 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4201 aNodePosition->shapeType = GEOM::SHELL;
4207 return aNodePosition;
4210 //=============================================================================
4212 * \brief Return position of an element on shape
4214 //=============================================================================
4216 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4219 _preMeshInfo->FullLoadFromFile();
4221 SMESH::ElementPosition anElementPosition;
4222 anElementPosition.shapeID = 0;
4223 anElementPosition.shapeType = GEOM::SHAPE;
4225 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4226 if ( !mesh ) return anElementPosition;
4228 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4230 anElementPosition.shapeID = anElem->getshapeId();
4231 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4232 if ( !aSp.IsNull() ) {
4233 switch ( aSp.ShapeType() ) {
4235 anElementPosition.shapeType = GEOM::EDGE;
4238 anElementPosition.shapeType = GEOM::FACE;
4241 anElementPosition.shapeType = GEOM::VERTEX;
4244 anElementPosition.shapeType = GEOM::SOLID;
4247 anElementPosition.shapeType = GEOM::SHELL;
4253 return anElementPosition;
4256 //=============================================================================
4258 * If given element is node returns IDs of shape from position
4259 * If there is not node for given ID - returns -1
4261 //=============================================================================
4263 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4266 _preMeshInfo->FullLoadFromFile();
4268 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4269 if ( aSMESHDS_Mesh == NULL )
4273 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4275 return aNode->getshapeId();
4282 //=============================================================================
4284 * For given element returns ID of result shape after
4285 * ::FindShape() from SMESH_MeshEditor
4286 * If there is not element for given ID - returns -1
4288 //=============================================================================
4290 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4293 _preMeshInfo->FullLoadFromFile();
4295 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4296 if ( aSMESHDS_Mesh == NULL )
4299 // try to find element
4300 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4304 ::SMESH_MeshEditor aMeshEditor(_impl);
4305 int index = aMeshEditor.FindShape( elem );
4313 //=============================================================================
4315 * Returns number of nodes for given element
4316 * If there is not element for given ID - returns -1
4318 //=============================================================================
4320 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4323 _preMeshInfo->FullLoadFromFile();
4325 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4326 if ( aSMESHDS_Mesh == NULL ) return -1;
4327 // try to find element
4328 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4329 if(!elem) return -1;
4330 return elem->NbNodes();
4334 //=============================================================================
4336 * Returns ID of node by given index for given element
4337 * If there is not element for given ID - returns -1
4338 * If there is not node for given index - returns -2
4340 //=============================================================================
4342 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4345 _preMeshInfo->FullLoadFromFile();
4347 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4348 if ( aSMESHDS_Mesh == NULL ) return -1;
4349 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4350 if(!elem) return -1;
4351 if( index>=elem->NbNodes() || index<0 ) return -1;
4352 return elem->GetNode(index)->GetID();
4355 //=============================================================================
4357 * Returns IDs of nodes of given element
4359 //=============================================================================
4361 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4364 _preMeshInfo->FullLoadFromFile();
4366 SMESH::long_array_var aResult = new SMESH::long_array();
4367 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4369 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4371 aResult->length( elem->NbNodes() );
4372 for ( int i = 0; i < elem->NbNodes(); ++i )
4373 aResult[ i ] = elem->GetNode( i )->GetID();
4376 return aResult._retn();
4379 //=============================================================================
4381 * Returns true if given node is medium node
4382 * in given quadratic element
4384 //=============================================================================
4386 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4389 _preMeshInfo->FullLoadFromFile();
4391 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4392 if ( aSMESHDS_Mesh == NULL ) return false;
4394 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4395 if(!aNode) return false;
4396 // try to find element
4397 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4398 if(!elem) return false;
4400 return elem->IsMediumNode(aNode);
4404 //=============================================================================
4406 * Returns true if given node is medium node
4407 * in one of quadratic elements
4409 //=============================================================================
4411 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4412 SMESH::ElementType theElemType)
4415 _preMeshInfo->FullLoadFromFile();
4417 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4418 if ( aSMESHDS_Mesh == NULL ) return false;
4421 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4422 if(!aNode) return false;
4424 SMESH_MesherHelper aHelper( *(_impl) );
4426 SMDSAbs_ElementType aType;
4427 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4428 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4429 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4430 else aType = SMDSAbs_All;
4432 return aHelper.IsMedium(aNode,aType);
4436 //=============================================================================
4438 * Returns number of edges for given element
4440 //=============================================================================
4442 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4445 _preMeshInfo->FullLoadFromFile();
4447 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4448 if ( aSMESHDS_Mesh == NULL ) return -1;
4449 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4450 if(!elem) return -1;
4451 return elem->NbEdges();
4455 //=============================================================================
4457 * Returns number of faces for given element
4459 //=============================================================================
4461 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4464 _preMeshInfo->FullLoadFromFile();
4466 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4467 if ( aSMESHDS_Mesh == NULL ) return -1;
4468 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4469 if(!elem) return -1;
4470 return elem->NbFaces();
4473 //=======================================================================
4474 //function : GetElemFaceNodes
4475 //purpose : Returns nodes of given face (counted from zero) for given element.
4476 //=======================================================================
4478 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4479 CORBA::Short faceIndex)
4482 _preMeshInfo->FullLoadFromFile();
4484 SMESH::long_array_var aResult = new SMESH::long_array();
4485 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4487 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4489 SMDS_VolumeTool vtool( elem );
4490 if ( faceIndex < vtool.NbFaces() )
4492 aResult->length( vtool.NbFaceNodes( faceIndex ));
4493 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4494 for ( int i = 0; i < aResult->length(); ++i )
4495 aResult[ i ] = nn[ i ]->GetID();
4499 return aResult._retn();
4502 //=======================================================================
4503 //function : GetElemFaceNodes
4504 //purpose : Returns three components of normal of given mesh face.
4505 //=======================================================================
4507 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4508 CORBA::Boolean normalized)
4511 _preMeshInfo->FullLoadFromFile();
4513 SMESH::double_array_var aResult = new SMESH::double_array();
4515 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4518 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4520 aResult->length( 3 );
4521 aResult[ 0 ] = normal.X();
4522 aResult[ 1 ] = normal.Y();
4523 aResult[ 2 ] = normal.Z();
4526 return aResult._retn();
4529 //=======================================================================
4530 //function : FindElementByNodes
4531 //purpose : Returns an element based on all given nodes.
4532 //=======================================================================
4534 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4537 _preMeshInfo->FullLoadFromFile();
4539 CORBA::Long elemID(0);
4540 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4542 vector< const SMDS_MeshNode * > nn( nodes.length() );
4543 for ( int i = 0; i < nodes.length(); ++i )
4544 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4547 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4548 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4549 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4550 _impl->NbVolumes( ORDER_QUADRATIC )))
4551 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4553 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4558 //=============================================================================
4560 * Returns true if given element is polygon
4562 //=============================================================================
4564 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4567 _preMeshInfo->FullLoadFromFile();
4569 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4570 if ( aSMESHDS_Mesh == NULL ) return false;
4571 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4572 if(!elem) return false;
4573 return elem->IsPoly();
4577 //=============================================================================
4579 * Returns true if given element is quadratic
4581 //=============================================================================
4583 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4586 _preMeshInfo->FullLoadFromFile();
4588 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4589 if ( aSMESHDS_Mesh == NULL ) return false;
4590 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4591 if(!elem) return false;
4592 return elem->IsQuadratic();
4595 //=============================================================================
4597 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4599 //=============================================================================
4601 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4604 _preMeshInfo->FullLoadFromFile();
4606 if ( const SMDS_BallElement* ball =
4607 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4608 return ball->GetDiameter();
4613 //=============================================================================
4615 * Returns bary center for given element
4617 //=============================================================================
4619 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4622 _preMeshInfo->FullLoadFromFile();
4624 SMESH::double_array_var aResult = new SMESH::double_array();
4625 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4626 if ( aSMESHDS_Mesh == NULL )
4627 return aResult._retn();
4629 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4631 return aResult._retn();
4633 if(elem->GetType()==SMDSAbs_Volume) {
4634 SMDS_VolumeTool aTool;
4635 if(aTool.Set(elem)) {
4637 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4642 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4644 double x=0., y=0., z=0.;
4645 for(; anIt->more(); ) {
4647 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4661 return aResult._retn();
4664 //================================================================================
4666 * \brief Create a group of elements preventing computation of a sub-shape
4668 //================================================================================
4670 SMESH::ListOfGroups*
4671 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4672 const char* theGroupName )
4673 throw ( SALOME::SALOME_Exception )
4675 Unexpect aCatch(SALOME_SalomeException);
4677 if ( !theGroupName || strlen( theGroupName) == 0 )
4678 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4680 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4682 // submesh by subshape id
4683 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4684 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4687 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4688 if ( error && !error->myBadElements.empty())
4690 // sort bad elements by type
4691 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4692 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4693 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4694 for ( ; elemIt != elemEnd; ++elemIt )
4696 const SMDS_MeshElement* elem = *elemIt;
4697 if ( !elem ) continue;
4699 if ( elem->GetID() < 1 )
4701 // elem is a temporary element, make a real element
4702 vector< const SMDS_MeshNode* > nodes;
4703 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4704 while ( nIt->more() && elem )
4706 nodes.push_back( nIt->next() );
4707 if ( nodes.back()->GetID() < 1 )
4708 elem = 0; // a temporary element on temporary nodes
4712 ::SMESH_MeshEditor editor( _impl );
4713 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4717 elemsByType[ elem->GetType() ].push_back( elem );
4720 // how many groups to create?
4722 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4723 nbTypes += int( !elemsByType[ i ].empty() );
4724 groups->length( nbTypes );
4727 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4729 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4730 if ( elems.empty() ) continue;
4732 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4733 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4735 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4736 SMESH::SMESH_Mesh_var mesh = _this();
4737 SALOMEDS::SObject_wrap aSO =
4738 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4739 GEOM::GEOM_Object::_nil(), theGroupName);
4740 aSO->_is_nil(); // avoid "unused variable" warning
4742 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4743 if ( !grp_i ) continue;
4745 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4746 for ( size_t iE = 0; iE < elems.size(); ++iE )
4747 grpDS->SMDSGroup().Add( elems[ iE ]);
4752 return groups._retn();
4755 //=============================================================================
4757 * Create and publish group servants if any groups were imported or created anyhow
4759 //=============================================================================
4761 void SMESH_Mesh_i::CreateGroupServants()
4763 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4764 SMESH::SMESH_Mesh_var aMesh = _this();
4767 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4768 while ( groupIt->more() )
4770 ::SMESH_Group* group = groupIt->next();
4771 int anId = group->GetGroupDS()->GetID();
4773 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4774 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4776 addedIDs.insert( anId );
4778 SMESH_GroupBase_i* aGroupImpl;
4780 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4781 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4783 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4784 shape = groupOnGeom->GetShape();
4787 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4790 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4791 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4792 aGroupImpl->Register();
4794 // register CORBA object for persistence
4795 int nextId = _gen_i->RegisterObject( groupVar );
4796 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4797 else { nextId = 0; } // avoid "unused variable" warning in release mode
4799 // publishing the groups in the study
4800 if ( !aStudy->_is_nil() ) {
4801 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4802 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4805 if ( !addedIDs.empty() )
4808 set<int>::iterator id = addedIDs.begin();
4809 for ( ; id != addedIDs.end(); ++id )
4811 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4812 int i = std::distance( _mapGroups.begin(), it );
4813 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4818 //=============================================================================
4820 * \brief Return groups cantained in _mapGroups by their IDs
4822 //=============================================================================
4824 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4826 int nbGroups = groupIDs.size();
4827 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4828 aList->length( nbGroups );
4830 list<int>::const_iterator ids = groupIDs.begin();
4831 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4833 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4834 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4835 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4837 aList->length( nbGroups );
4838 return aList._retn();
4841 //=============================================================================
4843 * \brief Return information about imported file
4845 //=============================================================================
4847 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4849 SMESH::MedFileInfo_var res( _medFileInfo );
4850 if ( !res.operator->() ) {
4851 res = new SMESH::MedFileInfo;
4853 res->fileSize = res->major = res->minor = res->release = -1;
4858 //=============================================================================
4860 * \brief Pass names of mesh groups from study to mesh DS
4862 //=============================================================================
4864 void SMESH_Mesh_i::checkGroupNames()
4866 int nbGrp = NbGroups();
4870 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4871 if ( aStudy->_is_nil() )
4872 return; // nothing to do
4874 SMESH::ListOfGroups* grpList = 0;
4875 // avoid dump of "GetGroups"
4877 // store python dump into a local variable inside local scope
4878 SMESH::TPythonDump pDump; // do not delete this line of code
4879 grpList = GetGroups();
4882 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4883 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4886 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4887 if ( aGrpSO->_is_nil() )
4889 // correct name of the mesh group if necessary
4890 const char* guiName = aGrpSO->GetName();
4891 if ( strcmp(guiName, aGrp->GetName()) )
4892 aGrp->SetName( guiName );
4896 //=============================================================================
4898 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4900 //=============================================================================
4901 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4903 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4907 //=============================================================================
4909 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4911 //=============================================================================
4913 char* SMESH_Mesh_i::GetParameters()
4915 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4918 //=============================================================================
4920 * \brief Returns list of notebook variables used for last Mesh operation
4922 //=============================================================================
4923 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4925 SMESH::string_array_var aResult = new SMESH::string_array();
4926 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4928 CORBA::String_var aParameters = GetParameters();
4929 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4930 if ( !aStudy->_is_nil()) {
4931 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4932 if(aSections->length() > 0) {
4933 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4934 aResult->length(aVars.length());
4935 for(int i = 0;i < aVars.length();i++)
4936 aResult[i] = CORBA::string_dup( aVars[i]);
4940 return aResult._retn();
4943 //=======================================================================
4944 //function : GetTypes
4945 //purpose : Returns types of elements it contains
4946 //=======================================================================
4948 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4951 return _preMeshInfo->GetTypes();
4953 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4957 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4958 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4959 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4960 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4961 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4962 types->length( nbTypes );
4964 return types._retn();
4967 //=======================================================================
4968 //function : GetMesh
4969 //purpose : Returns self
4970 //=======================================================================
4972 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4974 return SMESH::SMESH_Mesh::_duplicate( _this() );
4977 //=======================================================================
4978 //function : IsMeshInfoCorrect
4979 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4980 // * happen if mesh data is not yet fully loaded from the file of study.
4981 //=======================================================================
4983 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4985 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4988 //=============================================================================
4990 * \brief Returns number of mesh elements per each \a EntityType
4992 //=============================================================================
4994 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4997 return _preMeshInfo->GetMeshInfo();
4999 SMESH::long_array_var aRes = new SMESH::long_array();
5000 aRes->length(SMESH::Entity_Last);
5001 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5003 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5005 return aRes._retn();
5006 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5007 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5008 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5009 return aRes._retn();
5012 //=============================================================================
5014 * \brief Returns number of mesh elements per each \a ElementType
5016 //=============================================================================
5018 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5020 SMESH::long_array_var aRes = new SMESH::long_array();
5021 aRes->length(SMESH::NB_ELEMENT_TYPES);
5022 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5025 const SMDS_MeshInfo* meshInfo = 0;
5027 meshInfo = _preMeshInfo;
5028 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5029 meshInfo = & meshDS->GetMeshInfo();
5032 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5033 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5035 return aRes._retn();
5038 //=============================================================================
5040 * Collect statistic of mesh elements given by iterator
5042 //=============================================================================
5044 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5045 SMESH::long_array& theInfo)
5047 if (!theItr) return;
5048 while (theItr->more())
5049 theInfo[ theItr->next()->GetEntityType() ]++;
5052 //=============================================================================
5053 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5054 * SMESH::ElementType type) */
5056 using namespace SMESH::Controls;
5057 //-----------------------------------------------------------------------------
5058 struct PredicateIterator : public SMDS_ElemIterator
5060 SMDS_ElemIteratorPtr _elemIter;
5061 PredicatePtr _predicate;
5062 const SMDS_MeshElement* _elem;
5064 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5065 PredicatePtr predicate):
5066 _elemIter(iterator), _predicate(predicate)
5074 virtual const SMDS_MeshElement* next()
5076 const SMDS_MeshElement* res = _elem;
5078 while ( _elemIter->more() && !_elem )
5080 _elem = _elemIter->next();
5081 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5088 //-----------------------------------------------------------------------------
5089 struct IDSourceIterator : public SMDS_ElemIterator
5091 const CORBA::Long* _idPtr;
5092 const CORBA::Long* _idEndPtr;
5093 SMESH::long_array_var _idArray;
5094 const SMDS_Mesh* _mesh;
5095 const SMDSAbs_ElementType _type;
5096 const SMDS_MeshElement* _elem;
5098 IDSourceIterator( const SMDS_Mesh* mesh,
5099 const CORBA::Long* ids,
5101 SMDSAbs_ElementType type):
5102 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5104 if ( _idPtr && nbIds && _mesh )
5107 IDSourceIterator( const SMDS_Mesh* mesh,
5108 SMESH::long_array* idArray,
5109 SMDSAbs_ElementType type):
5110 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5112 if ( idArray && _mesh )
5114 _idPtr = &_idArray[0];
5115 _idEndPtr = _idPtr + _idArray->length();
5123 virtual const SMDS_MeshElement* next()
5125 const SMDS_MeshElement* res = _elem;
5127 while ( _idPtr < _idEndPtr && !_elem )
5129 if ( _type == SMDSAbs_Node )
5131 _elem = _mesh->FindNode( *_idPtr++ );
5133 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5134 _elem->GetType() != _type )
5142 //-----------------------------------------------------------------------------
5144 struct NodeOfElemIterator : public SMDS_ElemIterator
5146 TColStd_MapOfInteger _checkedNodeIDs;
5147 SMDS_ElemIteratorPtr _elemIter;
5148 SMDS_ElemIteratorPtr _nodeIter;
5149 const SMDS_MeshElement* _node;
5151 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5153 if ( _elemIter && _elemIter->more() )
5155 _nodeIter = _elemIter->next()->nodesIterator();
5163 virtual const SMDS_MeshElement* next()
5165 const SMDS_MeshElement* res = _node;
5167 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5169 if ( _nodeIter->more() )
5171 _node = _nodeIter->next();
5172 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5177 _nodeIter = _elemIter->next()->nodesIterator();
5185 //=============================================================================
5187 * Return iterator on elements of given type in given object
5189 //=============================================================================
5191 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5192 SMESH::ElementType theType)
5194 SMDS_ElemIteratorPtr elemIt;
5195 bool typeOK = false;
5196 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5198 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5199 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5200 if ( !mesh_i ) return elemIt;
5201 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5203 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5205 elemIt = meshDS->elementsIterator( elemType );
5208 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5210 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5213 elemIt = sm->GetElements();
5214 if ( elemType != SMDSAbs_Node )
5216 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5217 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5221 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5223 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5224 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5226 elemIt = groupDS->GetElements();
5227 typeOK = ( groupDS->GetType() == elemType );
5230 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5232 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5234 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5235 if ( pred_i && pred_i->GetPredicate() )
5237 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5238 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5239 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5240 typeOK = ( filterType == elemType );
5246 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5247 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5248 if ( isNodes && elemType != SMDSAbs_Node )
5250 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5253 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5254 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5258 SMESH::long_array_var ids = theObject->GetIDs();
5259 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5261 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5264 if ( elemIt && elemIt->more() && !typeOK )
5266 if ( elemType == SMDSAbs_Node )
5268 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5272 elemIt = SMDS_ElemIteratorPtr();
5278 //=============================================================================
5279 namespace // Finding concurrent hypotheses
5280 //=============================================================================
5284 * \brief mapping of mesh dimension into shape type
5286 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5288 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5290 case 0: aType = TopAbs_VERTEX; break;
5291 case 1: aType = TopAbs_EDGE; break;
5292 case 2: aType = TopAbs_FACE; break;
5294 default:aType = TopAbs_SOLID; break;
5299 //-----------------------------------------------------------------------------
5301 * \brief Internal structure used to find concurent submeshes
5303 * It represents a pair < submesh, concurent dimension >, where
5304 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5305 * with another submesh. In other words, it is dimension of a hypothesis assigned
5312 int _dim; //!< a dimension the algo can build (concurrent dimension)
5313 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5314 TopTools_MapOfShape _shapeMap;
5315 SMESH_subMesh* _subMesh;
5316 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5318 //-----------------------------------------------------------------------------
5319 // Return the algorithm
5320 const SMESH_Algo* GetAlgo() const
5321 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5323 //-----------------------------------------------------------------------------
5325 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5327 const TopoDS_Shape& theShape)
5329 _subMesh = (SMESH_subMesh*)theSubMesh;
5330 SetShape( theDim, theShape );
5333 //-----------------------------------------------------------------------------
5335 void SetShape(const int theDim,
5336 const TopoDS_Shape& theShape)
5339 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5340 if (_dim >= _ownDim)
5341 _shapeMap.Add( theShape );
5343 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5344 for( ; anExp.More(); anExp.Next() )
5345 _shapeMap.Add( anExp.Current() );
5349 //-----------------------------------------------------------------------------
5350 //! Check sharing of sub-shapes
5351 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5352 const TopTools_MapOfShape& theToFind,
5353 const TopAbs_ShapeEnum theType)
5355 bool isShared = false;
5356 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5357 for (; !isShared && anItr.More(); anItr.Next() )
5359 const TopoDS_Shape aSubSh = anItr.Key();
5360 // check for case when concurrent dimensions are same
5361 isShared = theToFind.Contains( aSubSh );
5362 // check for sub-shape with concurrent dimension
5363 TopExp_Explorer anExp( aSubSh, theType );
5364 for ( ; !isShared && anExp.More(); anExp.Next() )
5365 isShared = theToFind.Contains( anExp.Current() );
5370 //-----------------------------------------------------------------------------
5371 //! check algorithms
5372 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5373 const SMESHDS_Hypothesis* theA2)
5375 if ( !theA1 || !theA2 ||
5376 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5377 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5378 return false; // one of the hypothesis is not algorithm
5379 // check algorithm names (should be equal)
5380 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5384 //-----------------------------------------------------------------------------
5385 //! Check if sub-shape hypotheses are concurrent
5386 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5388 if ( _subMesh == theOther->_subMesh )
5389 return false; // same sub-shape - should not be
5391 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5392 // any of the two submeshes is not on COMPOUND shape )
5393 // -> no concurrency
5394 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5395 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5396 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5397 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5398 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5401 // bool checkSubShape = ( _dim >= theOther->_dim )
5402 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5403 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5404 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5405 if ( !checkSubShape )
5408 // check algorithms to be same
5409 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5410 return true; // different algorithms -> concurrency !
5412 // check hypothesises for concurrence (skip first as algorithm)
5414 // pointers should be same, because it is referened from mesh hypothesis partition
5415 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5416 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5417 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5418 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5420 // the submeshes are concurrent if their algorithms has different parameters
5421 return nbSame != theOther->_hypotheses.size() - 1;
5424 // Return true if algorithm of this SMESH_DimHyp is used if no
5425 // sub-mesh order is imposed by the user
5426 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5428 // NeedDiscreteBoundary() algo has a higher priority
5429 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5430 theOther->GetAlgo()->NeedDiscreteBoundary() )
5431 return !this->GetAlgo()->NeedDiscreteBoundary();
5433 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5436 }; // end of SMESH_DimHyp
5437 //-----------------------------------------------------------------------------
5439 typedef list<const SMESH_DimHyp*> TDimHypList;
5441 //-----------------------------------------------------------------------------
5443 void addDimHypInstance(const int theDim,
5444 const TopoDS_Shape& theShape,
5445 const SMESH_Algo* theAlgo,
5446 const SMESH_subMesh* theSubMesh,
5447 const list <const SMESHDS_Hypothesis*>& theHypList,
5448 TDimHypList* theDimHypListArr )
5450 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5451 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5452 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5453 dimHyp->_hypotheses.push_front(theAlgo);
5454 listOfdimHyp.push_back( dimHyp );
5457 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5458 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5459 theHypList.begin(), theHypList.end() );
5462 //-----------------------------------------------------------------------------
5463 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5464 TDimHypList& theListOfConcurr)
5466 if ( theListOfConcurr.empty() )
5468 theListOfConcurr.push_back( theDimHyp );
5472 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5473 while ( hypIt != theListOfConcurr.end() &&
5474 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5476 theListOfConcurr.insert( hypIt, theDimHyp );
5480 //-----------------------------------------------------------------------------
5481 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5482 const TDimHypList& theListOfDimHyp,
5483 TDimHypList& theListOfConcurrHyp,
5484 set<int>& theSetOfConcurrId )
5486 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5487 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5489 const SMESH_DimHyp* curDimHyp = *rIt;
5490 if ( curDimHyp == theDimHyp )
5491 break; // meet own dimHyp pointer in same dimension
5493 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5494 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5496 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5501 //-----------------------------------------------------------------------------
5502 void unionLists(TListOfInt& theListOfId,
5503 TListOfListOfInt& theListOfListOfId,
5506 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5507 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5509 continue; //skip already treated lists
5510 // check if other list has any same submesh object
5511 TListOfInt& otherListOfId = *it;
5512 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5513 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5516 // union two lists (from source into target)
5517 TListOfInt::iterator it2 = otherListOfId.begin();
5518 for ( ; it2 != otherListOfId.end(); it2++ ) {
5519 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5520 theListOfId.push_back(*it2);
5522 // clear source list
5523 otherListOfId.clear();
5526 //-----------------------------------------------------------------------------
5528 //! free memory allocated for dimension-hypothesis objects
5529 void removeDimHyps( TDimHypList* theArrOfList )
5531 for (int i = 0; i < 4; i++ ) {
5532 TDimHypList& listOfdimHyp = theArrOfList[i];
5533 TDimHypList::const_iterator it = listOfdimHyp.begin();
5534 for ( ; it != listOfdimHyp.end(); it++ )
5539 //-----------------------------------------------------------------------------
5541 * \brief find common submeshes with given submesh
5542 * \param theSubMeshList list of already collected submesh to check
5543 * \param theSubMesh given submesh to intersect with other
5544 * \param theCommonSubMeshes collected common submeshes
5546 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5547 const SMESH_subMesh* theSubMesh,
5548 set<const SMESH_subMesh*>& theCommon )
5552 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5553 for ( ; it != theSubMeshList.end(); it++ )
5554 theSubMesh->FindIntersection( *it, theCommon );
5555 theSubMeshList.push_back( theSubMesh );
5556 //theCommon.insert( theSubMesh );
5559 //-----------------------------------------------------------------------------
5560 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5562 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5563 for ( ; listsIt != smLists.end(); ++listsIt )
5565 const TListOfInt& smIDs = *listsIt;
5566 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5574 //=============================================================================
5576 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5578 //=============================================================================
5580 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5582 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5583 if ( isSubMeshInList( submeshID, anOrder ))
5586 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5587 return isSubMeshInList( submeshID, allConurrent );
5590 //=============================================================================
5592 * \brief Return submesh objects list in meshing order
5594 //=============================================================================
5596 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5598 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5600 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5602 return aResult._retn();
5604 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5605 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5606 anOrder.splice( anOrder.end(), allConurrent );
5609 TListOfListOfInt::iterator listIt = anOrder.begin();
5610 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5611 unionLists( *listIt, anOrder, listIndx + 1 );
5613 // convert submesh ids into interface instances
5614 // and dump command into python
5615 convertMeshOrder( anOrder, aResult, false );
5617 return aResult._retn();
5620 //=============================================================================
5622 * \brief Finds concurrent sub-meshes
5624 //=============================================================================
5626 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5628 TListOfListOfInt anOrder;
5629 ::SMESH_Mesh& mesh = GetImpl();
5631 // collect submeshes and detect concurrent algorithms and hypothesises
5632 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5634 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5635 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5636 ::SMESH_subMesh* sm = (*i_sm).second;
5638 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5640 // list of assigned hypothesises
5641 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5642 // Find out dimensions where the submesh can be concurrent.
5643 // We define the dimensions by algo of each of hypotheses in hypList
5644 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5645 for( ; hypIt != hypList.end(); hypIt++ ) {
5646 SMESH_Algo* anAlgo = 0;
5647 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5648 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5649 // hyp it-self is algo
5650 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5652 // try to find algorithm with help of sub-shapes
5653 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5654 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5655 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5658 continue; // no algorithm assigned to a current submesh
5660 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5661 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5663 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5664 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5665 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5667 } // end iterations on submesh
5669 // iterate on created dimension-hypotheses and check for concurrents
5670 for ( int i = 0; i < 4; i++ ) {
5671 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5672 // check for concurrents in own and other dimensions (step-by-step)
5673 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5674 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5675 const SMESH_DimHyp* dimHyp = *dhIt;
5676 TDimHypList listOfConcurr;
5677 set<int> setOfConcurrIds;
5678 // looking for concurrents and collect into own list
5679 for ( int j = i; j < 4; j++ )
5680 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5681 // check if any concurrents found
5682 if ( listOfConcurr.size() > 0 ) {
5683 // add own submesh to list of concurrent
5684 addInOrderOfPriority( dimHyp, listOfConcurr );
5685 list<int> listOfConcurrIds;
5686 TDimHypList::iterator hypIt = listOfConcurr.begin();
5687 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5688 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5689 anOrder.push_back( listOfConcurrIds );
5694 removeDimHyps(dimHypListArr);
5696 // now, minimise the number of concurrent groups
5697 // Here we assume that lists of submeshes can have same submesh
5698 // in case of multi-dimension algorithms, as result
5699 // list with common submesh has to be united into one list
5701 TListOfListOfInt::iterator listIt = anOrder.begin();
5702 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5703 unionLists( *listIt, anOrder, listIndx + 1 );
5709 //=============================================================================
5711 * \brief Set submesh object order
5712 * \param theSubMeshArray submesh array order
5714 //=============================================================================
5716 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5719 _preMeshInfo->ForgetOrLoad();
5722 ::SMESH_Mesh& mesh = GetImpl();
5724 TPythonDump aPythonDump; // prevent dump of called methods
5725 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5727 TListOfListOfInt subMeshOrder;
5728 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5730 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5731 TListOfInt subMeshIds;
5733 aPythonDump << ", ";
5734 aPythonDump << "[ ";
5735 // Collect subMeshes which should be clear
5736 // do it list-by-list, because modification of submesh order
5737 // take effect between concurrent submeshes only
5738 set<const SMESH_subMesh*> subMeshToClear;
5739 list<const SMESH_subMesh*> subMeshList;
5740 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5742 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5744 aPythonDump << ", ";
5745 aPythonDump << subMesh;
5746 subMeshIds.push_back( subMesh->GetId() );
5747 // detect common parts of submeshes
5748 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5749 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5751 aPythonDump << " ]";
5752 subMeshOrder.push_back( subMeshIds );
5754 // clear collected submeshes
5755 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5756 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5757 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5758 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5760 aPythonDump << " ])";
5762 mesh.SetMeshOrder( subMeshOrder );
5768 //=============================================================================
5770 * \brief Convert submesh ids into submesh interfaces
5772 //=============================================================================
5774 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5775 SMESH::submesh_array_array& theResOrder,
5776 const bool theIsDump)
5778 int nbSet = theIdsOrder.size();
5779 TPythonDump aPythonDump; // prevent dump of called methods
5781 aPythonDump << "[ ";
5782 theResOrder.length(nbSet);
5783 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5785 for( ; it != theIdsOrder.end(); it++ ) {
5786 // translate submesh identificators into submesh objects
5787 // takeing into account real number of concurrent lists
5788 const TListOfInt& aSubOrder = (*it);
5789 if (!aSubOrder.size())
5792 aPythonDump << "[ ";
5793 // convert shape indeces into interfaces
5794 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5795 aResSubSet->length(aSubOrder.size());
5796 TListOfInt::const_iterator subIt = aSubOrder.begin();
5798 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5799 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5801 SMESH::SMESH_subMesh_var subMesh =
5802 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5805 aPythonDump << ", ";
5806 aPythonDump << subMesh;
5808 aResSubSet[ j++ ] = subMesh;
5811 aPythonDump << " ]";
5813 theResOrder[ listIndx++ ] = aResSubSet;
5815 // correct number of lists
5816 theResOrder.length( listIndx );
5819 // finilise python dump
5820 aPythonDump << " ]";
5821 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5825 //================================================================================
5827 // Implementation of SMESH_MeshPartDS
5829 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5830 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5832 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5833 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5835 _meshDS = mesh_i->GetImpl().GetMeshDS();
5837 SetPersistentId( _meshDS->GetPersistentId() );
5839 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5841 // <meshPart> is the whole mesh
5842 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5844 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5845 myGroupSet = _meshDS->GetGroups();
5850 SMESH::long_array_var anIDs = meshPart->GetIDs();
5851 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5852 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5854 for (int i=0; i < anIDs->length(); i++)
5855 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5856 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5861 for (int i=0; i < anIDs->length(); i++)
5862 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5863 if ( _elements[ e->GetType() ].insert( e ).second )
5866 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5867 while ( nIt->more() )
5869 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5870 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5877 _meshDS = 0; // to enforce iteration on _elements and _nodes
5880 // -------------------------------------------------------------------------------------
5881 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5882 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5885 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5886 for ( ; partIt != meshPart.end(); ++partIt )
5887 if ( const SMDS_MeshElement * e = *partIt )
5888 if ( _elements[ e->GetType() ].insert( e ).second )
5891 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5892 while ( nIt->more() )
5894 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5895 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5901 // -------------------------------------------------------------------------------------
5902 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5904 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5906 typedef SMDS_SetIterator
5907 <const SMDS_MeshElement*,
5908 TIDSortedElemSet::const_iterator,
5909 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5910 SMDS_MeshElement::GeomFilter
5913 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5915 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5916 _elements[type].end(),
5917 SMDS_MeshElement::GeomFilter( geomType )));
5919 // -------------------------------------------------------------------------------------
5920 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5922 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5924 typedef SMDS_SetIterator
5925 <const SMDS_MeshElement*,
5926 TIDSortedElemSet::const_iterator,
5927 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5928 SMDS_MeshElement::EntityFilter
5931 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5933 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5934 _elements[type].end(),
5935 SMDS_MeshElement::EntityFilter( entity )));
5937 // -------------------------------------------------------------------------------------
5938 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5940 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5941 if ( type == SMDSAbs_All && !_meshDS )
5943 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5945 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5946 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5948 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5950 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5951 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5953 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5954 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5956 // -------------------------------------------------------------------------------------
5957 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5958 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5960 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5961 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5962 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5964 // -------------------------------------------------------------------------------------
5965 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5966 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5967 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5968 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5969 #undef _GET_ITER_DEFINE
5971 // END Implementation of SMESH_MeshPartDS
5973 //================================================================================