1 // Copyright (C) 2007-2013 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.
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_SMESHDS_Mesh.h"
30 #include "MED_Factory.hxx"
31 #include "SMDS_EdgePosition.hxx"
32 #include "SMDS_ElemIterator.hxx"
33 #include "SMDS_FacePosition.hxx"
34 #include "SMDS_IteratorOnIterators.hxx"
35 #include "SMDS_MeshGroup.hxx"
36 #include "SMDS_SetIterator.hxx"
37 #include "SMDS_VolumeTool.hxx"
38 #include "SMESHDS_Command.hxx"
39 #include "SMESHDS_CommandType.hxx"
40 #include "SMESHDS_Group.hxx"
41 #include "SMESHDS_GroupOnGeom.hxx"
42 #include "SMESH_Filter_i.hxx"
43 #include "SMESH_Gen_i.hxx"
44 #include "SMESH_Group.hxx"
45 #include "SMESH_Group_i.hxx"
46 #include "SMESH_MEDMesh_i.hxx"
47 #include "SMESH_MeshEditor.hxx"
48 #include "SMESH_MeshEditor_i.hxx"
49 #include "SMESH_MeshPartDS.hxx"
50 #include "SMESH_MesherHelper.hxx"
51 #include "SMESH_PreMeshInfo.hxx"
52 #include "SMESH_PythonDump.hxx"
53 #include "SMESH_subMesh_i.hxx"
56 #include <SALOMEDS_Attributes_wrap.hxx>
57 #include <SALOMEDS_wrap.hxx>
58 #include <SALOME_NamingService.hxx>
59 #include <Utils_ExceptHandlers.hxx>
60 #include <Utils_SINGLETON.hxx>
61 #include <utilities.h>
63 #include <GEOMImpl_Types.hxx>
64 #include <GEOM_wrap.hxx>
67 #include <BRep_Builder.hxx>
68 #include <OSD_Directory.hxx>
69 #include <OSD_File.hxx>
70 #include <OSD_Path.hxx>
71 #include <OSD_Protection.hxx>
72 #include <Standard_OutOfMemory.hxx>
73 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
74 #include <TColStd_MapOfInteger.hxx>
75 #include <TColStd_SequenceOfInteger.hxx>
76 #include <TCollection_AsciiString.hxx>
78 #include <TopExp_Explorer.hxx>
79 #include <TopTools_MapIteratorOfMapOfShape.hxx>
80 #include <TopTools_MapOfShape.hxx>
81 #include <TopoDS_Compound.hxx>
83 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
94 static int MYDEBUG = 0;
96 static int MYDEBUG = 0;
100 using SMESH::TPythonDump;
102 int SMESH_Mesh_i::_idGenerator = 0;
104 //=============================================================================
108 //=============================================================================
110 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
112 CORBA::Long studyId )
113 : SALOME::GenericObj_i( thePOA )
115 MESSAGE("SMESH_Mesh_i");
118 _id = _idGenerator++;
123 //=============================================================================
127 //=============================================================================
129 SMESH_Mesh_i::~SMESH_Mesh_i()
131 MESSAGE("~SMESH_Mesh_i");
134 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
135 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
136 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
138 // _impl->RemoveGroup() is called by ~SMESH_GroupBase_i() (PAL6331)
139 //_impl->RemoveGroup( aGroup->GetLocalID() );
140 aGroup->myMeshServant = 0;
141 aGroup->UnRegister();
146 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
147 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
148 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
150 aSubMesh->UnRegister();
152 _mapSubMeshIor.clear();
154 // destroy hypotheses
155 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
156 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ )
157 if ( SMESH_Hypothesis_i* aHypo = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
163 delete _impl; _impl = NULL;
164 delete _preMeshInfo; _preMeshInfo = NULL;
167 //=============================================================================
171 * Associates <this> mesh with <theShape> and puts a reference
172 * to <theShape> into the current study;
173 * the previous shape is substituted by the new one.
175 //=============================================================================
177 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
178 throw (SALOME::SALOME_Exception)
180 Unexpect aCatch(SALOME_SalomeException);
182 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
184 catch(SALOME_Exception & S_ex) {
185 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
187 // to track changes of GEOM groups
188 addGeomGroupData( theShapeObject, _this() );
191 //================================================================================
193 * \brief return true if mesh has a shape to build a shape on
195 //================================================================================
197 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
198 throw (SALOME::SALOME_Exception)
200 Unexpect aCatch(SALOME_SalomeException);
203 res = _impl->HasShapeToMesh();
205 catch(SALOME_Exception & S_ex) {
206 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
211 //=======================================================================
212 //function : GetShapeToMesh
214 //=======================================================================
216 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
217 throw (SALOME::SALOME_Exception)
219 Unexpect aCatch(SALOME_SalomeException);
220 GEOM::GEOM_Object_var aShapeObj;
222 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
224 aShapeObj = _gen_i->ShapeToGeomObject( S );
226 catch(SALOME_Exception & S_ex) {
227 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
229 return aShapeObj._retn();
232 //================================================================================
234 * \brief Return false if the mesh is not yet fully loaded from the study file
236 //================================================================================
238 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
240 Unexpect aCatch(SALOME_SalomeException);
241 return !_preMeshInfo;
244 //================================================================================
246 * \brief Load full mesh data from the study file
248 //================================================================================
250 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
252 Unexpect aCatch(SALOME_SalomeException);
254 _preMeshInfo->FullLoadFromFile();
257 //================================================================================
259 * \brief Remove all nodes and elements
261 //================================================================================
263 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
265 Unexpect aCatch(SALOME_SalomeException);
267 _preMeshInfo->ForgetAllData();
271 CheckGeomGroupModif(); // issue 20145
273 catch(SALOME_Exception & S_ex) {
274 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
276 _impl->GetMeshDS()->Modified();
278 TPythonDump() << _this() << ".Clear()";
281 //================================================================================
283 * \brief Remove all nodes and elements for indicated shape
285 //================================================================================
287 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
288 throw (SALOME::SALOME_Exception)
290 Unexpect aCatch(SALOME_SalomeException);
292 _preMeshInfo->FullLoadFromFile();
295 _impl->ClearSubMesh( ShapeID );
297 catch(SALOME_Exception & S_ex) {
298 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
300 _impl->GetMeshDS()->Modified();
302 TPythonDump() << _this() << ".ClearSubMesh( " << ShapeID << " )";
305 //=============================================================================
307 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
309 //=============================================================================
311 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
313 SMESH::DriverMED_ReadStatus res;
316 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
317 res = SMESH::DRS_OK; break;
318 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
319 res = SMESH::DRS_EMPTY; break;
320 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
321 res = SMESH::DRS_WARN_RENUMBER; break;
322 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
323 res = SMESH::DRS_WARN_SKIP_ELEM; break;
324 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
325 res = SMESH::DRS_WARN_DESCENDING; break;
326 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
328 res = SMESH::DRS_FAIL; break;
333 //=============================================================================
335 * Convert ::SMESH_ComputeError to SMESH::ComputeError
337 //=============================================================================
339 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
341 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
342 errVar->subShapeID = -1;
343 errVar->hasBadMesh = false;
345 if ( !errorPtr || errorPtr->IsOK() )
347 errVar->code = SMESH::COMPERR_OK;
351 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
352 errVar->comment = errorPtr->myComment.c_str();
354 return errVar._retn();
357 //=============================================================================
361 * Imports mesh data from MED file
363 //=============================================================================
365 SMESH::DriverMED_ReadStatus
366 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
367 throw ( SALOME::SALOME_Exception )
369 Unexpect aCatch(SALOME_SalomeException);
372 status = _impl->MEDToMesh( theFileName, theMeshName );
374 catch( SALOME_Exception& S_ex ) {
375 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
378 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
381 CreateGroupServants();
383 int major, minor, release;
384 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
385 major = minor = release = -1;
386 _medFileInfo = new SALOME_MED::MedFileInfo();
387 _medFileInfo->fileName = theFileName;
388 _medFileInfo->fileSize = 0;
391 if ( ::_stati64( theFileName, &d ) != -1 )
394 if ( ::stat64( theFileName, &d ) != -1 )
396 _medFileInfo->fileSize = d.st_size;
397 _medFileInfo->major = major;
398 _medFileInfo->minor = minor;
399 _medFileInfo->release = release;
401 return ConvertDriverMEDReadStatus(status);
404 //================================================================================
406 * \brief Imports mesh data from the CGNS file
408 //================================================================================
410 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
411 const int theMeshIndex,
412 std::string& theMeshName )
413 throw ( SALOME::SALOME_Exception )
415 Unexpect aCatch(SALOME_SalomeException);
418 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
420 catch( SALOME_Exception& S_ex ) {
421 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
424 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
427 CreateGroupServants();
429 return ConvertDriverMEDReadStatus(status);
432 //================================================================================
434 * \brief Return string representation of a MED file version comprising nbDigits
436 //================================================================================
438 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
440 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
442 return CORBA::string_dup( ver.c_str() );
445 //=============================================================================
449 * Imports mesh data from MED file
451 //=============================================================================
453 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
454 throw ( SALOME::SALOME_Exception )
458 // Read mesh with name = <theMeshName> into SMESH_Mesh
459 _impl->UNVToMesh( theFileName );
461 CreateGroupServants();
463 SMESH_CATCH( SMESH::throwCorbaException );
468 //=============================================================================
472 * Imports mesh data from STL file
474 //=============================================================================
475 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
476 throw ( SALOME::SALOME_Exception )
480 // Read mesh with name = <theMeshName> into SMESH_Mesh
481 _impl->STLToMesh( theFileName );
483 SMESH_CATCH( SMESH::throwCorbaException );
488 //================================================================================
490 * \brief Function used in SMESH_CATCH by ImportGMFFile()
492 //================================================================================
496 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
498 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
502 //================================================================================
504 * \brief Imports data from a GMF file and returns an error description
506 //================================================================================
508 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
509 bool theMakeRequiredGroups )
510 throw (SALOME::SALOME_Exception)
512 SMESH_ComputeErrorPtr error;
515 #define SMESH_CAUGHT error =
518 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
520 SMESH_CATCH( exceptionToComputeError );
524 CreateGroupServants();
526 return ConvertComputeError( error );
529 //=============================================================================
533 //=============================================================================
535 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
537 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
538 (SMESH_Hypothesis::Hypothesis_Status theStatus)
541 RETURNCASE( HYP_OK );
542 RETURNCASE( HYP_MISSING );
543 RETURNCASE( HYP_CONCURENT );
544 RETURNCASE( HYP_BAD_PARAMETER );
545 RETURNCASE( HYP_HIDDEN_ALGO );
546 RETURNCASE( HYP_HIDING_ALGO );
547 RETURNCASE( HYP_UNKNOWN_FATAL );
548 RETURNCASE( HYP_INCOMPATIBLE );
549 RETURNCASE( HYP_NOTCONFORM );
550 RETURNCASE( HYP_ALREADY_EXIST );
551 RETURNCASE( HYP_BAD_DIM );
552 RETURNCASE( HYP_BAD_SUBSHAPE );
553 RETURNCASE( HYP_BAD_GEOMETRY );
554 RETURNCASE( HYP_NEED_SHAPE );
557 return SMESH::HYP_UNKNOWN_FATAL;
560 //=============================================================================
564 * calls internal addHypothesis() and then adds a reference to <anHyp> under
565 * the SObject actually having a reference to <aSubShape>.
566 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
568 //=============================================================================
570 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
571 SMESH::SMESH_Hypothesis_ptr anHyp)
572 throw(SALOME::SALOME_Exception)
574 Unexpect aCatch(SALOME_SalomeException);
576 _preMeshInfo->ForgetOrLoad();
578 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
580 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
581 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
582 aSubShapeObject, anHyp );
584 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
586 // Update Python script
587 //if(_impl->HasShapeToMesh()) {
588 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
589 << aSubShapeObject << ", " << anHyp << " )";
592 // TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
595 return ConvertHypothesisStatus(status);
598 //=============================================================================
602 //=============================================================================
604 SMESH_Hypothesis::Hypothesis_Status
605 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
606 SMESH::SMESH_Hypothesis_ptr anHyp)
608 if(MYDEBUG) MESSAGE("addHypothesis");
610 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
611 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
614 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
615 if (CORBA::is_nil(myHyp))
616 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
619 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
622 TopoDS_Shape myLocSubShape;
623 //use PseudoShape in case if mesh has no shape
625 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
627 myLocSubShape = _impl->GetShapeToMesh();
629 int hypId = myHyp->GetId();
630 status = _impl->AddHypothesis(myLocSubShape, hypId);
631 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
632 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
633 _mapHypo[hypId]->Register();
634 // assure there is a corresponding submesh
635 if ( !_impl->IsMainShape( myLocSubShape )) {
636 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
637 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
638 createSubMesh( aSubShapeObject );
642 catch(SALOME_Exception & S_ex)
644 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
649 //=============================================================================
653 //=============================================================================
655 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
656 SMESH::SMESH_Hypothesis_ptr anHyp)
657 throw(SALOME::SALOME_Exception)
659 Unexpect aCatch(SALOME_SalomeException);
661 _preMeshInfo->ForgetOrLoad();
663 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
665 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
666 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
667 aSubShapeObject, anHyp );
669 // Update Python script
670 // Update Python script
671 if(_impl->HasShapeToMesh()) {
672 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
673 << aSubShapeObject << ", " << anHyp << " )";
676 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
680 return ConvertHypothesisStatus(status);
683 //=============================================================================
687 //=============================================================================
689 SMESH_Hypothesis::Hypothesis_Status
690 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
691 SMESH::SMESH_Hypothesis_ptr anHyp)
693 if(MYDEBUG) MESSAGE("removeHypothesis()");
694 // **** proposer liste de sub-shape (selection multiple)
696 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
697 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
699 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
700 if (CORBA::is_nil(myHyp))
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
709 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
711 myLocSubShape = _impl->GetShapeToMesh();
713 int hypId = myHyp->GetId();
714 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
715 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
716 // _mapHypo.erase( hypId );
718 catch(SALOME_Exception & S_ex)
720 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
725 //=============================================================================
729 //=============================================================================
731 SMESH::ListOfHypothesis *
732 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
733 throw(SALOME::SALOME_Exception)
735 Unexpect aCatch(SALOME_SalomeException);
736 if (MYDEBUG) MESSAGE("GetHypothesisList");
737 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
738 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
740 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
743 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
744 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
745 myLocSubShape = _impl->GetShapeToMesh();
746 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
747 int i = 0, n = aLocalList.size();
750 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
751 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
752 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
753 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
758 catch(SALOME_Exception & S_ex) {
759 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
762 return aList._retn();
765 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
767 Unexpect aCatch(SALOME_SalomeException);
768 if (MYDEBUG) MESSAGE("GetSubMeshes");
770 SMESH::submesh_array_var aList = new SMESH::submesh_array();
773 TPythonDump aPythonDump;
774 if ( !_mapSubMeshIor.empty() )
778 aList->length( _mapSubMeshIor.size() );
780 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
781 for ( ; it != _mapSubMeshIor.end(); it++ ) {
782 if ( CORBA::is_nil( it->second )) continue;
783 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
785 if (i > 1) aPythonDump << ", ";
786 aPythonDump << it->second;
790 catch(SALOME_Exception & S_ex) {
791 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
794 // Update Python script
795 if ( !_mapSubMeshIor.empty() )
796 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
798 return aList._retn();
801 //=============================================================================
805 //=============================================================================
806 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
807 const char* theName )
808 throw(SALOME::SALOME_Exception)
810 Unexpect aCatch(SALOME_SalomeException);
811 MESSAGE("SMESH_Mesh_i::GetSubMesh");
812 if (CORBA::is_nil(aSubShapeObject))
813 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
816 SMESH::SMESH_subMesh_var subMesh;
817 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
819 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
821 //Get or Create the SMESH_subMesh object implementation
823 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
825 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
827 TopoDS_Iterator it( myLocSubShape );
829 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
831 subMesh = getSubMesh( subMeshId );
833 // create a new subMesh object servant if there is none for the shape
834 if ( subMesh->_is_nil() )
835 subMesh = createSubMesh( aSubShapeObject );
836 if ( _gen_i->CanPublishInStudy( subMesh )) {
837 SALOMEDS::SObject_wrap aSO =
838 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
839 subMesh, aSubShapeObject, theName );
840 if ( !aSO->_is_nil()) {
841 // Update Python script
842 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
843 << aSubShapeObject << ", '" << theName << "' )";
847 catch(SALOME_Exception & S_ex) {
848 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
850 return subMesh._retn();
853 //=============================================================================
857 //=============================================================================
859 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
860 throw (SALOME::SALOME_Exception)
864 if ( theSubMesh->_is_nil() )
867 GEOM::GEOM_Object_var aSubShapeObject;
868 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
869 if ( !aStudy->_is_nil() ) {
870 // Remove submesh's SObject
871 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
872 if ( !anSO->_is_nil() ) {
873 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
874 SALOMEDS::SObject_wrap anObj, aRef;
875 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
876 anObj->ReferencedObject( aRef.inout() ))
878 CORBA::Object_var obj = aRef->GetObject();
879 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
881 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
882 // aSubShapeObject = theSubMesh->GetSubShape();
884 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
885 builder->RemoveObjectWithChildren( anSO );
887 // Update Python script
888 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
892 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
894 _preMeshInfo->ForgetOrLoad();
896 SMESH_CATCH( SMESH::throwCorbaException );
899 //=============================================================================
903 //=============================================================================
905 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
906 const char* theName )
907 throw(SALOME::SALOME_Exception)
909 Unexpect aCatch(SALOME_SalomeException);
911 _preMeshInfo->FullLoadFromFile();
913 SMESH::SMESH_Group_var aNewGroup =
914 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
916 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
917 SALOMEDS::SObject_wrap aSO =
918 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
919 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
920 if ( !aSO->_is_nil()) {
921 // Update Python script
922 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
923 << theElemType << ", '" << theName << "' )";
926 return aNewGroup._retn();
930 //=============================================================================
934 //=============================================================================
935 SMESH::SMESH_GroupOnGeom_ptr
936 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
938 GEOM::GEOM_Object_ptr theGeomObj)
939 throw(SALOME::SALOME_Exception)
941 Unexpect aCatch(SALOME_SalomeException);
943 _preMeshInfo->FullLoadFromFile();
945 SMESH::SMESH_GroupOnGeom_var aNewGroup;
947 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
948 if ( !aShape.IsNull() )
950 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
951 ( createGroup( theElemType, theName, aShape ));
953 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
954 SALOMEDS::SObject_wrap aSO =
955 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
956 aNewGroup, theGeomObj, theName);
957 if ( !aSO->_is_nil()) {
958 // Update Python script
959 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
960 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
965 return aNewGroup._retn();
968 //================================================================================
970 * \brief Creates a group whose contents is defined by filter
971 * \param theElemType - group type
972 * \param theName - group name
973 * \param theFilter - the filter
974 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
976 //================================================================================
978 SMESH::SMESH_GroupOnFilter_ptr
979 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
981 SMESH::Filter_ptr theFilter )
982 throw (SALOME::SALOME_Exception)
984 Unexpect aCatch(SALOME_SalomeException);
986 _preMeshInfo->FullLoadFromFile();
988 if ( CORBA::is_nil( theFilter ))
989 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
991 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
993 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
995 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
996 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
999 if ( !aNewGroup->_is_nil() )
1000 aNewGroup->SetFilter( theFilter );
1002 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1004 SALOMEDS::SObject_wrap aSO =
1005 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
1006 GEOM::GEOM_Object::_nil(), theName);
1007 if ( !aSO->_is_nil()) {
1008 // Update Python script
1009 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
1010 << theElemType << ", '" << theName << "', " << theFilter << " )";
1014 return aNewGroup._retn();
1017 //=============================================================================
1021 //=============================================================================
1023 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1024 throw (SALOME::SALOME_Exception)
1026 if ( theGroup->_is_nil() )
1031 SMESH_GroupBase_i* aGroup =
1032 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1036 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1037 if ( !aStudy->_is_nil() ) {
1038 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1040 if ( !aGroupSO->_is_nil() ) {
1041 // Update Python script
1042 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
1044 // Remove group's SObject
1045 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1046 builder->RemoveObjectWithChildren( aGroupSO );
1050 // Remove the group from SMESH data structures
1051 removeGroup( aGroup->GetLocalID() );
1053 SMESH_CATCH( SMESH::throwCorbaException );
1056 //=============================================================================
1058 * Remove group with its contents
1060 //=============================================================================
1062 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1063 throw (SALOME::SALOME_Exception)
1067 _preMeshInfo->FullLoadFromFile();
1069 if ( theGroup->_is_nil() )
1072 SMESH_GroupBase_i* aGroup =
1073 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1077 SMESH::long_array_var anIds = aGroup->GetListOfID();
1078 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
1080 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
1083 if ( aGroup->GetType() == SMESH::NODE )
1084 aMeshEditor->RemoveNodes( anIds );
1086 aMeshEditor->RemoveElements( anIds );
1088 // Update Python script (theGroup must be alive for this)
1089 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
1092 RemoveGroup( theGroup );
1094 SMESH_CATCH( SMESH::throwCorbaException );
1097 //================================================================================
1099 * \brief Get the list of groups existing in the mesh
1100 * \retval SMESH::ListOfGroups * - list of groups
1102 //================================================================================
1104 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1106 Unexpect aCatch(SALOME_SalomeException);
1107 if (MYDEBUG) MESSAGE("GetGroups");
1109 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1112 TPythonDump aPythonDump;
1113 if ( !_mapGroups.empty() )
1115 aPythonDump << "[ ";
1117 aList->length( _mapGroups.size() );
1119 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1120 for ( ; it != _mapGroups.end(); it++ ) {
1121 if ( CORBA::is_nil( it->second )) continue;
1122 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1124 if (i > 1) aPythonDump << ", ";
1125 aPythonDump << it->second;
1129 catch(SALOME_Exception & S_ex) {
1130 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1132 aPythonDump << " ] = " << _this() << ".GetGroups()";
1134 return aList._retn();
1137 //=============================================================================
1139 * Get number of groups existing in the mesh
1141 //=============================================================================
1143 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1145 Unexpect aCatch(SALOME_SalomeException);
1146 return _mapGroups.size();
1149 //=============================================================================
1151 * New group is created. All mesh elements that are
1152 * present in initial groups are added to the new one
1154 //=============================================================================
1155 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1156 SMESH::SMESH_GroupBase_ptr theGroup2,
1157 const char* theName )
1158 throw (SALOME::SALOME_Exception)
1160 SMESH::SMESH_Group_var aResGrp;
1164 _preMeshInfo->FullLoadFromFile();
1166 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1167 theGroup1->GetType() != theGroup2->GetType() )
1168 return SMESH::SMESH_Group::_nil();
1173 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1174 if ( aResGrp->_is_nil() )
1175 return SMESH::SMESH_Group::_nil();
1177 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1178 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1180 TColStd_MapOfInteger aResMap;
1182 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1183 aResMap.Add( anIds1[ i1 ] );
1185 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1186 aResMap.Add( anIds2[ i2 ] );
1188 SMESH::long_array_var aResIds = new SMESH::long_array;
1189 aResIds->length( aResMap.Extent() );
1192 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1193 for( ; anIter.More(); anIter.Next() )
1194 aResIds[ resI++ ] = anIter.Key();
1196 aResGrp->Add( aResIds );
1198 // Update Python script
1199 pyDump << aResGrp << " = " << _this() << ".UnionGroups( "
1200 << theGroup1 << ", " << theGroup2 << ", '"
1201 << theName << "' )";
1203 SMESH_CATCH( SMESH::throwCorbaException );
1205 return aResGrp._retn();
1208 //=============================================================================
1210 \brief Union list of groups. New group is created. All mesh elements that are
1211 present in initial groups are added to the new one.
1212 \param theGroups list of groups
1213 \param theName name of group to be created
1214 \return pointer on the group
1216 //=============================================================================
1217 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1218 const char* theName )
1219 throw (SALOME::SALOME_Exception)
1222 _preMeshInfo->FullLoadFromFile();
1225 return SMESH::SMESH_Group::_nil();
1227 SMESH::SMESH_Group_var aResGrp;
1231 vector< int > anIds;
1232 SMESH::ElementType aType = SMESH::ALL;
1233 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1235 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1236 if ( CORBA::is_nil( aGrp ) )
1240 SMESH::ElementType aCurrType = aGrp->GetType();
1241 if ( aType == SMESH::ALL )
1245 if ( aType != aCurrType )
1246 return SMESH::SMESH_Group::_nil();
1250 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1251 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1253 int aCurrId = aCurrIds[ i ];
1254 anIds.push_back( aCurrId );
1261 aResGrp = CreateGroup( aType, theName );
1262 if ( aResGrp->_is_nil() )
1263 return SMESH::SMESH_Group::_nil();
1265 // Create array of identifiers
1266 SMESH::long_array_var aResIds = new SMESH::long_array;
1267 aResIds->length( anIds.size() );
1269 for ( size_t i = 0; i<anIds.size(); i++ )
1270 aResIds[ i ] = anIds[i];
1271 aResGrp->Add( aResIds );
1273 // Update Python script
1274 pyDump << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1275 << &theGroups << ", '" << theName << "' )";
1277 SMESH_CATCH( SMESH::throwCorbaException );
1279 return aResGrp._retn();
1282 //=============================================================================
1284 * New group is created. All mesh elements that are
1285 * present in both initial groups are added to the new one.
1287 //=============================================================================
1288 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1289 SMESH::SMESH_GroupBase_ptr theGroup2,
1290 const char* theName )
1291 throw (SALOME::SALOME_Exception)
1293 SMESH::SMESH_Group_var aResGrp;
1297 _preMeshInfo->FullLoadFromFile();
1299 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1300 theGroup1->GetType() != theGroup2->GetType() )
1301 return SMESH::SMESH_Group::_nil();
1305 // Create Intersection
1306 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1307 if ( aResGrp->_is_nil() )
1310 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1311 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1313 TColStd_MapOfInteger aMap1;
1315 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1316 aMap1.Add( anIds1[ i1 ] );
1318 TColStd_SequenceOfInteger aSeq;
1319 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1320 if ( aMap1.Contains( anIds2[ i2 ] ) )
1321 aSeq.Append( anIds2[ i2 ] );
1323 SMESH::long_array_var aResIds = new SMESH::long_array;
1324 aResIds->length( aSeq.Length() );
1325 for ( size_t resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1326 aResIds[ resI ] = aSeq( resI + 1 );
1327 aResGrp->Add( aResIds );
1329 // Update Python script
1330 pyDump << aResGrp << " = " << _this() << ".IntersectGroups( "
1331 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1333 SMESH_CATCH( SMESH::throwCorbaException );
1335 return aResGrp._retn();
1338 //=============================================================================
1340 \brief Intersect list of groups. New group is created. All mesh elements that
1341 are present in all initial groups simultaneously are added to the new one.
1342 \param theGroups list of groups
1343 \param theName name of group to be created
1344 \return pointer on the group
1346 //=============================================================================
1347 SMESH::SMESH_Group_ptr
1348 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1349 const char* theName )
1350 throw (SALOME::SALOME_Exception)
1352 SMESH::SMESH_Group_var aResGrp;
1356 _preMeshInfo->FullLoadFromFile();
1359 return SMESH::SMESH_Group::_nil();
1361 NCollection_DataMap< int, int > anIdToCount;
1362 SMESH::ElementType aType = SMESH::ALL;
1363 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1365 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1366 if ( CORBA::is_nil( aGrp ) )
1370 SMESH::ElementType aCurrType = aGrp->GetType();
1371 if ( aType == SMESH::ALL )
1375 if ( aType != aCurrType )
1376 return SMESH::SMESH_Group::_nil();
1379 // calculates number of occurance ids in groups
1380 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1381 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1383 int aCurrId = aCurrIds[ i ];
1384 if ( !anIdToCount.IsBound( aCurrId ) )
1385 anIdToCount.Bind( aCurrId, 1 );
1387 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1391 // create map of ids
1392 int nbGrp = theGroups.length();
1393 vector< int > anIds;
1394 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1395 for ( ; anIter.More(); anIter.Next() )
1397 int aCurrId = anIter.Key();
1398 int aCurrNb = anIter.Value();
1399 if ( aCurrNb == nbGrp )
1400 anIds.push_back( aCurrId );
1406 aResGrp = CreateGroup( aType, theName );
1407 if ( aResGrp->_is_nil() )
1408 return SMESH::SMESH_Group::_nil();
1410 // Create array of identifiers
1411 SMESH::long_array_var aResIds = new SMESH::long_array;
1412 aResIds->length( anIds.size() );
1414 for ( size_t i = 0; i<anIds.size(); i++ )
1415 aResIds[ i ] = anIds[i];
1416 aResGrp->Add( aResIds );
1418 // Update Python script
1419 pyDump << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1420 << &theGroups << ", '" << theName << "' )";
1422 SMESH_CATCH( SMESH::throwCorbaException );
1424 return aResGrp._retn();
1427 //=============================================================================
1429 * New group is created. All mesh elements that are present in
1430 * main group but do not present in tool group are added to the new one
1432 //=============================================================================
1433 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1434 SMESH::SMESH_GroupBase_ptr theGroup2,
1435 const char* theName )
1436 throw (SALOME::SALOME_Exception)
1438 SMESH::SMESH_Group_var aResGrp;
1442 _preMeshInfo->FullLoadFromFile();
1444 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1445 theGroup1->GetType() != theGroup2->GetType() )
1446 return SMESH::SMESH_Group::_nil();
1451 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1452 if ( aResGrp->_is_nil() )
1455 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1456 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1458 TColStd_MapOfInteger aMap2;
1460 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1461 aMap2.Add( anIds2[ i2 ] );
1463 TColStd_SequenceOfInteger aSeq;
1464 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1465 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1466 aSeq.Append( anIds1[ i1 ] );
1468 SMESH::long_array_var aResIds = new SMESH::long_array;
1469 aResIds->length( aSeq.Length() );
1471 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1472 aResIds[ resI ] = aSeq( resI + 1 );
1473 aResGrp->Add( aResIds );
1475 // Update Python script
1476 pyDump << aResGrp << " = " << _this() << ".CutGroups( "
1477 << theGroup1 << ", " << theGroup2 << ", '"
1478 << theName << "' )";
1480 SMESH_CATCH( SMESH::throwCorbaException );
1482 return aResGrp._retn();
1485 //=============================================================================
1487 \brief Cut lists of groups. New group is created. All mesh elements that are
1488 present in main groups but do not present in tool groups are added to the new one
1489 \param theMainGroups list of main groups
1490 \param theToolGroups list of tool groups
1491 \param theName name of group to be created
1492 \return pointer on the group
1494 //=============================================================================
1495 SMESH::SMESH_Group_ptr
1496 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1497 const SMESH::ListOfGroups& theToolGroups,
1498 const char* theName )
1499 throw (SALOME::SALOME_Exception)
1501 SMESH::SMESH_Group_var aResGrp;
1505 _preMeshInfo->FullLoadFromFile();
1508 return SMESH::SMESH_Group::_nil();
1510 set< int > aToolIds;
1511 SMESH::ElementType aType = SMESH::ALL;
1513 // iterate through tool groups
1514 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1516 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1517 if ( CORBA::is_nil( aGrp ) )
1521 SMESH::ElementType aCurrType = aGrp->GetType();
1522 if ( aType == SMESH::ALL )
1526 if ( aType != aCurrType )
1527 return SMESH::SMESH_Group::_nil();
1531 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1532 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1534 int aCurrId = aCurrIds[ i ];
1535 aToolIds.insert( aCurrId );
1539 vector< int > anIds; // result
1541 // Iterate through main group
1542 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1544 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1545 if ( CORBA::is_nil( aGrp ) )
1549 SMESH::ElementType aCurrType = aGrp->GetType();
1550 if ( aType == SMESH::ALL )
1554 if ( aType != aCurrType )
1555 return SMESH::SMESH_Group::_nil();
1559 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1560 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1562 int aCurrId = aCurrIds[ i ];
1563 if ( !aToolIds.count( aCurrId ) )
1564 anIds.push_back( aCurrId );
1571 aResGrp = CreateGroup( aType, theName );
1572 if ( aResGrp->_is_nil() )
1573 return SMESH::SMESH_Group::_nil();
1575 // Create array of identifiers
1576 SMESH::long_array_var aResIds = new SMESH::long_array;
1577 aResIds->length( anIds.size() );
1579 for (int i=0; i<anIds.size(); i++ )
1580 aResIds[ i ] = anIds[i];
1581 aResGrp->Add( aResIds );
1583 // Update Python script
1584 pyDump << aResGrp << " = " << _this() << ".CutListOfGroups( "
1585 << &theMainGroups << ", " << &theToolGroups << ", '"
1586 << theName << "' )";
1588 SMESH_CATCH( SMESH::throwCorbaException );
1590 return aResGrp._retn();
1593 //=============================================================================
1595 \brief Create groups of entities from existing groups of superior dimensions
1597 1) extract all nodes from each group,
1598 2) combine all elements of specified dimension laying on these nodes.
1599 \param theGroups list of source groups
1600 \param theElemType dimension of elements
1601 \param theName name of new group
1602 \return pointer on new group
1606 //=============================================================================
1608 SMESH::SMESH_Group_ptr
1609 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1610 SMESH::ElementType theElemType,
1611 const char* theName )
1612 throw (SALOME::SALOME_Exception)
1614 SMESH::SMESH_Group_var aResGrp;
1618 _preMeshInfo->FullLoadFromFile();
1620 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1622 if ( !theName || !aMeshDS )
1623 return SMESH::SMESH_Group::_nil();
1625 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1631 aResGrp = CreateGroup( theElemType, theName );
1632 if ( aResGrp->_is_nil() )
1633 return SMESH::SMESH_Group::_nil();
1635 SMESHDS_GroupBase* groupBaseDS =
1636 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1637 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1639 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1641 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1642 if ( CORBA::is_nil( aGrp ) )
1645 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1646 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1648 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1650 while ( elIt->more() ) {
1651 const SMDS_MeshElement* el = elIt->next();
1652 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1653 while ( nIt->more() )
1654 resGroupCore.Add( nIt->next() );
1657 else // get elements of theElemType based on nodes of every element of group
1659 while ( elIt->more() )
1661 const SMDS_MeshElement* el = elIt->next(); // an element of group
1662 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1663 TIDSortedElemSet checkedElems;
1664 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1665 while ( nIt->more() )
1667 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1668 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1669 // check nodes of elements of theElemType around el
1670 while ( elOfTypeIt->more() )
1672 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1673 if ( !checkedElems.insert( elOfType ).second ) continue;
1675 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1676 bool allNodesOK = true;
1677 while ( nIt2->more() && allNodesOK )
1678 allNodesOK = elNodes.count( nIt2->next() );
1680 resGroupCore.Add( elOfType );
1687 // Update Python script
1688 pyDump << aResGrp << " = " << _this() << ".CreateDimGroup( "
1689 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1691 SMESH_CATCH( SMESH::throwCorbaException );
1693 return aResGrp._retn();
1696 //================================================================================
1698 * \brief Remember GEOM group data
1700 //================================================================================
1702 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1703 CORBA::Object_ptr theSmeshObj)
1705 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1708 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1709 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1710 if ( groupSO->_is_nil() )
1713 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1714 GEOM::GEOM_IGroupOperations_wrap groupOp =
1715 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1716 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1719 _geomGroupData.push_back( TGeomGroupData() );
1720 TGeomGroupData & groupData = _geomGroupData.back();
1722 CORBA::String_var entry = groupSO->GetID();
1723 groupData._groupEntry = entry.in();
1725 for ( int i = 0; i < ids->length(); ++i )
1726 groupData._indices.insert( ids[i] );
1728 groupData._smeshObject = theSmeshObj;
1731 //================================================================================
1733 * Remove GEOM group data relating to removed smesh object
1735 //================================================================================
1737 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1739 list<TGeomGroupData>::iterator
1740 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1741 for ( ; data != dataEnd; ++data ) {
1742 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1743 _geomGroupData.erase( data );
1749 //================================================================================
1751 * \brief Return new group contents if it has been changed and update group data
1753 //================================================================================
1755 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1757 TopoDS_Shape newShape;
1760 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1761 if ( study->_is_nil() ) return newShape; // means "not changed"
1762 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1763 if ( !groupSO->_is_nil() )
1765 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1766 if ( CORBA::is_nil( groupObj )) return newShape;
1767 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1769 // get indices of group items
1770 set<int> curIndices;
1771 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1772 GEOM::GEOM_IGroupOperations_wrap groupOp =
1773 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1774 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1775 for ( int i = 0; i < ids->length(); ++i )
1776 curIndices.insert( ids[i] );
1778 if ( groupData._indices == curIndices )
1779 return newShape; // group not changed
1782 groupData._indices = curIndices;
1784 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1785 if ( !geomClient ) return newShape;
1786 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1787 geomClient->RemoveShapeFromBuffer( groupIOR );
1788 newShape = _gen_i->GeomObjectToShape( geomGroup );
1791 if ( newShape.IsNull() ) {
1792 // geom group becomes empty - return empty compound
1793 TopoDS_Compound compound;
1794 BRep_Builder().MakeCompound(compound);
1795 newShape = compound;
1802 //=============================================================================
1804 * \brief Storage of shape and index used in CheckGeomGroupModif()
1806 //=============================================================================
1807 struct TIndexedShape
1810 TopoDS_Shape _shape;
1811 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1814 //=============================================================================
1816 * \brief Update objects depending on changed geom groups
1818 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1819 * issue 0020210: Update of a smesh group after modification of the associated geom group
1821 //=============================================================================
1823 void SMESH_Mesh_i::CheckGeomGroupModif()
1825 if ( !_impl->HasShapeToMesh() ) return;
1827 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1828 if ( study->_is_nil() ) return;
1830 CORBA::Long nbEntities = NbNodes() + NbElements();
1832 // Check if group contents changed
1834 typedef map< string, TopoDS_Shape > TEntry2Geom;
1835 TEntry2Geom newGroupContents;
1837 list<TGeomGroupData>::iterator
1838 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1839 for ( ; data != dataEnd; ++data )
1841 pair< TEntry2Geom::iterator, bool > it_new =
1842 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1843 bool processedGroup = !it_new.second;
1844 TopoDS_Shape& newShape = it_new.first->second;
1845 if ( !processedGroup )
1846 newShape = newGroupShape( *data );
1847 if ( newShape.IsNull() )
1848 continue; // no changes
1851 _preMeshInfo->ForgetOrLoad();
1853 if ( processedGroup ) { // update group indices
1854 list<TGeomGroupData>::iterator data2 = data;
1855 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1856 data->_indices = data2->_indices;
1859 // Update SMESH objects according to new GEOM group contents
1861 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1862 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1864 int oldID = submesh->GetId();
1865 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1867 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1869 // update hypotheses
1870 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1871 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1872 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1874 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1875 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1877 // care of submeshes
1878 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1879 int newID = newSubmesh->GetId();
1880 if ( newID != oldID ) {
1881 _mapSubMesh [ newID ] = newSubmesh;
1882 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1883 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1884 _mapSubMesh. erase(oldID);
1885 _mapSubMesh_i. erase(oldID);
1886 _mapSubMeshIor.erase(oldID);
1887 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1892 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1893 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1894 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1896 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1898 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1899 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1900 ds->SetShape( newShape );
1905 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1906 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1908 // Remove groups and submeshes basing on removed sub-shapes
1910 TopTools_MapOfShape newShapeMap;
1911 TopoDS_Iterator shapeIt( newShape );
1912 for ( ; shapeIt.More(); shapeIt.Next() )
1913 newShapeMap.Add( shapeIt.Value() );
1915 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1916 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1918 if ( newShapeMap.Contains( shapeIt.Value() ))
1920 TopTools_IndexedMapOfShape oldShapeMap;
1921 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1922 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1924 const TopoDS_Shape& oldShape = oldShapeMap(i);
1925 int oldInd = meshDS->ShapeToIndex( oldShape );
1927 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1928 if ( i_smIor != _mapSubMeshIor.end() ) {
1929 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1932 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1933 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1935 // check if a group bases on oldInd shape
1936 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1937 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1938 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1939 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1941 RemoveGroup( i_grp->second ); // several groups can base on same shape
1942 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1947 // Reassign hypotheses and update groups after setting the new shape to mesh
1949 // collect anassigned hypotheses
1950 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1951 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1952 TShapeHypList assignedHyps;
1953 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1955 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1956 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1957 if ( !hyps.empty() ) {
1958 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1959 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1960 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1963 // collect shapes supporting groups
1964 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1965 TShapeTypeList groupData;
1966 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1967 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1968 for ( ; grIt != groups.end(); ++grIt )
1970 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1972 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1974 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1975 _impl->ShapeToMesh( newShape );
1977 // reassign hypotheses
1978 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1979 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1981 TIndexedShape& geom = indS_hyps->first;
1982 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1983 int oldID = geom._index;
1984 int newID = meshDS->ShapeToIndex( geom._shape );
1985 if ( oldID == 1 ) { // main shape
1987 geom._shape = newShape;
1991 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1992 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1993 // care of submeshes
1994 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1995 if ( newID != oldID ) {
1996 _mapSubMesh [ newID ] = newSubmesh;
1997 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1998 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1999 _mapSubMesh. erase(oldID);
2000 _mapSubMesh_i. erase(oldID);
2001 _mapSubMeshIor.erase(oldID);
2002 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2006 TShapeTypeList::iterator geomType = groupData.begin();
2007 for ( ; geomType != groupData.end(); ++geomType )
2009 const TIndexedShape& geom = geomType->first;
2010 int oldID = geom._index;
2011 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2014 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2015 CORBA::String_var name = groupSO->GetName();
2017 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2019 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2020 group_i->changeLocalId( newID );
2023 break; // everything has been updated
2026 } // loop on group data
2030 CORBA::Long newNbEntities = NbNodes() + NbElements();
2031 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2032 if ( newNbEntities != nbEntities )
2034 // Add all SObjects with icons to soToUpdateIcons
2035 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2037 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2038 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2039 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2041 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2042 i_gr != _mapGroups.end(); ++i_gr ) // groups
2043 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2046 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2047 for ( ; so != soToUpdateIcons.end(); ++so )
2048 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2051 //=============================================================================
2053 * \brief Create standalone group from a group on geometry or filter
2055 //=============================================================================
2057 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2058 throw (SALOME::SALOME_Exception)
2060 SMESH::SMESH_Group_var aGroup;
2065 _preMeshInfo->FullLoadFromFile();
2067 if ( theGroup->_is_nil() )
2068 return aGroup._retn();
2070 SMESH_GroupBase_i* aGroupToRem =
2071 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2073 return aGroup._retn();
2075 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2077 int anId = aGroupToRem->GetLocalID();
2078 if ( !_impl->ConvertToStandalone( anId ) )
2079 return aGroup._retn();
2080 removeGeomGroupData( theGroup );
2082 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2084 // remove old instance of group from own map
2085 _mapGroups.erase( anId );
2087 SALOMEDS::StudyBuilder_var builder;
2088 SALOMEDS::SObject_wrap aGroupSO;
2089 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2090 if ( !aStudy->_is_nil() ) {
2091 builder = aStudy->NewBuilder();
2092 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2093 if ( !aGroupSO->_is_nil() )
2095 // remove reference to geometry
2096 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2097 for ( ; chItr->More(); chItr->Next() )
2098 // Remove group's child SObject
2099 builder->RemoveObject( chItr->Value() );
2101 // Update Python script
2102 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2103 << aGroupSO << " )";
2105 // change icon of Group on Filter
2108 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2109 const int isEmpty = ( elemTypes->length() == 0 );
2112 SALOMEDS::GenericAttribute_wrap anAttr =
2113 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2114 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2115 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2121 // remember new group in own map
2122 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2123 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2125 // register CORBA object for persistence
2126 _gen_i->RegisterObject( aGroup );
2128 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2129 builder->SetIOR( aGroupSO, ior.in() );
2131 SMESH_CATCH( SMESH::throwCorbaException );
2133 return aGroup._retn();
2136 //=============================================================================
2140 //=============================================================================
2142 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2144 if(MYDEBUG) MESSAGE( "createSubMesh" );
2145 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2147 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2148 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2149 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2150 SMESH::SMESH_subMesh_var subMesh
2151 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2153 _mapSubMesh[subMeshId] = mySubMesh;
2154 _mapSubMesh_i[subMeshId] = subMeshServant;
2155 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2157 // register CORBA object for persistence
2158 int nextId = _gen_i->RegisterObject( subMesh );
2159 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2160 else { nextId = 0; } // avoid "unused variable" warning in release mode
2162 // to track changes of GEOM groups
2163 addGeomGroupData( theSubShapeObject, subMesh );
2165 return subMesh._retn();
2168 //=======================================================================
2169 //function : getSubMesh
2171 //=======================================================================
2173 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2175 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2176 if ( it == _mapSubMeshIor.end() )
2177 return SMESH::SMESH_subMesh::_nil();
2179 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2183 //=============================================================================
2187 //=============================================================================
2189 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2190 GEOM::GEOM_Object_ptr theSubShapeObject )
2192 bool isHypChanged = false;
2193 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2194 return isHypChanged;
2196 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2198 CORBA::Long shapeId = theSubMesh->GetId();
2199 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2201 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2204 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2205 isHypChanged = !hyps.empty();
2206 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2207 for ( ; hyp != hyps.end(); ++hyp )
2208 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2215 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2216 isHypChanged = ( aHypList->length() > 0 );
2217 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2218 removeHypothesis( theSubShapeObject, aHypList[i] );
2221 catch( const SALOME::SALOME_Exception& ) {
2222 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2224 removeGeomGroupData( theSubShapeObject );
2226 int subMeshId = theSubMesh->GetId();
2228 _mapSubMesh.erase(subMeshId);
2229 _mapSubMesh_i.erase(subMeshId);
2230 _mapSubMeshIor.erase(subMeshId);
2232 return isHypChanged;
2235 //=============================================================================
2239 //=============================================================================
2241 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2242 const char* theName,
2243 const TopoDS_Shape& theShape,
2244 const SMESH_PredicatePtr& thePredicate )
2246 std::string newName;
2247 if ( !theName || strlen( theName ) == 0 )
2249 std::set< std::string > presentNames;
2250 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2251 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2252 presentNames.insert( i_gr->second->GetName() );
2254 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2255 } while ( !presentNames.insert( newName ).second );
2256 theName = newName.c_str();
2259 SMESH::SMESH_GroupBase_var aGroup;
2260 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2262 SMESH_GroupBase_i* aGroupImpl;
2263 if ( !theShape.IsNull() )
2264 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2265 else if ( thePredicate )
2266 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2268 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2270 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2271 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2273 // register CORBA object for persistence
2274 int nextId = _gen_i->RegisterObject( aGroup );
2275 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2276 else { nextId = 0; } // avoid "unused variable" warning in release mode
2278 // to track changes of GEOM groups
2279 if ( !theShape.IsNull() ) {
2280 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2281 addGeomGroupData( geom, aGroup );
2284 return aGroup._retn();
2287 //=============================================================================
2289 * SMESH_Mesh_i::removeGroup
2291 * Should be called by ~SMESH_Group_i()
2293 //=============================================================================
2295 void SMESH_Mesh_i::removeGroup( const int theId )
2297 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2298 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2299 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2300 _mapGroups.erase( theId );
2301 removeGeomGroupData( group );
2302 if (! _impl->RemoveGroup( theId ))
2304 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2305 RemoveGroup( group );
2310 //=============================================================================
2314 //=============================================================================
2316 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2317 throw(SALOME::SALOME_Exception)
2319 SMESH::log_array_var aLog;
2323 _preMeshInfo->FullLoadFromFile();
2325 list < SMESHDS_Command * >logDS = _impl->GetLog();
2326 aLog = new SMESH::log_array;
2328 int lg = logDS.size();
2331 list < SMESHDS_Command * >::iterator its = logDS.begin();
2332 while(its != logDS.end()){
2333 SMESHDS_Command *com = *its;
2334 int comType = com->GetType();
2336 int lgcom = com->GetNumber();
2338 const list < int >&intList = com->GetIndexes();
2339 int inum = intList.size();
2341 list < int >::const_iterator ii = intList.begin();
2342 const list < double >&coordList = com->GetCoords();
2343 int rnum = coordList.size();
2345 list < double >::const_iterator ir = coordList.begin();
2346 aLog[indexLog].commandType = comType;
2347 aLog[indexLog].number = lgcom;
2348 aLog[indexLog].coords.length(rnum);
2349 aLog[indexLog].indexes.length(inum);
2350 for(int i = 0; i < rnum; i++){
2351 aLog[indexLog].coords[i] = *ir;
2352 //MESSAGE(" "<<i<<" "<<ir.Value());
2355 for(int i = 0; i < inum; i++){
2356 aLog[indexLog].indexes[i] = *ii;
2357 //MESSAGE(" "<<i<<" "<<ii.Value());
2366 SMESH_CATCH( SMESH::throwCorbaException );
2368 return aLog._retn();
2372 //=============================================================================
2376 //=============================================================================
2378 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2382 SMESH_CATCH( SMESH::throwCorbaException );
2385 //=============================================================================
2389 //=============================================================================
2391 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2396 //=============================================================================
2400 //=============================================================================
2402 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2407 //=============================================================================
2410 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2411 // issue 0020918: groups removal is caused by hyp modification
2412 // issue 0021208: to forget not loaded mesh data at hyp modification
2413 struct TCallUp_i : public SMESH_Mesh::TCallUp
2415 SMESH_Mesh_i* _mesh;
2416 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2417 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2418 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2419 virtual void Load () { _mesh->Load(); }
2423 //================================================================================
2425 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2427 //================================================================================
2429 void SMESH_Mesh_i::onHypothesisModified()
2432 _preMeshInfo->ForgetOrLoad();
2435 //=============================================================================
2439 //=============================================================================
2441 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2443 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2446 _impl->SetCallUp( new TCallUp_i(this));
2449 //=============================================================================
2453 //=============================================================================
2455 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2457 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2461 //=============================================================================
2463 * Return mesh editor
2465 //=============================================================================
2467 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2468 throw (SALOME::SALOME_Exception)
2470 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2474 _preMeshInfo->FullLoadFromFile();
2476 // Create MeshEditor
2477 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2478 aMeshEdVar = aMeshEditor->_this();
2480 // Update Python script
2481 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2483 SMESH_CATCH( SMESH::throwCorbaException );
2485 return aMeshEdVar._retn();
2488 //=============================================================================
2490 * Return mesh edition previewer
2492 //=============================================================================
2494 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2495 throw (SALOME::SALOME_Exception)
2497 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2501 _preMeshInfo->FullLoadFromFile();
2503 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2504 aMeshEdVar = aMeshEditor->_this();
2506 SMESH_CATCH( SMESH::throwCorbaException );
2508 return aMeshEdVar._retn();
2511 //================================================================================
2513 * \brief Return true if the mesh has been edited since a last total re-compute
2514 * and those modifications may prevent successful partial re-compute
2516 //================================================================================
2518 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2520 Unexpect aCatch(SALOME_SalomeException);
2521 return _impl->HasModificationsToDiscard();
2524 //================================================================================
2526 * \brief Returns a random unique color
2528 //================================================================================
2530 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2532 const int MAX_ATTEMPTS = 100;
2534 double tolerance = 0.5;
2535 SALOMEDS::Color col;
2539 // generate random color
2540 double red = (double)rand() / RAND_MAX;
2541 double green = (double)rand() / RAND_MAX;
2542 double blue = (double)rand() / RAND_MAX;
2543 // check existence in the list of the existing colors
2544 bool matched = false;
2545 std::list<SALOMEDS::Color>::const_iterator it;
2546 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2547 SALOMEDS::Color color = *it;
2548 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2549 matched = tol < tolerance;
2551 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2552 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2560 //=============================================================================
2562 * Sets auto-color mode. If it is on, groups get unique random colors
2564 //=============================================================================
2566 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2568 Unexpect aCatch(SALOME_SalomeException);
2569 _impl->SetAutoColor(theAutoColor);
2571 TPythonDump pyDump; // not to dump group->SetColor() from below code
2572 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2574 std::list<SALOMEDS::Color> aReservedColors;
2575 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2576 for ( ; it != _mapGroups.end(); it++ ) {
2577 if ( CORBA::is_nil( it->second )) continue;
2578 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2579 it->second->SetColor( aColor );
2580 aReservedColors.push_back( aColor );
2584 //=============================================================================
2586 * Returns true if auto-color mode is on
2588 //=============================================================================
2590 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2592 Unexpect aCatch(SALOME_SalomeException);
2593 return _impl->GetAutoColor();
2596 //=============================================================================
2598 * Checks if there are groups with equal names
2600 //=============================================================================
2602 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2604 return _impl->HasDuplicatedGroupNamesMED();
2607 //================================================================================
2609 * \brief Care of a file before exporting mesh into it
2611 //================================================================================
2613 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2615 TCollection_AsciiString aFullName ((char*)file);
2616 OSD_Path aPath (aFullName);
2617 OSD_File aFile (aPath);
2618 if (aFile.Exists()) {
2619 // existing filesystem node
2620 if (aFile.KindOfFile() == OSD_FILE) {
2621 if (aFile.IsWriteable()) {
2626 if (aFile.Failed()) {
2627 TCollection_AsciiString msg ("File ");
2628 msg += aFullName + " cannot be replaced.";
2629 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2632 TCollection_AsciiString msg ("File ");
2633 msg += aFullName + " cannot be overwritten.";
2634 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2637 TCollection_AsciiString msg ("Location ");
2638 msg += aFullName + " is not a file.";
2639 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2642 // nonexisting file; check if it can be created
2644 aFile.Build(OSD_WriteOnly, OSD_Protection());
2645 if (aFile.Failed()) {
2646 TCollection_AsciiString msg ("You cannot create the file ");
2647 msg += aFullName + ". Check the directory existance and access rights.";
2648 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2656 //================================================================================
2658 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2659 * \param file - file name
2660 * \param overwrite - to erase the file or not
2661 * \retval string - mesh name
2663 //================================================================================
2665 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2666 CORBA::Boolean overwrite)
2669 PrepareForWriting(file, overwrite);
2670 string aMeshName = "Mesh";
2671 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2672 if ( !aStudy->_is_nil() ) {
2673 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2674 if ( !aMeshSO->_is_nil() ) {
2675 CORBA::String_var name = aMeshSO->GetName();
2677 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2678 if ( !aStudy->GetProperties()->IsLocked() )
2680 SALOMEDS::GenericAttribute_wrap anAttr;
2681 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2682 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2683 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2684 ASSERT(!aFileName->_is_nil());
2685 aFileName->SetValue(file);
2686 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2687 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2688 ASSERT(!aFileType->_is_nil());
2689 aFileType->SetValue("FICHIERMED");
2693 // Update Python script
2694 // set name of mesh before export
2695 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2697 // check names of groups
2703 //================================================================================
2705 * \brief Export to med file
2707 //================================================================================
2709 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2710 CORBA::Boolean auto_groups,
2711 SMESH::MED_VERSION theVersion,
2712 CORBA::Boolean overwrite,
2713 CORBA::Boolean autoDimension)
2714 throw(SALOME::SALOME_Exception)
2716 Unexpect aCatch(SALOME_SalomeException);
2718 _preMeshInfo->FullLoadFromFile();
2720 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2721 TPythonDump() << _this() << ".ExportToMEDX( r'"
2722 << file << "', " << auto_groups << ", "
2723 << theVersion << ", " << overwrite << ", "
2724 << autoDimension << " )";
2726 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2729 //================================================================================
2731 * \brief Export a mesh to a med file
2733 //================================================================================
2735 void SMESH_Mesh_i::ExportToMED (const char* file,
2736 CORBA::Boolean auto_groups,
2737 SMESH::MED_VERSION theVersion)
2738 throw(SALOME::SALOME_Exception)
2740 ExportToMEDX(file,auto_groups,theVersion,true);
2743 //================================================================================
2745 * \brief Export a mesh to a med file
2747 //================================================================================
2749 void SMESH_Mesh_i::ExportMED (const char* file,
2750 CORBA::Boolean auto_groups)
2751 throw(SALOME::SALOME_Exception)
2753 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2756 //================================================================================
2758 * \brief Export a mesh to a SAUV file
2760 //================================================================================
2762 void SMESH_Mesh_i::ExportSAUV (const char* file,
2763 CORBA::Boolean auto_groups)
2764 throw(SALOME::SALOME_Exception)
2766 Unexpect aCatch(SALOME_SalomeException);
2768 _preMeshInfo->FullLoadFromFile();
2770 string aMeshName = prepareMeshNameAndGroups(file, true);
2771 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2772 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2776 //================================================================================
2778 * \brief Export a mesh to a DAT file
2780 //================================================================================
2782 void SMESH_Mesh_i::ExportDAT (const char *file)
2783 throw(SALOME::SALOME_Exception)
2785 Unexpect aCatch(SALOME_SalomeException);
2787 _preMeshInfo->FullLoadFromFile();
2789 // Update Python script
2790 // check names of groups
2792 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2795 PrepareForWriting(file);
2796 _impl->ExportDAT(file);
2799 //================================================================================
2801 * \brief Export a mesh to an UNV file
2803 //================================================================================
2805 void SMESH_Mesh_i::ExportUNV (const char *file)
2806 throw(SALOME::SALOME_Exception)
2808 Unexpect aCatch(SALOME_SalomeException);
2810 _preMeshInfo->FullLoadFromFile();
2812 // Update Python script
2813 // check names of groups
2815 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2818 PrepareForWriting(file);
2819 _impl->ExportUNV(file);
2822 //================================================================================
2824 * \brief Export a mesh to an STL file
2826 //================================================================================
2828 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2829 throw(SALOME::SALOME_Exception)
2831 Unexpect aCatch(SALOME_SalomeException);
2833 _preMeshInfo->FullLoadFromFile();
2835 // Update Python script
2836 // check names of groups
2838 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2841 PrepareForWriting(file);
2842 _impl->ExportSTL(file, isascii);
2845 //================================================================================
2847 * \brief Export a part of mesh to a med file
2849 //================================================================================
2851 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2853 CORBA::Boolean auto_groups,
2854 ::SMESH::MED_VERSION version,
2855 ::CORBA::Boolean overwrite,
2856 ::CORBA::Boolean autoDimension)
2857 throw (SALOME::SALOME_Exception)
2859 Unexpect aCatch(SALOME_SalomeException);
2862 if ( SMESH_Mesh_i * mesh = SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
2864 mesh->ExportToMEDX( file, auto_groups, version, autoDimension );
2869 _preMeshInfo->FullLoadFromFile();
2871 PrepareForWriting(file, overwrite);
2873 string aMeshName = "Mesh";
2874 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2875 if ( !aStudy->_is_nil() ) {
2876 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2877 if ( !SO->_is_nil() ) {
2878 CORBA::String_var name = SO->GetName();
2882 SMESH_MeshPartDS partDS( meshPart );
2883 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS, autoDimension );
2885 pyDump << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2886 << auto_groups << ", " << version << ", " << overwrite << ", "
2887 << autoDimension << " )";
2890 //================================================================================
2892 * \brief Export a part of mesh to a DAT file
2894 //================================================================================
2896 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2898 throw (SALOME::SALOME_Exception)
2900 Unexpect aCatch(SALOME_SalomeException);
2902 _preMeshInfo->FullLoadFromFile();
2904 PrepareForWriting(file);
2906 SMESH_MeshPartDS partDS( meshPart );
2907 _impl->ExportDAT(file,&partDS);
2909 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2911 //================================================================================
2913 * \brief Export a part of mesh to an UNV file
2915 //================================================================================
2917 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2919 throw (SALOME::SALOME_Exception)
2921 Unexpect aCatch(SALOME_SalomeException);
2923 _preMeshInfo->FullLoadFromFile();
2925 PrepareForWriting(file);
2927 SMESH_MeshPartDS partDS( meshPart );
2928 _impl->ExportUNV(file, &partDS);
2930 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2932 //================================================================================
2934 * \brief Export a part of mesh to an STL file
2936 //================================================================================
2938 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2940 ::CORBA::Boolean isascii)
2941 throw (SALOME::SALOME_Exception)
2943 Unexpect aCatch(SALOME_SalomeException);
2945 _preMeshInfo->FullLoadFromFile();
2947 PrepareForWriting(file);
2949 SMESH_MeshPartDS partDS( meshPart );
2950 _impl->ExportSTL(file, isascii, &partDS);
2952 TPythonDump() << _this() << ".ExportPartToSTL( "
2953 << meshPart<< ", r'" << file << "', " << isascii << ")";
2956 //================================================================================
2958 * \brief Export a part of mesh to an STL file
2960 //================================================================================
2962 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2964 CORBA::Boolean overwrite)
2965 throw (SALOME::SALOME_Exception)
2968 Unexpect aCatch(SALOME_SalomeException);
2970 _preMeshInfo->FullLoadFromFile();
2972 PrepareForWriting(file,overwrite);
2974 SMESH_MeshPartDS partDS( meshPart );
2975 _impl->ExportCGNS(file, &partDS);
2977 TPythonDump() << _this() << ".ExportCGNS( "
2978 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2980 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2984 //================================================================================
2986 * \brief Export a part of mesh to a GMF file
2988 //================================================================================
2990 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
2992 bool withRequiredGroups)
2993 throw (SALOME::SALOME_Exception)
2995 Unexpect aCatch(SALOME_SalomeException);
2997 _preMeshInfo->FullLoadFromFile();
2999 PrepareForWriting(file,/*overwrite=*/true);
3001 SMESH_MeshPartDS partDS( meshPart );
3002 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3004 TPythonDump() << _this() << ".ExportGMF( "
3005 << meshPart<< ", r'"
3007 << withRequiredGroups << ")";
3010 //=============================================================================
3012 * Return implementation of SALOME_MED::MESH interfaces
3014 //=============================================================================
3016 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
3018 Unexpect aCatch(SALOME_SalomeException);
3020 _preMeshInfo->FullLoadFromFile();
3022 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
3023 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
3024 return aMesh._retn();
3027 //=============================================================================
3029 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3031 Unexpect aCatch(SALOME_SalomeException);
3033 return _preMeshInfo->NbNodes();
3035 return _impl->NbNodes();
3038 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3040 Unexpect aCatch(SALOME_SalomeException);
3042 return _preMeshInfo->NbElements();
3044 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3047 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3049 Unexpect aCatch(SALOME_SalomeException);
3051 return _preMeshInfo->Nb0DElements();
3053 return _impl->Nb0DElements();
3056 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3058 Unexpect aCatch(SALOME_SalomeException);
3060 return _preMeshInfo->NbBalls();
3062 return _impl->NbBalls();
3065 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3067 Unexpect aCatch(SALOME_SalomeException);
3069 return _preMeshInfo->NbEdges();
3071 return _impl->NbEdges();
3074 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3075 throw(SALOME::SALOME_Exception)
3077 Unexpect aCatch(SALOME_SalomeException);
3079 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3081 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3084 //=============================================================================
3086 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3088 Unexpect aCatch(SALOME_SalomeException);
3090 return _preMeshInfo->NbFaces();
3092 return _impl->NbFaces();
3095 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3097 Unexpect aCatch(SALOME_SalomeException);
3099 return _preMeshInfo->NbTriangles();
3101 return _impl->NbTriangles();
3104 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3106 Unexpect aCatch(SALOME_SalomeException);
3108 return _preMeshInfo->NbBiQuadTriangles();
3110 return _impl->NbBiQuadTriangles();
3113 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3115 Unexpect aCatch(SALOME_SalomeException);
3117 return _preMeshInfo->NbQuadrangles();
3119 return _impl->NbQuadrangles();
3122 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3124 Unexpect aCatch(SALOME_SalomeException);
3126 return _preMeshInfo->NbBiQuadQuadrangles();
3128 return _impl->NbBiQuadQuadrangles();
3131 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3133 Unexpect aCatch(SALOME_SalomeException);
3135 return _preMeshInfo->NbPolygons();
3137 return _impl->NbPolygons();
3140 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3141 throw(SALOME::SALOME_Exception)
3143 Unexpect aCatch(SALOME_SalomeException);
3145 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3147 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3150 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3151 throw(SALOME::SALOME_Exception)
3153 Unexpect aCatch(SALOME_SalomeException);
3155 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3157 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3160 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3161 throw(SALOME::SALOME_Exception)
3163 Unexpect aCatch(SALOME_SalomeException);
3165 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3167 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3170 //=============================================================================
3172 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3174 Unexpect aCatch(SALOME_SalomeException);
3176 return _preMeshInfo->NbVolumes();
3178 return _impl->NbVolumes();
3181 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3183 Unexpect aCatch(SALOME_SalomeException);
3185 return _preMeshInfo->NbTetras();
3187 return _impl->NbTetras();
3190 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3192 Unexpect aCatch(SALOME_SalomeException);
3194 return _preMeshInfo->NbHexas();
3196 return _impl->NbHexas();
3199 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3201 Unexpect aCatch(SALOME_SalomeException);
3203 return _preMeshInfo->NbTriQuadHexas();
3205 return _impl->NbTriQuadraticHexas();
3208 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3210 Unexpect aCatch(SALOME_SalomeException);
3212 return _preMeshInfo->NbPyramids();
3214 return _impl->NbPyramids();
3217 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3219 Unexpect aCatch(SALOME_SalomeException);
3221 return _preMeshInfo->NbPrisms();
3223 return _impl->NbPrisms();
3226 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3228 Unexpect aCatch(SALOME_SalomeException);
3230 return _preMeshInfo->NbHexPrisms();
3232 return _impl->NbHexagonalPrisms();
3235 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3237 Unexpect aCatch(SALOME_SalomeException);
3239 return _preMeshInfo->NbPolyhedrons();
3241 return _impl->NbPolyhedrons();
3244 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3245 throw(SALOME::SALOME_Exception)
3247 Unexpect aCatch(SALOME_SalomeException);
3249 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3251 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3254 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3255 throw(SALOME::SALOME_Exception)
3257 Unexpect aCatch(SALOME_SalomeException);
3259 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3261 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3264 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3265 throw(SALOME::SALOME_Exception)
3267 Unexpect aCatch(SALOME_SalomeException);
3269 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3271 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3274 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3275 throw(SALOME::SALOME_Exception)
3277 Unexpect aCatch(SALOME_SalomeException);
3279 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3281 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3284 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3285 throw(SALOME::SALOME_Exception)
3287 Unexpect aCatch(SALOME_SalomeException);
3289 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3291 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3294 //=============================================================================
3296 * Returns nb of published sub-meshes
3298 //=============================================================================
3300 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3302 Unexpect aCatch(SALOME_SalomeException);
3303 return _mapSubMesh_i.size();
3306 //=============================================================================
3308 * Dumps mesh into a string
3310 //=============================================================================
3312 char* SMESH_Mesh_i::Dump()
3316 return CORBA::string_dup( os.str().c_str() );
3319 //=============================================================================
3321 * Method of SMESH_IDSource interface
3323 //=============================================================================
3325 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3327 return GetElementsId();
3330 //=============================================================================
3332 * Returns ids of all elements
3334 //=============================================================================
3336 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3337 throw (SALOME::SALOME_Exception)
3339 Unexpect aCatch(SALOME_SalomeException);
3341 _preMeshInfo->FullLoadFromFile();
3343 SMESH::long_array_var aResult = new SMESH::long_array();
3344 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3346 if ( aSMESHDS_Mesh == NULL )
3347 return aResult._retn();
3349 long nbElements = NbElements();
3350 aResult->length( nbElements );
3351 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3352 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3353 aResult[i] = anIt->next()->GetID();
3355 return aResult._retn();
3359 //=============================================================================
3361 * Returns ids of all elements of given type
3363 //=============================================================================
3365 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3366 throw (SALOME::SALOME_Exception)
3368 Unexpect aCatch(SALOME_SalomeException);
3370 _preMeshInfo->FullLoadFromFile();
3372 SMESH::long_array_var aResult = new SMESH::long_array();
3373 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3375 if ( aSMESHDS_Mesh == NULL )
3376 return aResult._retn();
3378 long nbElements = NbElements();
3380 // No sense in returning ids of elements along with ids of nodes:
3381 // when theElemType == SMESH::ALL, return node ids only if
3382 // there are no elements
3383 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3384 return GetNodesId();
3386 aResult->length( nbElements );
3390 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3391 while ( i < nbElements && anIt->more() ) {
3392 const SMDS_MeshElement* anElem = anIt->next();
3393 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3394 aResult[i++] = anElem->GetID();
3397 aResult->length( i );
3399 return aResult._retn();
3402 //=============================================================================
3404 * Returns ids of all nodes
3406 //=============================================================================
3408 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3409 throw (SALOME::SALOME_Exception)
3411 Unexpect aCatch(SALOME_SalomeException);
3413 _preMeshInfo->FullLoadFromFile();
3415 SMESH::long_array_var aResult = new SMESH::long_array();
3416 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3418 if ( aSMESHDS_Mesh == NULL )
3419 return aResult._retn();
3421 long nbNodes = NbNodes();
3422 aResult->length( nbNodes );
3423 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3424 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3425 aResult[i] = anIt->next()->GetID();
3427 return aResult._retn();
3430 //=============================================================================
3434 //=============================================================================
3436 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3437 throw (SALOME::SALOME_Exception)
3439 SMESH::ElementType type;
3443 _preMeshInfo->FullLoadFromFile();
3445 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3447 SMESH_CATCH( SMESH::throwCorbaException );
3452 //=============================================================================
3456 //=============================================================================
3458 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3459 throw (SALOME::SALOME_Exception)
3462 _preMeshInfo->FullLoadFromFile();
3464 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3466 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3468 return ( SMESH::EntityType ) e->GetEntityType();
3471 //=============================================================================
3473 * Returns ID of elements for given submesh
3475 //=============================================================================
3476 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3477 throw (SALOME::SALOME_Exception)
3479 SMESH::long_array_var aResult = new SMESH::long_array();
3483 _preMeshInfo->FullLoadFromFile();
3485 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3486 if(!SM) return aResult._retn();
3488 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3489 if(!SDSM) return aResult._retn();
3491 aResult->length(SDSM->NbElements());
3493 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3495 while ( eIt->more() ) {
3496 aResult[i++] = eIt->next()->GetID();
3499 SMESH_CATCH( SMESH::throwCorbaException );
3501 return aResult._retn();
3505 //=============================================================================
3507 * Returns ID of nodes for given submesh
3508 * If param all==true - returns all nodes, else -
3509 * returns only nodes on shapes.
3511 //=============================================================================
3512 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3514 throw (SALOME::SALOME_Exception)
3516 SMESH::long_array_var aResult = new SMESH::long_array();
3520 _preMeshInfo->FullLoadFromFile();
3522 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3523 if(!SM) return aResult._retn();
3525 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3526 if(!SDSM) return aResult._retn();
3529 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3530 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3531 while ( nIt->more() ) {
3532 const SMDS_MeshNode* elem = nIt->next();
3533 theElems.insert( elem->GetID() );
3536 else { // all nodes of submesh elements
3537 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3538 while ( eIt->more() ) {
3539 const SMDS_MeshElement* anElem = eIt->next();
3540 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3541 while ( nIt->more() ) {
3542 const SMDS_MeshElement* elem = nIt->next();
3543 theElems.insert( elem->GetID() );
3548 aResult->length(theElems.size());
3549 set<int>::iterator itElem;
3551 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3552 aResult[i++] = *itElem;
3554 SMESH_CATCH( SMESH::throwCorbaException );
3556 return aResult._retn();
3559 //=============================================================================
3561 * Returns type of elements for given submesh
3563 //=============================================================================
3565 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3566 throw (SALOME::SALOME_Exception)
3568 SMESH::ElementType type;
3572 _preMeshInfo->FullLoadFromFile();
3574 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3575 if(!SM) return SMESH::ALL;
3577 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3578 if(!SDSM) return SMESH::ALL;
3580 if(SDSM->NbElements()==0)
3581 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3583 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3584 const SMDS_MeshElement* anElem = eIt->next();
3586 type = ( SMESH::ElementType ) anElem->GetType();
3588 SMESH_CATCH( SMESH::throwCorbaException );
3594 //=============================================================================
3596 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3598 //=============================================================================
3600 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3603 _preMeshInfo->FullLoadFromFile();
3605 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3607 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3612 //=============================================================================
3614 * Get XYZ coordinates of node as list of double
3615 * If there is not node for given ID - returns empty list
3617 //=============================================================================
3619 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3622 _preMeshInfo->FullLoadFromFile();
3624 SMESH::double_array_var aResult = new SMESH::double_array();
3625 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3626 if ( aSMESHDS_Mesh == NULL )
3627 return aResult._retn();
3630 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3632 return aResult._retn();
3636 aResult[0] = aNode->X();
3637 aResult[1] = aNode->Y();
3638 aResult[2] = aNode->Z();
3639 return aResult._retn();
3643 //=============================================================================
3645 * For given node returns list of IDs of inverse elements
3646 * If there is not node for given ID - returns empty list
3648 //=============================================================================
3650 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3653 _preMeshInfo->FullLoadFromFile();
3655 SMESH::long_array_var aResult = new SMESH::long_array();
3656 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3657 if ( aSMESHDS_Mesh == NULL )
3658 return aResult._retn();
3661 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3663 return aResult._retn();
3665 // find inverse elements
3666 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3667 TColStd_SequenceOfInteger IDs;
3668 while(eIt->more()) {
3669 const SMDS_MeshElement* elem = eIt->next();
3670 IDs.Append(elem->GetID());
3672 if(IDs.Length()>0) {
3673 aResult->length(IDs.Length());
3675 for(; i<=IDs.Length(); i++) {
3676 aResult[i-1] = IDs.Value(i);
3679 return aResult._retn();
3682 //=============================================================================
3684 * \brief Return position of a node on shape
3686 //=============================================================================
3688 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3691 _preMeshInfo->FullLoadFromFile();
3693 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3694 aNodePosition->shapeID = 0;
3695 aNodePosition->shapeType = GEOM::SHAPE;
3697 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3698 if ( !mesh ) return aNodePosition;
3700 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3702 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3704 aNodePosition->shapeID = aNode->getshapeId();
3705 switch ( pos->GetTypeOfPosition() ) {
3707 aNodePosition->shapeType = GEOM::EDGE;
3708 aNodePosition->params.length(1);
3709 aNodePosition->params[0] =
3710 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3713 aNodePosition->shapeType = GEOM::FACE;
3714 aNodePosition->params.length(2);
3715 aNodePosition->params[0] =
3716 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3717 aNodePosition->params[1] =
3718 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3720 case SMDS_TOP_VERTEX:
3721 aNodePosition->shapeType = GEOM::VERTEX;
3723 case SMDS_TOP_3DSPACE:
3724 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3725 aNodePosition->shapeType = GEOM::SOLID;
3726 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3727 aNodePosition->shapeType = GEOM::SHELL;
3733 return aNodePosition;
3736 //=============================================================================
3738 * \brief Return position of an element on shape
3740 //=============================================================================
3742 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
3745 _preMeshInfo->FullLoadFromFile();
3747 SMESH::ElementPosition anElementPosition;
3748 anElementPosition.shapeID = 0;
3749 anElementPosition.shapeType = GEOM::SHAPE;
3751 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3752 if ( !mesh ) return anElementPosition;
3754 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
3756 anElementPosition.shapeID = anElem->getshapeId();
3757 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
3758 if ( !aSp.IsNull() ) {
3759 switch ( aSp.ShapeType() ) {
3761 anElementPosition.shapeType = GEOM::EDGE;
3764 anElementPosition.shapeType = GEOM::FACE;
3767 anElementPosition.shapeType = GEOM::VERTEX;
3770 anElementPosition.shapeType = GEOM::SOLID;
3773 anElementPosition.shapeType = GEOM::SHELL;
3779 return anElementPosition;
3782 //=============================================================================
3784 * If given element is node returns IDs of shape from position
3785 * If there is not node for given ID - returns -1
3787 //=============================================================================
3789 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3792 _preMeshInfo->FullLoadFromFile();
3794 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3795 if ( aSMESHDS_Mesh == NULL )
3799 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3801 return aNode->getshapeId();
3808 //=============================================================================
3810 * For given element returns ID of result shape after
3811 * ::FindShape() from SMESH_MeshEditor
3812 * If there is not element for given ID - returns -1
3814 //=============================================================================
3816 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3819 _preMeshInfo->FullLoadFromFile();
3821 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3822 if ( aSMESHDS_Mesh == NULL )
3825 // try to find element
3826 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3830 ::SMESH_MeshEditor aMeshEditor(_impl);
3831 int index = aMeshEditor.FindShape( elem );
3839 //=============================================================================
3841 * Returns number of nodes for given element
3842 * If there is not element for given ID - returns -1
3844 //=============================================================================
3846 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3849 _preMeshInfo->FullLoadFromFile();
3851 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3852 if ( aSMESHDS_Mesh == NULL ) return -1;
3853 // try to find element
3854 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3855 if(!elem) return -1;
3856 return elem->NbNodes();
3860 //=============================================================================
3862 * Returns ID of node by given index for given element
3863 * If there is not element for given ID - returns -1
3864 * If there is not node for given index - returns -2
3866 //=============================================================================
3868 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3871 _preMeshInfo->FullLoadFromFile();
3873 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3874 if ( aSMESHDS_Mesh == NULL ) return -1;
3875 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3876 if(!elem) return -1;
3877 if( index>=elem->NbNodes() || index<0 ) return -1;
3878 return elem->GetNode(index)->GetID();
3881 //=============================================================================
3883 * Returns IDs of nodes of given element
3885 //=============================================================================
3887 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3890 _preMeshInfo->FullLoadFromFile();
3892 SMESH::long_array_var aResult = new SMESH::long_array();
3893 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3895 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3897 aResult->length( elem->NbNodes() );
3898 for ( int i = 0; i < elem->NbNodes(); ++i )
3899 aResult[ i ] = elem->GetNode( i )->GetID();
3902 return aResult._retn();
3905 //=============================================================================
3907 * Returns true if given node is medium node
3908 * in given quadratic element
3910 //=============================================================================
3912 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3915 _preMeshInfo->FullLoadFromFile();
3917 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3918 if ( aSMESHDS_Mesh == NULL ) return false;
3920 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3921 if(!aNode) return false;
3922 // try to find element
3923 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3924 if(!elem) return false;
3926 return elem->IsMediumNode(aNode);
3930 //=============================================================================
3932 * Returns true if given node is medium node
3933 * in one of quadratic elements
3935 //=============================================================================
3937 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3938 SMESH::ElementType theElemType)
3941 _preMeshInfo->FullLoadFromFile();
3943 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3944 if ( aSMESHDS_Mesh == NULL ) return false;
3947 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3948 if(!aNode) return false;
3950 SMESH_MesherHelper aHelper( *(_impl) );
3952 SMDSAbs_ElementType aType;
3953 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3954 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3955 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3956 else aType = SMDSAbs_All;
3958 return aHelper.IsMedium(aNode,aType);
3962 //=============================================================================
3964 * Returns number of edges for given element
3966 //=============================================================================
3968 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3971 _preMeshInfo->FullLoadFromFile();
3973 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3974 if ( aSMESHDS_Mesh == NULL ) return -1;
3975 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3976 if(!elem) return -1;
3977 return elem->NbEdges();
3981 //=============================================================================
3983 * Returns number of faces for given element
3985 //=============================================================================
3987 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3990 _preMeshInfo->FullLoadFromFile();
3992 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3993 if ( aSMESHDS_Mesh == NULL ) return -1;
3994 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3995 if(!elem) return -1;
3996 return elem->NbFaces();
3999 //=======================================================================
4000 //function : GetElemFaceNodes
4001 //purpose : Returns nodes of given face (counted from zero) for given element.
4002 //=======================================================================
4004 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4005 CORBA::Short faceIndex)
4008 _preMeshInfo->FullLoadFromFile();
4010 SMESH::long_array_var aResult = new SMESH::long_array();
4011 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4013 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4015 SMDS_VolumeTool vtool( elem );
4016 if ( faceIndex < vtool.NbFaces() )
4018 aResult->length( vtool.NbFaceNodes( faceIndex ));
4019 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4020 for ( int i = 0; i < aResult->length(); ++i )
4021 aResult[ i ] = nn[ i ]->GetID();
4025 return aResult._retn();
4028 //=======================================================================
4029 //function : FindElementByNodes
4030 //purpose : Returns an element based on all given nodes.
4031 //=======================================================================
4033 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4036 _preMeshInfo->FullLoadFromFile();
4038 CORBA::Long elemID(0);
4039 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4041 vector< const SMDS_MeshNode * > nn( nodes.length() );
4042 for ( int i = 0; i < nodes.length(); ++i )
4043 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4046 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4047 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4048 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4049 _impl->NbVolumes( ORDER_QUADRATIC )))
4050 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4052 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4057 //=============================================================================
4059 * Returns true if given element is polygon
4061 //=============================================================================
4063 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4066 _preMeshInfo->FullLoadFromFile();
4068 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4069 if ( aSMESHDS_Mesh == NULL ) return false;
4070 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4071 if(!elem) return false;
4072 return elem->IsPoly();
4076 //=============================================================================
4078 * Returns true if given element is quadratic
4080 //=============================================================================
4082 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4085 _preMeshInfo->FullLoadFromFile();
4087 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4088 if ( aSMESHDS_Mesh == NULL ) return false;
4089 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4090 if(!elem) return false;
4091 return elem->IsQuadratic();
4094 //=============================================================================
4096 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4098 //=============================================================================
4100 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4103 _preMeshInfo->FullLoadFromFile();
4105 if ( const SMDS_BallElement* ball =
4106 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4107 return ball->GetDiameter();
4112 //=============================================================================
4114 * Returns bary center for given element
4116 //=============================================================================
4118 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4121 _preMeshInfo->FullLoadFromFile();
4123 SMESH::double_array_var aResult = new SMESH::double_array();
4124 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4125 if ( aSMESHDS_Mesh == NULL )
4126 return aResult._retn();
4128 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4130 return aResult._retn();
4132 if(elem->GetType()==SMDSAbs_Volume) {
4133 SMDS_VolumeTool aTool;
4134 if(aTool.Set(elem)) {
4136 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4141 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4143 double x=0., y=0., z=0.;
4144 for(; anIt->more(); ) {
4146 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4160 return aResult._retn();
4163 //================================================================================
4165 * \brief Create a group of elements preventing computation of a sub-shape
4167 //================================================================================
4169 SMESH::ListOfGroups*
4170 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4171 const char* theGroupName )
4172 throw ( SALOME::SALOME_Exception )
4174 Unexpect aCatch(SALOME_SalomeException);
4176 if ( !theGroupName || strlen( theGroupName) == 0 )
4177 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4179 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4181 // submesh by subshape id
4182 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4183 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4186 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4187 if ( error && !error->myBadElements.empty())
4189 // sort bad elements by type
4190 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4191 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4192 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4193 for ( ; elemIt != elemEnd; ++elemIt )
4195 const SMDS_MeshElement* elem = *elemIt;
4196 if ( !elem ) continue;
4198 if ( elem->GetID() < 1 )
4200 // elem is a temporary element, make a real element
4201 vector< const SMDS_MeshNode* > nodes;
4202 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4203 while ( nIt->more() && elem )
4205 nodes.push_back( nIt->next() );
4206 if ( nodes.back()->GetID() < 1 )
4207 elem = 0; // a temporary element on temporary nodes
4211 ::SMESH_MeshEditor editor( _impl );
4212 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4216 elemsByType[ elem->GetType() ].push_back( elem );
4219 // how many groups to create?
4221 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4222 nbTypes += int( !elemsByType[ i ].empty() );
4223 groups->length( nbTypes );
4226 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4228 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4229 if ( elems.empty() ) continue;
4231 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4232 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4234 SALOMEDS::SObject_wrap aSO =
4235 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), groups[ iG ],
4236 GEOM::GEOM_Object::_nil(), theGroupName);
4237 aSO->_is_nil(); // avoid "unused variable" warning
4239 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4240 if ( !grp_i ) continue;
4242 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4243 for ( size_t iE = 0; iE < elems.size(); ++iE )
4244 grpDS->SMDSGroup().Add( elems[ iE ]);
4249 return groups._retn();
4252 //=============================================================================
4254 * Create and publish group servants if any groups were imported or created anyhow
4256 //=============================================================================
4258 void SMESH_Mesh_i::CreateGroupServants()
4260 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4263 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4264 while ( groupIt->more() )
4266 ::SMESH_Group* group = groupIt->next();
4267 int anId = group->GetGroupDS()->GetID();
4269 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4270 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4272 addedIDs.insert( anId );
4274 SMESH_GroupBase_i* aGroupImpl;
4276 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4277 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4279 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4280 shape = groupOnGeom->GetShape();
4283 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4286 SMESH::SMESH_GroupBase_var groupVar =
4287 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4288 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4290 // register CORBA object for persistence
4291 int nextId = _gen_i->RegisterObject( groupVar );
4292 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4293 else { nextId = 0; } // avoid "unused variable" warning in release mode
4295 // publishing the groups in the study
4296 if ( !aStudy->_is_nil() ) {
4297 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4298 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4301 if ( !addedIDs.empty() )
4304 set<int>::iterator id = addedIDs.begin();
4305 for ( ; id != addedIDs.end(); ++id )
4307 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4308 int i = std::distance( _mapGroups.begin(), it );
4309 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4314 //=============================================================================
4316 * \brief Return groups cantained in _mapGroups by their IDs
4318 //=============================================================================
4320 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4322 int nbGroups = groupIDs.size();
4323 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4324 aList->length( nbGroups );
4326 list<int>::const_iterator ids = groupIDs.begin();
4327 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4329 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4330 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4331 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4333 aList->length( nbGroups );
4334 return aList._retn();
4337 //=============================================================================
4339 * \brief Return information about imported file
4341 //=============================================================================
4343 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4345 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4346 if ( !res.operator->() ) {
4347 res = new SALOME_MED::MedFileInfo;
4349 res->fileSize = res->major = res->minor = res->release = -1;
4354 //=============================================================================
4356 * \brief Pass names of mesh groups from study to mesh DS
4358 //=============================================================================
4360 void SMESH_Mesh_i::checkGroupNames()
4362 int nbGrp = NbGroups();
4366 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4367 if ( aStudy->_is_nil() )
4368 return; // nothing to do
4370 SMESH::ListOfGroups* grpList = 0;
4371 // avoid dump of "GetGroups"
4373 // store python dump into a local variable inside local scope
4374 SMESH::TPythonDump pDump; // do not delete this line of code
4375 grpList = GetGroups();
4378 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4379 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4382 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4383 if ( aGrpSO->_is_nil() )
4385 // correct name of the mesh group if necessary
4386 const char* guiName = aGrpSO->GetName();
4387 if ( strcmp(guiName, aGrp->GetName()) )
4388 aGrp->SetName( guiName );
4392 //=============================================================================
4394 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4396 //=============================================================================
4397 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4399 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4403 //=============================================================================
4405 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4407 //=============================================================================
4408 char* SMESH_Mesh_i::GetParameters()
4410 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4411 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4414 //=============================================================================
4416 * \brief Returns list of notebook variables used for last Mesh operation
4418 //=============================================================================
4419 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4421 SMESH::string_array_var aResult = new SMESH::string_array();
4422 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4424 char *aParameters = GetParameters();
4425 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4426 if(!aStudy->_is_nil()) {
4427 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4428 if(aSections->length() > 0) {
4429 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4430 aResult->length(aVars.length());
4431 for(int i = 0;i < aVars.length();i++)
4432 aResult[i] = CORBA::string_dup( aVars[i]);
4436 return aResult._retn();
4439 //=======================================================================
4440 //function : GetTypes
4441 //purpose : Returns types of elements it contains
4442 //=======================================================================
4444 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4447 return _preMeshInfo->GetTypes();
4449 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4453 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4454 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4455 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4456 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4457 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4458 types->length( nbTypes );
4460 return types._retn();
4463 //=======================================================================
4464 //function : GetMesh
4465 //purpose : Returns self
4466 //=======================================================================
4468 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4470 return SMESH::SMESH_Mesh::_duplicate( _this() );
4473 //=======================================================================
4474 //function : IsMeshInfoCorrect
4475 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4476 // * happen if mesh data is not yet fully loaded from the file of study.
4477 //=======================================================================
4479 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4481 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4484 //=============================================================================
4486 * \brief Returns statistic of mesh elements
4488 //=============================================================================
4490 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4493 return _preMeshInfo->GetMeshInfo();
4495 SMESH::long_array_var aRes = new SMESH::long_array();
4496 aRes->length(SMESH::Entity_Last);
4497 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4499 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4501 return aRes._retn();
4502 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4503 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4504 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4505 return aRes._retn();
4508 //=============================================================================
4510 * \brief Collect statistic of mesh elements given by iterator
4512 //=============================================================================
4514 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4515 SMESH::long_array& theInfo)
4517 if (!theItr) return;
4518 while (theItr->more())
4519 theInfo[ theItr->next()->GetEntityType() ]++;
4522 //=============================================================================
4523 namespace // Finding concurrent hypotheses
4524 //=============================================================================
4528 * \brief mapping of mesh dimension into shape type
4530 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4532 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4534 case 0: aType = TopAbs_VERTEX; break;
4535 case 1: aType = TopAbs_EDGE; break;
4536 case 2: aType = TopAbs_FACE; break;
4538 default:aType = TopAbs_SOLID; break;
4543 //-----------------------------------------------------------------------------
4545 * \brief Internal structure used to find concurent submeshes
4547 * It represents a pair < submesh, concurent dimension >, where
4548 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4549 * with another submesh. In other words, it is dimension of a hypothesis assigned
4556 int _dim; //!< a dimension the algo can build (concurrent dimension)
4557 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4558 TopTools_MapOfShape _shapeMap;
4559 SMESH_subMesh* _subMesh;
4560 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4562 //-----------------------------------------------------------------------------
4563 // Return the algorithm
4564 const SMESH_Algo* GetAlgo() const
4565 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4567 //-----------------------------------------------------------------------------
4569 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4571 const TopoDS_Shape& theShape)
4573 _subMesh = (SMESH_subMesh*)theSubMesh;
4574 SetShape( theDim, theShape );
4577 //-----------------------------------------------------------------------------
4579 void SetShape(const int theDim,
4580 const TopoDS_Shape& theShape)
4583 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4584 if (_dim >= _ownDim)
4585 _shapeMap.Add( theShape );
4587 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4588 for( ; anExp.More(); anExp.Next() )
4589 _shapeMap.Add( anExp.Current() );
4593 //-----------------------------------------------------------------------------
4594 //! Check sharing of sub-shapes
4595 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4596 const TopTools_MapOfShape& theToFind,
4597 const TopAbs_ShapeEnum theType)
4599 bool isShared = false;
4600 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4601 for (; !isShared && anItr.More(); anItr.Next() )
4603 const TopoDS_Shape aSubSh = anItr.Key();
4604 // check for case when concurrent dimensions are same
4605 isShared = theToFind.Contains( aSubSh );
4606 // check for sub-shape with concurrent dimension
4607 TopExp_Explorer anExp( aSubSh, theType );
4608 for ( ; !isShared && anExp.More(); anExp.Next() )
4609 isShared = theToFind.Contains( anExp.Current() );
4614 //-----------------------------------------------------------------------------
4615 //! check algorithms
4616 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4617 const SMESHDS_Hypothesis* theA2)
4619 if ( !theA1 || !theA2 ||
4620 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4621 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4622 return false; // one of the hypothesis is not algorithm
4623 // check algorithm names (should be equal)
4624 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4628 //-----------------------------------------------------------------------------
4629 //! Check if sub-shape hypotheses are concurrent
4630 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4632 if ( _subMesh == theOther->_subMesh )
4633 return false; // same sub-shape - should not be
4635 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4636 // any of the two submeshes is not on COMPOUND shape )
4637 // -> no concurrency
4638 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4639 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4640 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4641 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4642 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4645 // bool checkSubShape = ( _dim >= theOther->_dim )
4646 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4647 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4648 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4649 if ( !checkSubShape )
4652 // check algorithms to be same
4653 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4654 return true; // different algorithms -> concurrency !
4656 // check hypothesises for concurrence (skip first as algorithm)
4658 // pointers should be same, because it is referened from mesh hypothesis partition
4659 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4660 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4661 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4662 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4664 // the submeshes are concurrent if their algorithms has different parameters
4665 return nbSame != theOther->_hypotheses.size() - 1;
4668 // Return true if algorithm of this SMESH_DimHyp is used if no
4669 // sub-mesh order is imposed by the user
4670 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4672 // NeedDiscreteBoundary() algo has a higher priority
4673 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4674 theOther->GetAlgo()->NeedDiscreteBoundary() )
4675 return !this->GetAlgo()->NeedDiscreteBoundary();
4677 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4680 }; // end of SMESH_DimHyp
4681 //-----------------------------------------------------------------------------
4683 typedef list<const SMESH_DimHyp*> TDimHypList;
4685 //-----------------------------------------------------------------------------
4687 void addDimHypInstance(const int theDim,
4688 const TopoDS_Shape& theShape,
4689 const SMESH_Algo* theAlgo,
4690 const SMESH_subMesh* theSubMesh,
4691 const list <const SMESHDS_Hypothesis*>& theHypList,
4692 TDimHypList* theDimHypListArr )
4694 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4695 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4696 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4697 dimHyp->_hypotheses.push_front(theAlgo);
4698 listOfdimHyp.push_back( dimHyp );
4701 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4702 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4703 theHypList.begin(), theHypList.end() );
4706 //-----------------------------------------------------------------------------
4707 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4708 TDimHypList& theListOfConcurr)
4710 if ( theListOfConcurr.empty() )
4712 theListOfConcurr.push_back( theDimHyp );
4716 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4717 while ( hypIt != theListOfConcurr.end() &&
4718 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4720 theListOfConcurr.insert( hypIt, theDimHyp );
4724 //-----------------------------------------------------------------------------
4725 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4726 const TDimHypList& theListOfDimHyp,
4727 TDimHypList& theListOfConcurrHyp,
4728 set<int>& theSetOfConcurrId )
4730 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4731 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4733 const SMESH_DimHyp* curDimHyp = *rIt;
4734 if ( curDimHyp == theDimHyp )
4735 break; // meet own dimHyp pointer in same dimension
4737 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4738 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4740 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4745 //-----------------------------------------------------------------------------
4746 void unionLists(TListOfInt& theListOfId,
4747 TListOfListOfInt& theListOfListOfId,
4750 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4751 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4753 continue; //skip already treated lists
4754 // check if other list has any same submesh object
4755 TListOfInt& otherListOfId = *it;
4756 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4757 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4760 // union two lists (from source into target)
4761 TListOfInt::iterator it2 = otherListOfId.begin();
4762 for ( ; it2 != otherListOfId.end(); it2++ ) {
4763 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4764 theListOfId.push_back(*it2);
4766 // clear source list
4767 otherListOfId.clear();
4770 //-----------------------------------------------------------------------------
4772 //! free memory allocated for dimension-hypothesis objects
4773 void removeDimHyps( TDimHypList* theArrOfList )
4775 for (int i = 0; i < 4; i++ ) {
4776 TDimHypList& listOfdimHyp = theArrOfList[i];
4777 TDimHypList::const_iterator it = listOfdimHyp.begin();
4778 for ( ; it != listOfdimHyp.end(); it++ )
4783 //-----------------------------------------------------------------------------
4785 * \brief find common submeshes with given submesh
4786 * \param theSubMeshList list of already collected submesh to check
4787 * \param theSubMesh given submesh to intersect with other
4788 * \param theCommonSubMeshes collected common submeshes
4790 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4791 const SMESH_subMesh* theSubMesh,
4792 set<const SMESH_subMesh*>& theCommon )
4796 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4797 for ( ; it != theSubMeshList.end(); it++ )
4798 theSubMesh->FindIntersection( *it, theCommon );
4799 theSubMeshList.push_back( theSubMesh );
4800 //theCommon.insert( theSubMesh );
4805 //=============================================================================
4807 * \brief Return submesh objects list in meshing order
4809 //=============================================================================
4811 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4813 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4815 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4817 return aResult._retn();
4819 ::SMESH_Mesh& mesh = GetImpl();
4820 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4821 if ( !anOrder.size() ) {
4823 // collect submeshes and detect concurrent algorithms and hypothesises
4824 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4826 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4827 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4828 ::SMESH_subMesh* sm = (*i_sm).second;
4830 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4832 // list of assigned hypothesises
4833 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4834 // Find out dimensions where the submesh can be concurrent.
4835 // We define the dimensions by algo of each of hypotheses in hypList
4836 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4837 for( ; hypIt != hypList.end(); hypIt++ ) {
4838 SMESH_Algo* anAlgo = 0;
4839 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4840 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4841 // hyp it-self is algo
4842 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4844 // try to find algorithm with help of sub-shapes
4845 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4846 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4847 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4850 continue; // no algorithm assigned to a current submesh
4852 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4853 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4855 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4856 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4857 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4859 } // end iterations on submesh
4861 // iterate on created dimension-hypotheses and check for concurrents
4862 for ( int i = 0; i < 4; i++ ) {
4863 const TDimHypList& listOfDimHyp = dimHypListArr[i];
4864 // check for concurrents in own and other dimensions (step-by-step)
4865 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4866 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4867 const SMESH_DimHyp* dimHyp = *dhIt;
4868 TDimHypList listOfConcurr;
4869 set<int> setOfConcurrIds;
4870 // looking for concurrents and collect into own list
4871 for ( int j = i; j < 4; j++ )
4872 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
4873 // check if any concurrents found
4874 if ( listOfConcurr.size() > 0 ) {
4875 // add own submesh to list of concurrent
4876 addInOrderOfPriority( dimHyp, listOfConcurr );
4877 list<int> listOfConcurrIds;
4878 TDimHypList::iterator hypIt = listOfConcurr.begin();
4879 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
4880 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
4881 anOrder.push_back( listOfConcurrIds );
4886 removeDimHyps(dimHypListArr);
4888 // now, minimise the number of concurrent groups
4889 // Here we assume that lists of submeshes can have same submesh
4890 // in case of multi-dimension algorithms, as result
4891 // list with common submesh has to be united into one list
4893 TListOfListOfInt::iterator listIt = anOrder.begin();
4894 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4895 unionLists( *listIt, anOrder, listIndx + 1 );
4897 // convert submesh ids into interface instances
4898 // and dump command into python
4899 convertMeshOrder( anOrder, aResult, false );
4901 return aResult._retn();
4904 //=============================================================================
4906 * \brief Set submesh object order
4907 * \param theSubMeshArray submesh array order
4909 //=============================================================================
4911 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4914 _preMeshInfo->ForgetOrLoad();
4917 ::SMESH_Mesh& mesh = GetImpl();
4919 TPythonDump aPythonDump; // prevent dump of called methods
4920 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4922 TListOfListOfInt subMeshOrder;
4923 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4925 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4926 TListOfInt subMeshIds;
4927 aPythonDump << "[ ";
4928 // Collect subMeshes which should be clear
4929 // do it list-by-list, because modification of submesh order
4930 // take effect between concurrent submeshes only
4931 set<const SMESH_subMesh*> subMeshToClear;
4932 list<const SMESH_subMesh*> subMeshList;
4933 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4935 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4937 aPythonDump << ", ";
4938 aPythonDump << subMesh;
4939 subMeshIds.push_back( subMesh->GetId() );
4940 // detect common parts of submeshes
4941 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4942 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4944 aPythonDump << " ]";
4945 subMeshOrder.push_back( subMeshIds );
4947 // clear collected submeshes
4948 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4949 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
4950 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
4951 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4953 aPythonDump << " ])";
4955 mesh.SetMeshOrder( subMeshOrder );
4961 //=============================================================================
4963 * \brief Convert submesh ids into submesh interfaces
4965 //=============================================================================
4967 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4968 SMESH::submesh_array_array& theResOrder,
4969 const bool theIsDump)
4971 int nbSet = theIdsOrder.size();
4972 TPythonDump aPythonDump; // prevent dump of called methods
4974 aPythonDump << "[ ";
4975 theResOrder.length(nbSet);
4976 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4978 for( ; it != theIdsOrder.end(); it++ ) {
4979 // translate submesh identificators into submesh objects
4980 // takeing into account real number of concurrent lists
4981 const TListOfInt& aSubOrder = (*it);
4982 if (!aSubOrder.size())
4985 aPythonDump << "[ ";
4986 // convert shape indeces into interfaces
4987 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4988 aResSubSet->length(aSubOrder.size());
4989 TListOfInt::const_iterator subIt = aSubOrder.begin();
4990 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4991 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4993 SMESH::SMESH_subMesh_var subMesh =
4994 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4997 aPythonDump << ", ";
4998 aPythonDump << subMesh;
5000 aResSubSet[ j++ ] = subMesh;
5003 aPythonDump << " ]";
5004 theResOrder[ listIndx++ ] = aResSubSet;
5006 // correct number of lists
5007 theResOrder.length( listIndx );
5010 // finilise python dump
5011 aPythonDump << " ]";
5012 aPythonDump << " = " << _this() << ".GetMeshOrder()";
5016 //================================================================================
5018 // Implementation of SMESH_MeshPartDS
5020 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5021 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5023 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5024 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5026 _meshDS = mesh_i->GetImpl().GetMeshDS();
5028 SetPersistentId( _meshDS->GetPersistentId() );
5030 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5032 // <meshPart> is the whole mesh
5033 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5035 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5036 myGroupSet = _meshDS->GetGroups();
5041 SMESH::long_array_var anIDs = meshPart->GetIDs();
5042 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5043 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5045 for (int i=0; i < anIDs->length(); i++)
5046 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5047 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5052 for (int i=0; i < anIDs->length(); i++)
5053 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5054 if ( _elements[ e->GetType() ].insert( e ).second )
5057 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5058 while ( nIt->more() )
5060 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5061 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5068 _meshDS = 0; // to enforce iteration on _elements and _nodes
5071 // -------------------------------------------------------------------------------------
5072 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5073 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5076 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5077 for ( ; partIt != meshPart.end(); ++partIt )
5078 if ( const SMDS_MeshElement * e = *partIt )
5079 if ( _elements[ e->GetType() ].insert( e ).second )
5082 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5083 while ( nIt->more() )
5085 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5086 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5092 // -------------------------------------------------------------------------------------
5093 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5095 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5097 typedef SMDS_SetIterator
5098 <const SMDS_MeshElement*,
5099 TIDSortedElemSet::const_iterator,
5100 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5101 SMDS_MeshElement::GeomFilter
5104 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5106 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5107 _elements[type].end(),
5108 SMDS_MeshElement::GeomFilter( geomType )));
5110 // -------------------------------------------------------------------------------------
5111 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5113 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5115 typedef SMDS_SetIterator
5116 <const SMDS_MeshElement*,
5117 TIDSortedElemSet::const_iterator,
5118 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5119 SMDS_MeshElement::EntityFilter
5122 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5124 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5125 _elements[type].end(),
5126 SMDS_MeshElement::EntityFilter( entity )));
5128 // -------------------------------------------------------------------------------------
5129 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5131 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5132 if ( type == SMDSAbs_All && !_meshDS )
5134 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5136 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5137 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5139 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5141 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5142 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5144 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5145 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5147 // -------------------------------------------------------------------------------------
5148 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5149 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5151 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5152 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5153 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5155 // -------------------------------------------------------------------------------------
5156 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5157 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5158 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5159 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5160 #undef _GET_ITER_DEFINE
5162 // END Implementation of SMESH_MeshPartDS
5164 //================================================================================