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_Controls.hxx"
43 #include "SMESH_Filter_i.hxx"
44 #include "SMESH_Gen_i.hxx"
45 #include "SMESH_Group.hxx"
46 #include "SMESH_Group_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 SMESH::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 computation progress [0.,1]
3014 //=============================================================================
3016 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3020 return _impl->GetComputeProgress();
3022 SMESH_CATCH( SMESH::doNothing );
3026 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3028 Unexpect aCatch(SALOME_SalomeException);
3030 return _preMeshInfo->NbNodes();
3032 return _impl->NbNodes();
3035 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3037 Unexpect aCatch(SALOME_SalomeException);
3039 return _preMeshInfo->NbElements();
3041 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3044 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3046 Unexpect aCatch(SALOME_SalomeException);
3048 return _preMeshInfo->Nb0DElements();
3050 return _impl->Nb0DElements();
3053 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3055 Unexpect aCatch(SALOME_SalomeException);
3057 return _preMeshInfo->NbBalls();
3059 return _impl->NbBalls();
3062 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3064 Unexpect aCatch(SALOME_SalomeException);
3066 return _preMeshInfo->NbEdges();
3068 return _impl->NbEdges();
3071 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3072 throw(SALOME::SALOME_Exception)
3074 Unexpect aCatch(SALOME_SalomeException);
3076 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3078 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3081 //=============================================================================
3083 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3085 Unexpect aCatch(SALOME_SalomeException);
3087 return _preMeshInfo->NbFaces();
3089 return _impl->NbFaces();
3092 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3094 Unexpect aCatch(SALOME_SalomeException);
3096 return _preMeshInfo->NbTriangles();
3098 return _impl->NbTriangles();
3101 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3103 Unexpect aCatch(SALOME_SalomeException);
3105 return _preMeshInfo->NbBiQuadTriangles();
3107 return _impl->NbBiQuadTriangles();
3110 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3112 Unexpect aCatch(SALOME_SalomeException);
3114 return _preMeshInfo->NbQuadrangles();
3116 return _impl->NbQuadrangles();
3119 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3121 Unexpect aCatch(SALOME_SalomeException);
3123 return _preMeshInfo->NbBiQuadQuadrangles();
3125 return _impl->NbBiQuadQuadrangles();
3128 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3130 Unexpect aCatch(SALOME_SalomeException);
3132 return _preMeshInfo->NbPolygons();
3134 return _impl->NbPolygons();
3137 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3138 throw(SALOME::SALOME_Exception)
3140 Unexpect aCatch(SALOME_SalomeException);
3142 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3144 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3147 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3148 throw(SALOME::SALOME_Exception)
3150 Unexpect aCatch(SALOME_SalomeException);
3152 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3154 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3157 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3158 throw(SALOME::SALOME_Exception)
3160 Unexpect aCatch(SALOME_SalomeException);
3162 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3164 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3167 //=============================================================================
3169 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3171 Unexpect aCatch(SALOME_SalomeException);
3173 return _preMeshInfo->NbVolumes();
3175 return _impl->NbVolumes();
3178 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3180 Unexpect aCatch(SALOME_SalomeException);
3182 return _preMeshInfo->NbTetras();
3184 return _impl->NbTetras();
3187 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3189 Unexpect aCatch(SALOME_SalomeException);
3191 return _preMeshInfo->NbHexas();
3193 return _impl->NbHexas();
3196 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3198 Unexpect aCatch(SALOME_SalomeException);
3200 return _preMeshInfo->NbTriQuadHexas();
3202 return _impl->NbTriQuadraticHexas();
3205 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3207 Unexpect aCatch(SALOME_SalomeException);
3209 return _preMeshInfo->NbPyramids();
3211 return _impl->NbPyramids();
3214 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3216 Unexpect aCatch(SALOME_SalomeException);
3218 return _preMeshInfo->NbPrisms();
3220 return _impl->NbPrisms();
3223 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3225 Unexpect aCatch(SALOME_SalomeException);
3227 return _preMeshInfo->NbHexPrisms();
3229 return _impl->NbHexagonalPrisms();
3232 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3234 Unexpect aCatch(SALOME_SalomeException);
3236 return _preMeshInfo->NbPolyhedrons();
3238 return _impl->NbPolyhedrons();
3241 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3242 throw(SALOME::SALOME_Exception)
3244 Unexpect aCatch(SALOME_SalomeException);
3246 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3248 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3251 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3252 throw(SALOME::SALOME_Exception)
3254 Unexpect aCatch(SALOME_SalomeException);
3256 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3258 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3261 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3262 throw(SALOME::SALOME_Exception)
3264 Unexpect aCatch(SALOME_SalomeException);
3266 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3268 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3271 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3272 throw(SALOME::SALOME_Exception)
3274 Unexpect aCatch(SALOME_SalomeException);
3276 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3278 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3281 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3282 throw(SALOME::SALOME_Exception)
3284 Unexpect aCatch(SALOME_SalomeException);
3286 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3288 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3291 //=============================================================================
3293 * Returns nb of published sub-meshes
3295 //=============================================================================
3297 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3299 Unexpect aCatch(SALOME_SalomeException);
3300 return _mapSubMesh_i.size();
3303 //=============================================================================
3305 * Dumps mesh into a string
3307 //=============================================================================
3309 char* SMESH_Mesh_i::Dump()
3313 return CORBA::string_dup( os.str().c_str() );
3316 //=============================================================================
3318 * Method of SMESH_IDSource interface
3320 //=============================================================================
3322 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3324 return GetElementsId();
3327 //=============================================================================
3329 * Returns ids of all elements
3331 //=============================================================================
3333 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3334 throw (SALOME::SALOME_Exception)
3336 Unexpect aCatch(SALOME_SalomeException);
3338 _preMeshInfo->FullLoadFromFile();
3340 SMESH::long_array_var aResult = new SMESH::long_array();
3341 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3343 if ( aSMESHDS_Mesh == NULL )
3344 return aResult._retn();
3346 long nbElements = NbElements();
3347 aResult->length( nbElements );
3348 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3349 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3350 aResult[i] = anIt->next()->GetID();
3352 return aResult._retn();
3356 //=============================================================================
3358 * Returns ids of all elements of given type
3360 //=============================================================================
3362 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3363 throw (SALOME::SALOME_Exception)
3365 Unexpect aCatch(SALOME_SalomeException);
3367 _preMeshInfo->FullLoadFromFile();
3369 SMESH::long_array_var aResult = new SMESH::long_array();
3370 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3372 if ( aSMESHDS_Mesh == NULL )
3373 return aResult._retn();
3375 long nbElements = NbElements();
3377 // No sense in returning ids of elements along with ids of nodes:
3378 // when theElemType == SMESH::ALL, return node ids only if
3379 // there are no elements
3380 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3381 return GetNodesId();
3383 aResult->length( nbElements );
3387 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3388 while ( i < nbElements && anIt->more() ) {
3389 const SMDS_MeshElement* anElem = anIt->next();
3390 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3391 aResult[i++] = anElem->GetID();
3394 aResult->length( i );
3396 return aResult._retn();
3399 //=============================================================================
3401 * Returns ids of all nodes
3403 //=============================================================================
3405 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3406 throw (SALOME::SALOME_Exception)
3408 Unexpect aCatch(SALOME_SalomeException);
3410 _preMeshInfo->FullLoadFromFile();
3412 SMESH::long_array_var aResult = new SMESH::long_array();
3413 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3415 if ( aSMESHDS_Mesh == NULL )
3416 return aResult._retn();
3418 long nbNodes = NbNodes();
3419 aResult->length( nbNodes );
3420 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3421 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3422 aResult[i] = anIt->next()->GetID();
3424 return aResult._retn();
3427 //=============================================================================
3431 //=============================================================================
3433 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3434 throw (SALOME::SALOME_Exception)
3436 SMESH::ElementType type;
3440 _preMeshInfo->FullLoadFromFile();
3442 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3444 SMESH_CATCH( SMESH::throwCorbaException );
3449 //=============================================================================
3453 //=============================================================================
3455 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3456 throw (SALOME::SALOME_Exception)
3459 _preMeshInfo->FullLoadFromFile();
3461 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3463 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3465 return ( SMESH::EntityType ) e->GetEntityType();
3468 //=============================================================================
3470 * Returns ID of elements for given submesh
3472 //=============================================================================
3473 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3474 throw (SALOME::SALOME_Exception)
3476 SMESH::long_array_var aResult = new SMESH::long_array();
3480 _preMeshInfo->FullLoadFromFile();
3482 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3483 if(!SM) return aResult._retn();
3485 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3486 if(!SDSM) return aResult._retn();
3488 aResult->length(SDSM->NbElements());
3490 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3492 while ( eIt->more() ) {
3493 aResult[i++] = eIt->next()->GetID();
3496 SMESH_CATCH( SMESH::throwCorbaException );
3498 return aResult._retn();
3502 //=============================================================================
3504 * Returns ID of nodes for given submesh
3505 * If param all==true - returns all nodes, else -
3506 * returns only nodes on shapes.
3508 //=============================================================================
3509 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3511 throw (SALOME::SALOME_Exception)
3513 SMESH::long_array_var aResult = new SMESH::long_array();
3517 _preMeshInfo->FullLoadFromFile();
3519 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3520 if(!SM) return aResult._retn();
3522 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3523 if(!SDSM) return aResult._retn();
3526 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3527 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3528 while ( nIt->more() ) {
3529 const SMDS_MeshNode* elem = nIt->next();
3530 theElems.insert( elem->GetID() );
3533 else { // all nodes of submesh elements
3534 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3535 while ( eIt->more() ) {
3536 const SMDS_MeshElement* anElem = eIt->next();
3537 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3538 while ( nIt->more() ) {
3539 const SMDS_MeshElement* elem = nIt->next();
3540 theElems.insert( elem->GetID() );
3545 aResult->length(theElems.size());
3546 set<int>::iterator itElem;
3548 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3549 aResult[i++] = *itElem;
3551 SMESH_CATCH( SMESH::throwCorbaException );
3553 return aResult._retn();
3556 //=============================================================================
3558 * Returns type of elements for given submesh
3560 //=============================================================================
3562 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3563 throw (SALOME::SALOME_Exception)
3565 SMESH::ElementType type;
3569 _preMeshInfo->FullLoadFromFile();
3571 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3572 if(!SM) return SMESH::ALL;
3574 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3575 if(!SDSM) return SMESH::ALL;
3577 if(SDSM->NbElements()==0)
3578 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3580 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3581 const SMDS_MeshElement* anElem = eIt->next();
3583 type = ( SMESH::ElementType ) anElem->GetType();
3585 SMESH_CATCH( SMESH::throwCorbaException );
3591 //=============================================================================
3593 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3595 //=============================================================================
3597 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3600 _preMeshInfo->FullLoadFromFile();
3602 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3604 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3609 //=============================================================================
3611 * Get XYZ coordinates of node as list of double
3612 * If there is not node for given ID - returns empty list
3614 //=============================================================================
3616 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3619 _preMeshInfo->FullLoadFromFile();
3621 SMESH::double_array_var aResult = new SMESH::double_array();
3622 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3623 if ( aSMESHDS_Mesh == NULL )
3624 return aResult._retn();
3627 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3629 return aResult._retn();
3633 aResult[0] = aNode->X();
3634 aResult[1] = aNode->Y();
3635 aResult[2] = aNode->Z();
3636 return aResult._retn();
3640 //=============================================================================
3642 * For given node returns list of IDs of inverse elements
3643 * If there is not node for given ID - returns empty list
3645 //=============================================================================
3647 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3650 _preMeshInfo->FullLoadFromFile();
3652 SMESH::long_array_var aResult = new SMESH::long_array();
3653 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3654 if ( aSMESHDS_Mesh == NULL )
3655 return aResult._retn();
3658 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3660 return aResult._retn();
3662 // find inverse elements
3663 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3664 TColStd_SequenceOfInteger IDs;
3665 while(eIt->more()) {
3666 const SMDS_MeshElement* elem = eIt->next();
3667 IDs.Append(elem->GetID());
3669 if(IDs.Length()>0) {
3670 aResult->length(IDs.Length());
3672 for(; i<=IDs.Length(); i++) {
3673 aResult[i-1] = IDs.Value(i);
3676 return aResult._retn();
3679 //=============================================================================
3681 * \brief Return position of a node on shape
3683 //=============================================================================
3685 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3688 _preMeshInfo->FullLoadFromFile();
3690 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3691 aNodePosition->shapeID = 0;
3692 aNodePosition->shapeType = GEOM::SHAPE;
3694 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3695 if ( !mesh ) return aNodePosition;
3697 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3699 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3701 aNodePosition->shapeID = aNode->getshapeId();
3702 switch ( pos->GetTypeOfPosition() ) {
3704 aNodePosition->shapeType = GEOM::EDGE;
3705 aNodePosition->params.length(1);
3706 aNodePosition->params[0] =
3707 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3710 aNodePosition->shapeType = GEOM::FACE;
3711 aNodePosition->params.length(2);
3712 aNodePosition->params[0] =
3713 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3714 aNodePosition->params[1] =
3715 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3717 case SMDS_TOP_VERTEX:
3718 aNodePosition->shapeType = GEOM::VERTEX;
3720 case SMDS_TOP_3DSPACE:
3721 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3722 aNodePosition->shapeType = GEOM::SOLID;
3723 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3724 aNodePosition->shapeType = GEOM::SHELL;
3730 return aNodePosition;
3733 //=============================================================================
3735 * \brief Return position of an element on shape
3737 //=============================================================================
3739 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
3742 _preMeshInfo->FullLoadFromFile();
3744 SMESH::ElementPosition anElementPosition;
3745 anElementPosition.shapeID = 0;
3746 anElementPosition.shapeType = GEOM::SHAPE;
3748 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3749 if ( !mesh ) return anElementPosition;
3751 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
3753 anElementPosition.shapeID = anElem->getshapeId();
3754 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
3755 if ( !aSp.IsNull() ) {
3756 switch ( aSp.ShapeType() ) {
3758 anElementPosition.shapeType = GEOM::EDGE;
3761 anElementPosition.shapeType = GEOM::FACE;
3764 anElementPosition.shapeType = GEOM::VERTEX;
3767 anElementPosition.shapeType = GEOM::SOLID;
3770 anElementPosition.shapeType = GEOM::SHELL;
3776 return anElementPosition;
3779 //=============================================================================
3781 * If given element is node returns IDs of shape from position
3782 * If there is not node for given ID - returns -1
3784 //=============================================================================
3786 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3789 _preMeshInfo->FullLoadFromFile();
3791 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3792 if ( aSMESHDS_Mesh == NULL )
3796 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3798 return aNode->getshapeId();
3805 //=============================================================================
3807 * For given element returns ID of result shape after
3808 * ::FindShape() from SMESH_MeshEditor
3809 * If there is not element for given ID - returns -1
3811 //=============================================================================
3813 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3816 _preMeshInfo->FullLoadFromFile();
3818 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3819 if ( aSMESHDS_Mesh == NULL )
3822 // try to find element
3823 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3827 ::SMESH_MeshEditor aMeshEditor(_impl);
3828 int index = aMeshEditor.FindShape( elem );
3836 //=============================================================================
3838 * Returns number of nodes for given element
3839 * If there is not element for given ID - returns -1
3841 //=============================================================================
3843 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3846 _preMeshInfo->FullLoadFromFile();
3848 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3849 if ( aSMESHDS_Mesh == NULL ) return -1;
3850 // try to find element
3851 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3852 if(!elem) return -1;
3853 return elem->NbNodes();
3857 //=============================================================================
3859 * Returns ID of node by given index for given element
3860 * If there is not element for given ID - returns -1
3861 * If there is not node for given index - returns -2
3863 //=============================================================================
3865 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3868 _preMeshInfo->FullLoadFromFile();
3870 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3871 if ( aSMESHDS_Mesh == NULL ) return -1;
3872 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3873 if(!elem) return -1;
3874 if( index>=elem->NbNodes() || index<0 ) return -1;
3875 return elem->GetNode(index)->GetID();
3878 //=============================================================================
3880 * Returns IDs of nodes of given element
3882 //=============================================================================
3884 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3887 _preMeshInfo->FullLoadFromFile();
3889 SMESH::long_array_var aResult = new SMESH::long_array();
3890 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3892 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3894 aResult->length( elem->NbNodes() );
3895 for ( int i = 0; i < elem->NbNodes(); ++i )
3896 aResult[ i ] = elem->GetNode( i )->GetID();
3899 return aResult._retn();
3902 //=============================================================================
3904 * Returns true if given node is medium node
3905 * in given quadratic element
3907 //=============================================================================
3909 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3912 _preMeshInfo->FullLoadFromFile();
3914 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3915 if ( aSMESHDS_Mesh == NULL ) return false;
3917 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3918 if(!aNode) return false;
3919 // try to find element
3920 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3921 if(!elem) return false;
3923 return elem->IsMediumNode(aNode);
3927 //=============================================================================
3929 * Returns true if given node is medium node
3930 * in one of quadratic elements
3932 //=============================================================================
3934 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3935 SMESH::ElementType theElemType)
3938 _preMeshInfo->FullLoadFromFile();
3940 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3941 if ( aSMESHDS_Mesh == NULL ) return false;
3944 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3945 if(!aNode) return false;
3947 SMESH_MesherHelper aHelper( *(_impl) );
3949 SMDSAbs_ElementType aType;
3950 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3951 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3952 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3953 else aType = SMDSAbs_All;
3955 return aHelper.IsMedium(aNode,aType);
3959 //=============================================================================
3961 * Returns number of edges for given element
3963 //=============================================================================
3965 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3968 _preMeshInfo->FullLoadFromFile();
3970 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3971 if ( aSMESHDS_Mesh == NULL ) return -1;
3972 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3973 if(!elem) return -1;
3974 return elem->NbEdges();
3978 //=============================================================================
3980 * Returns number of faces for given element
3982 //=============================================================================
3984 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3987 _preMeshInfo->FullLoadFromFile();
3989 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3990 if ( aSMESHDS_Mesh == NULL ) return -1;
3991 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3992 if(!elem) return -1;
3993 return elem->NbFaces();
3996 //=======================================================================
3997 //function : GetElemFaceNodes
3998 //purpose : Returns nodes of given face (counted from zero) for given element.
3999 //=======================================================================
4001 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4002 CORBA::Short faceIndex)
4005 _preMeshInfo->FullLoadFromFile();
4007 SMESH::long_array_var aResult = new SMESH::long_array();
4008 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4010 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4012 SMDS_VolumeTool vtool( elem );
4013 if ( faceIndex < vtool.NbFaces() )
4015 aResult->length( vtool.NbFaceNodes( faceIndex ));
4016 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4017 for ( int i = 0; i < aResult->length(); ++i )
4018 aResult[ i ] = nn[ i ]->GetID();
4022 return aResult._retn();
4025 //=======================================================================
4026 //function : FindElementByNodes
4027 //purpose : Returns an element based on all given nodes.
4028 //=======================================================================
4030 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4033 _preMeshInfo->FullLoadFromFile();
4035 CORBA::Long elemID(0);
4036 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4038 vector< const SMDS_MeshNode * > nn( nodes.length() );
4039 for ( int i = 0; i < nodes.length(); ++i )
4040 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4043 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4044 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4045 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4046 _impl->NbVolumes( ORDER_QUADRATIC )))
4047 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4049 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4054 //=============================================================================
4056 * Returns true if given element is polygon
4058 //=============================================================================
4060 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4063 _preMeshInfo->FullLoadFromFile();
4065 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4066 if ( aSMESHDS_Mesh == NULL ) return false;
4067 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4068 if(!elem) return false;
4069 return elem->IsPoly();
4073 //=============================================================================
4075 * Returns true if given element is quadratic
4077 //=============================================================================
4079 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4082 _preMeshInfo->FullLoadFromFile();
4084 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4085 if ( aSMESHDS_Mesh == NULL ) return false;
4086 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4087 if(!elem) return false;
4088 return elem->IsQuadratic();
4091 //=============================================================================
4093 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4095 //=============================================================================
4097 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4100 _preMeshInfo->FullLoadFromFile();
4102 if ( const SMDS_BallElement* ball =
4103 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4104 return ball->GetDiameter();
4109 //=============================================================================
4111 * Returns bary center for given element
4113 //=============================================================================
4115 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4118 _preMeshInfo->FullLoadFromFile();
4120 SMESH::double_array_var aResult = new SMESH::double_array();
4121 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4122 if ( aSMESHDS_Mesh == NULL )
4123 return aResult._retn();
4125 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4127 return aResult._retn();
4129 if(elem->GetType()==SMDSAbs_Volume) {
4130 SMDS_VolumeTool aTool;
4131 if(aTool.Set(elem)) {
4133 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4138 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4140 double x=0., y=0., z=0.;
4141 for(; anIt->more(); ) {
4143 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4157 return aResult._retn();
4160 //================================================================================
4162 * \brief Create a group of elements preventing computation of a sub-shape
4164 //================================================================================
4166 SMESH::ListOfGroups*
4167 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4168 const char* theGroupName )
4169 throw ( SALOME::SALOME_Exception )
4171 Unexpect aCatch(SALOME_SalomeException);
4173 if ( !theGroupName || strlen( theGroupName) == 0 )
4174 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4176 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4178 // submesh by subshape id
4179 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4180 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4183 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4184 if ( error && !error->myBadElements.empty())
4186 // sort bad elements by type
4187 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4188 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4189 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4190 for ( ; elemIt != elemEnd; ++elemIt )
4192 const SMDS_MeshElement* elem = *elemIt;
4193 if ( !elem ) continue;
4195 if ( elem->GetID() < 1 )
4197 // elem is a temporary element, make a real element
4198 vector< const SMDS_MeshNode* > nodes;
4199 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4200 while ( nIt->more() && elem )
4202 nodes.push_back( nIt->next() );
4203 if ( nodes.back()->GetID() < 1 )
4204 elem = 0; // a temporary element on temporary nodes
4208 ::SMESH_MeshEditor editor( _impl );
4209 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4213 elemsByType[ elem->GetType() ].push_back( elem );
4216 // how many groups to create?
4218 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4219 nbTypes += int( !elemsByType[ i ].empty() );
4220 groups->length( nbTypes );
4223 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4225 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4226 if ( elems.empty() ) continue;
4228 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4229 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4231 SALOMEDS::SObject_wrap aSO =
4232 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), groups[ iG ],
4233 GEOM::GEOM_Object::_nil(), theGroupName);
4234 aSO->_is_nil(); // avoid "unused variable" warning
4236 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4237 if ( !grp_i ) continue;
4239 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4240 for ( size_t iE = 0; iE < elems.size(); ++iE )
4241 grpDS->SMDSGroup().Add( elems[ iE ]);
4246 return groups._retn();
4249 //=============================================================================
4251 * Create and publish group servants if any groups were imported or created anyhow
4253 //=============================================================================
4255 void SMESH_Mesh_i::CreateGroupServants()
4257 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4260 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4261 while ( groupIt->more() )
4263 ::SMESH_Group* group = groupIt->next();
4264 int anId = group->GetGroupDS()->GetID();
4266 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4267 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4269 addedIDs.insert( anId );
4271 SMESH_GroupBase_i* aGroupImpl;
4273 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4274 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4276 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4277 shape = groupOnGeom->GetShape();
4280 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4283 SMESH::SMESH_GroupBase_var groupVar =
4284 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4285 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4287 // register CORBA object for persistence
4288 int nextId = _gen_i->RegisterObject( groupVar );
4289 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4290 else { nextId = 0; } // avoid "unused variable" warning in release mode
4292 // publishing the groups in the study
4293 if ( !aStudy->_is_nil() ) {
4294 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4295 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4298 if ( !addedIDs.empty() )
4301 set<int>::iterator id = addedIDs.begin();
4302 for ( ; id != addedIDs.end(); ++id )
4304 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4305 int i = std::distance( _mapGroups.begin(), it );
4306 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4311 //=============================================================================
4313 * \brief Return groups cantained in _mapGroups by their IDs
4315 //=============================================================================
4317 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4319 int nbGroups = groupIDs.size();
4320 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4321 aList->length( nbGroups );
4323 list<int>::const_iterator ids = groupIDs.begin();
4324 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4326 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4327 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4328 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4330 aList->length( nbGroups );
4331 return aList._retn();
4334 //=============================================================================
4336 * \brief Return information about imported file
4338 //=============================================================================
4340 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4342 SMESH::MedFileInfo_var res( _medFileInfo );
4343 if ( !res.operator->() ) {
4344 res = new SMESH::MedFileInfo;
4346 res->fileSize = res->major = res->minor = res->release = -1;
4351 //=============================================================================
4353 * \brief Pass names of mesh groups from study to mesh DS
4355 //=============================================================================
4357 void SMESH_Mesh_i::checkGroupNames()
4359 int nbGrp = NbGroups();
4363 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4364 if ( aStudy->_is_nil() )
4365 return; // nothing to do
4367 SMESH::ListOfGroups* grpList = 0;
4368 // avoid dump of "GetGroups"
4370 // store python dump into a local variable inside local scope
4371 SMESH::TPythonDump pDump; // do not delete this line of code
4372 grpList = GetGroups();
4375 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4376 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4379 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4380 if ( aGrpSO->_is_nil() )
4382 // correct name of the mesh group if necessary
4383 const char* guiName = aGrpSO->GetName();
4384 if ( strcmp(guiName, aGrp->GetName()) )
4385 aGrp->SetName( guiName );
4389 //=============================================================================
4391 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4393 //=============================================================================
4394 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4396 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4400 //=============================================================================
4402 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4404 //=============================================================================
4405 char* SMESH_Mesh_i::GetParameters()
4407 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4408 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4411 //=============================================================================
4413 * \brief Returns list of notebook variables used for last Mesh operation
4415 //=============================================================================
4416 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4418 SMESH::string_array_var aResult = new SMESH::string_array();
4419 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4421 char *aParameters = GetParameters();
4422 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4423 if(!aStudy->_is_nil()) {
4424 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4425 if(aSections->length() > 0) {
4426 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4427 aResult->length(aVars.length());
4428 for(int i = 0;i < aVars.length();i++)
4429 aResult[i] = CORBA::string_dup( aVars[i]);
4433 return aResult._retn();
4436 //=======================================================================
4437 //function : GetTypes
4438 //purpose : Returns types of elements it contains
4439 //=======================================================================
4441 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4444 return _preMeshInfo->GetTypes();
4446 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4450 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4451 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4452 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4453 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4454 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4455 types->length( nbTypes );
4457 return types._retn();
4460 //=======================================================================
4461 //function : GetMesh
4462 //purpose : Returns self
4463 //=======================================================================
4465 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4467 return SMESH::SMESH_Mesh::_duplicate( _this() );
4470 //=======================================================================
4471 //function : IsMeshInfoCorrect
4472 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4473 // * happen if mesh data is not yet fully loaded from the file of study.
4474 //=======================================================================
4476 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4478 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4481 //=============================================================================
4483 * \brief Returns number of mesh elements per each \a EntityType
4485 //=============================================================================
4487 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4490 return _preMeshInfo->GetMeshInfo();
4492 SMESH::long_array_var aRes = new SMESH::long_array();
4493 aRes->length(SMESH::Entity_Last);
4494 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4496 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4498 return aRes._retn();
4499 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4500 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4501 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4502 return aRes._retn();
4505 //=============================================================================
4507 * \brief Returns number of mesh elements per each \a ElementType
4509 //=============================================================================
4511 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
4513 SMESH::long_array_var aRes = new SMESH::long_array();
4514 aRes->length(SMESH::NB_ELEMENT_TYPES);
4515 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4518 const SMDS_MeshInfo* meshInfo = 0;
4520 meshInfo = _preMeshInfo;
4521 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
4522 meshInfo = & meshDS->GetMeshInfo();
4525 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4526 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
4528 return aRes._retn();
4531 //=============================================================================
4533 * Collect statistic of mesh elements given by iterator
4535 //=============================================================================
4537 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4538 SMESH::long_array& theInfo)
4540 if (!theItr) return;
4541 while (theItr->more())
4542 theInfo[ theItr->next()->GetEntityType() ]++;
4545 //=============================================================================
4546 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
4547 * SMESH::ElementType type) */
4549 using namespace SMESH::Controls;
4550 //-----------------------------------------------------------------------------
4551 struct PredicateIterator : public SMDS_ElemIterator
4553 SMDS_ElemIteratorPtr _elemIter;
4554 PredicatePtr _predicate;
4555 const SMDS_MeshElement* _elem;
4557 PredicateIterator( SMDS_ElemIteratorPtr iterator,
4558 PredicatePtr predicate):
4559 _elemIter(iterator), _predicate(predicate)
4567 virtual const SMDS_MeshElement* next()
4569 const SMDS_MeshElement* res = _elem;
4571 while ( _elemIter->more() && !_elem )
4573 _elem = _elemIter->next();
4574 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
4581 //-----------------------------------------------------------------------------
4582 struct IDSourceIterator : public SMDS_ElemIterator
4584 const CORBA::Long* _idPtr;
4585 const CORBA::Long* _idEndPtr;
4586 SMESH::long_array_var _idArray;
4587 const SMDS_Mesh* _mesh;
4588 const SMDSAbs_ElementType _type;
4589 const SMDS_MeshElement* _elem;
4591 IDSourceIterator( const SMDS_Mesh* mesh,
4592 const CORBA::Long* ids,
4594 SMDSAbs_ElementType type):
4595 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
4597 if ( _idPtr && nbIds && _mesh )
4600 IDSourceIterator( const SMDS_Mesh* mesh,
4601 SMESH::long_array* idArray,
4602 SMDSAbs_ElementType type):
4603 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
4605 if ( idArray && _mesh )
4607 _idPtr = &_idArray[0];
4608 _idEndPtr = _idPtr + _idArray->length();
4616 virtual const SMDS_MeshElement* next()
4618 const SMDS_MeshElement* res = _elem;
4620 while ( _idPtr < _idEndPtr && !_elem )
4622 if ( _type == SMDSAbs_Node )
4624 _elem = _mesh->FindNode( *_idPtr++ );
4626 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
4627 _elem->GetType() != _type )
4635 //-----------------------------------------------------------------------------
4637 struct NodeOfElemIterator : public SMDS_ElemIterator
4639 TColStd_MapOfInteger _checkedNodeIDs;
4640 SMDS_ElemIteratorPtr _elemIter;
4641 SMDS_ElemIteratorPtr _nodeIter;
4642 const SMDS_MeshElement* _node;
4644 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
4646 if ( _elemIter && _elemIter->more() )
4648 _nodeIter = _elemIter->next()->nodesIterator();
4656 virtual const SMDS_MeshElement* next()
4658 const SMDS_MeshElement* res = _node;
4660 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
4662 if ( _nodeIter->more() )
4664 _node = _nodeIter->next();
4665 if ( !_checkedNodeIDs.Add( _node->GetID() ))
4670 _nodeIter = _elemIter->next()->nodesIterator();
4678 //=============================================================================
4680 * Return iterator on elements of given type in given object
4682 //=============================================================================
4684 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
4685 SMESH::ElementType theType)
4687 SMDS_ElemIteratorPtr elemIt;
4688 bool typeOK = false;
4689 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
4691 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
4692 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
4693 if ( !mesh_i ) return elemIt;
4694 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
4696 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
4698 elemIt = meshDS->elementsIterator( elemType );
4701 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
4703 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
4706 elemIt = sm->GetElements();
4707 if ( elemType != SMDSAbs_Node )
4709 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
4710 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
4714 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
4716 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
4717 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
4719 elemIt = groupDS->GetElements();
4720 typeOK = ( groupDS->GetType() == elemType );
4723 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
4725 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
4727 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
4728 if ( pred_i && pred_i->GetPredicate() )
4730 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
4731 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
4732 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
4733 typeOK = ( filterType == elemType );
4739 SMESH::array_of_ElementType_var types = theObject->GetTypes();
4740 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
4741 if ( isNodes && elemType != SMDSAbs_Node )
4743 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
4746 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
4747 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
4751 SMESH::long_array_var ids = theObject->GetIDs();
4752 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
4754 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
4757 if ( elemIt && elemIt->more() && !typeOK )
4759 if ( elemType == SMDSAbs_Node )
4761 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
4765 elemIt = SMDS_ElemIteratorPtr();
4771 //=============================================================================
4772 namespace // Finding concurrent hypotheses
4773 //=============================================================================
4777 * \brief mapping of mesh dimension into shape type
4779 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4781 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4783 case 0: aType = TopAbs_VERTEX; break;
4784 case 1: aType = TopAbs_EDGE; break;
4785 case 2: aType = TopAbs_FACE; break;
4787 default:aType = TopAbs_SOLID; break;
4792 //-----------------------------------------------------------------------------
4794 * \brief Internal structure used to find concurent submeshes
4796 * It represents a pair < submesh, concurent dimension >, where
4797 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4798 * with another submesh. In other words, it is dimension of a hypothesis assigned
4805 int _dim; //!< a dimension the algo can build (concurrent dimension)
4806 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4807 TopTools_MapOfShape _shapeMap;
4808 SMESH_subMesh* _subMesh;
4809 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4811 //-----------------------------------------------------------------------------
4812 // Return the algorithm
4813 const SMESH_Algo* GetAlgo() const
4814 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4816 //-----------------------------------------------------------------------------
4818 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4820 const TopoDS_Shape& theShape)
4822 _subMesh = (SMESH_subMesh*)theSubMesh;
4823 SetShape( theDim, theShape );
4826 //-----------------------------------------------------------------------------
4828 void SetShape(const int theDim,
4829 const TopoDS_Shape& theShape)
4832 _ownDim = SMESH_Gen::GetShapeDim(theShape);
4833 if (_dim >= _ownDim)
4834 _shapeMap.Add( theShape );
4836 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4837 for( ; anExp.More(); anExp.Next() )
4838 _shapeMap.Add( anExp.Current() );
4842 //-----------------------------------------------------------------------------
4843 //! Check sharing of sub-shapes
4844 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4845 const TopTools_MapOfShape& theToFind,
4846 const TopAbs_ShapeEnum theType)
4848 bool isShared = false;
4849 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4850 for (; !isShared && anItr.More(); anItr.Next() )
4852 const TopoDS_Shape aSubSh = anItr.Key();
4853 // check for case when concurrent dimensions are same
4854 isShared = theToFind.Contains( aSubSh );
4855 // check for sub-shape with concurrent dimension
4856 TopExp_Explorer anExp( aSubSh, theType );
4857 for ( ; !isShared && anExp.More(); anExp.Next() )
4858 isShared = theToFind.Contains( anExp.Current() );
4863 //-----------------------------------------------------------------------------
4864 //! check algorithms
4865 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4866 const SMESHDS_Hypothesis* theA2)
4868 if ( !theA1 || !theA2 ||
4869 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4870 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4871 return false; // one of the hypothesis is not algorithm
4872 // check algorithm names (should be equal)
4873 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4877 //-----------------------------------------------------------------------------
4878 //! Check if sub-shape hypotheses are concurrent
4879 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4881 if ( _subMesh == theOther->_subMesh )
4882 return false; // same sub-shape - should not be
4884 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4885 // any of the two submeshes is not on COMPOUND shape )
4886 // -> no concurrency
4887 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4888 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4889 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4890 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4891 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4894 // bool checkSubShape = ( _dim >= theOther->_dim )
4895 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4896 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4897 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4898 if ( !checkSubShape )
4901 // check algorithms to be same
4902 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4903 return true; // different algorithms -> concurrency !
4905 // check hypothesises for concurrence (skip first as algorithm)
4907 // pointers should be same, because it is referened from mesh hypothesis partition
4908 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4909 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4910 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4911 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4913 // the submeshes are concurrent if their algorithms has different parameters
4914 return nbSame != theOther->_hypotheses.size() - 1;
4917 // Return true if algorithm of this SMESH_DimHyp is used if no
4918 // sub-mesh order is imposed by the user
4919 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4921 // NeedDiscreteBoundary() algo has a higher priority
4922 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4923 theOther->GetAlgo()->NeedDiscreteBoundary() )
4924 return !this->GetAlgo()->NeedDiscreteBoundary();
4926 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4929 }; // end of SMESH_DimHyp
4930 //-----------------------------------------------------------------------------
4932 typedef list<const SMESH_DimHyp*> TDimHypList;
4934 //-----------------------------------------------------------------------------
4936 void addDimHypInstance(const int theDim,
4937 const TopoDS_Shape& theShape,
4938 const SMESH_Algo* theAlgo,
4939 const SMESH_subMesh* theSubMesh,
4940 const list <const SMESHDS_Hypothesis*>& theHypList,
4941 TDimHypList* theDimHypListArr )
4943 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4944 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4945 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4946 dimHyp->_hypotheses.push_front(theAlgo);
4947 listOfdimHyp.push_back( dimHyp );
4950 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4951 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4952 theHypList.begin(), theHypList.end() );
4955 //-----------------------------------------------------------------------------
4956 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4957 TDimHypList& theListOfConcurr)
4959 if ( theListOfConcurr.empty() )
4961 theListOfConcurr.push_back( theDimHyp );
4965 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4966 while ( hypIt != theListOfConcurr.end() &&
4967 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4969 theListOfConcurr.insert( hypIt, theDimHyp );
4973 //-----------------------------------------------------------------------------
4974 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4975 const TDimHypList& theListOfDimHyp,
4976 TDimHypList& theListOfConcurrHyp,
4977 set<int>& theSetOfConcurrId )
4979 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4980 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4982 const SMESH_DimHyp* curDimHyp = *rIt;
4983 if ( curDimHyp == theDimHyp )
4984 break; // meet own dimHyp pointer in same dimension
4986 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4987 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4989 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4994 //-----------------------------------------------------------------------------
4995 void unionLists(TListOfInt& theListOfId,
4996 TListOfListOfInt& theListOfListOfId,
4999 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5000 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5002 continue; //skip already treated lists
5003 // check if other list has any same submesh object
5004 TListOfInt& otherListOfId = *it;
5005 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5006 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5009 // union two lists (from source into target)
5010 TListOfInt::iterator it2 = otherListOfId.begin();
5011 for ( ; it2 != otherListOfId.end(); it2++ ) {
5012 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5013 theListOfId.push_back(*it2);
5015 // clear source list
5016 otherListOfId.clear();
5019 //-----------------------------------------------------------------------------
5021 //! free memory allocated for dimension-hypothesis objects
5022 void removeDimHyps( TDimHypList* theArrOfList )
5024 for (int i = 0; i < 4; i++ ) {
5025 TDimHypList& listOfdimHyp = theArrOfList[i];
5026 TDimHypList::const_iterator it = listOfdimHyp.begin();
5027 for ( ; it != listOfdimHyp.end(); it++ )
5032 //-----------------------------------------------------------------------------
5034 * \brief find common submeshes with given submesh
5035 * \param theSubMeshList list of already collected submesh to check
5036 * \param theSubMesh given submesh to intersect with other
5037 * \param theCommonSubMeshes collected common submeshes
5039 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5040 const SMESH_subMesh* theSubMesh,
5041 set<const SMESH_subMesh*>& theCommon )
5045 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5046 for ( ; it != theSubMeshList.end(); it++ )
5047 theSubMesh->FindIntersection( *it, theCommon );
5048 theSubMeshList.push_back( theSubMesh );
5049 //theCommon.insert( theSubMesh );
5054 //=============================================================================
5056 * \brief Return submesh objects list in meshing order
5058 //=============================================================================
5060 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5062 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5064 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5066 return aResult._retn();
5068 ::SMESH_Mesh& mesh = GetImpl();
5069 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
5070 if ( !anOrder.size() ) {
5072 // collect submeshes and detect concurrent algorithms and hypothesises
5073 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5075 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5076 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5077 ::SMESH_subMesh* sm = (*i_sm).second;
5079 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5081 // list of assigned hypothesises
5082 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5083 // Find out dimensions where the submesh can be concurrent.
5084 // We define the dimensions by algo of each of hypotheses in hypList
5085 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5086 for( ; hypIt != hypList.end(); hypIt++ ) {
5087 SMESH_Algo* anAlgo = 0;
5088 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5089 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5090 // hyp it-self is algo
5091 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5093 // try to find algorithm with help of sub-shapes
5094 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5095 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5096 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5099 continue; // no algorithm assigned to a current submesh
5101 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5102 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5104 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5105 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5106 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5108 } // end iterations on submesh
5110 // iterate on created dimension-hypotheses and check for concurrents
5111 for ( int i = 0; i < 4; i++ ) {
5112 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5113 // check for concurrents in own and other dimensions (step-by-step)
5114 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5115 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5116 const SMESH_DimHyp* dimHyp = *dhIt;
5117 TDimHypList listOfConcurr;
5118 set<int> setOfConcurrIds;
5119 // looking for concurrents and collect into own list
5120 for ( int j = i; j < 4; j++ )
5121 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5122 // check if any concurrents found
5123 if ( listOfConcurr.size() > 0 ) {
5124 // add own submesh to list of concurrent
5125 addInOrderOfPriority( dimHyp, listOfConcurr );
5126 list<int> listOfConcurrIds;
5127 TDimHypList::iterator hypIt = listOfConcurr.begin();
5128 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5129 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5130 anOrder.push_back( listOfConcurrIds );
5135 removeDimHyps(dimHypListArr);
5137 // now, minimise the number of concurrent groups
5138 // Here we assume that lists of submeshes can have same submesh
5139 // in case of multi-dimension algorithms, as result
5140 // list with common submesh has to be united into one list
5142 TListOfListOfInt::iterator listIt = anOrder.begin();
5143 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5144 unionLists( *listIt, anOrder, listIndx + 1 );
5146 // convert submesh ids into interface instances
5147 // and dump command into python
5148 convertMeshOrder( anOrder, aResult, false );
5150 return aResult._retn();
5153 //=============================================================================
5155 * \brief Set submesh object order
5156 * \param theSubMeshArray submesh array order
5158 //=============================================================================
5160 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5163 _preMeshInfo->ForgetOrLoad();
5166 ::SMESH_Mesh& mesh = GetImpl();
5168 TPythonDump aPythonDump; // prevent dump of called methods
5169 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
5171 TListOfListOfInt subMeshOrder;
5172 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5174 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5175 TListOfInt subMeshIds;
5176 aPythonDump << "[ ";
5177 // Collect subMeshes which should be clear
5178 // do it list-by-list, because modification of submesh order
5179 // take effect between concurrent submeshes only
5180 set<const SMESH_subMesh*> subMeshToClear;
5181 list<const SMESH_subMesh*> subMeshList;
5182 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5184 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5186 aPythonDump << ", ";
5187 aPythonDump << subMesh;
5188 subMeshIds.push_back( subMesh->GetId() );
5189 // detect common parts of submeshes
5190 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5191 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5193 aPythonDump << " ]";
5194 subMeshOrder.push_back( subMeshIds );
5196 // clear collected submeshes
5197 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5198 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5199 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5200 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5202 aPythonDump << " ])";
5204 mesh.SetMeshOrder( subMeshOrder );
5210 //=============================================================================
5212 * \brief Convert submesh ids into submesh interfaces
5214 //=============================================================================
5216 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5217 SMESH::submesh_array_array& theResOrder,
5218 const bool theIsDump)
5220 int nbSet = theIdsOrder.size();
5221 TPythonDump aPythonDump; // prevent dump of called methods
5223 aPythonDump << "[ ";
5224 theResOrder.length(nbSet);
5225 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5227 for( ; it != theIdsOrder.end(); it++ ) {
5228 // translate submesh identificators into submesh objects
5229 // takeing into account real number of concurrent lists
5230 const TListOfInt& aSubOrder = (*it);
5231 if (!aSubOrder.size())
5234 aPythonDump << "[ ";
5235 // convert shape indeces into interfaces
5236 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5237 aResSubSet->length(aSubOrder.size());
5238 TListOfInt::const_iterator subIt = aSubOrder.begin();
5239 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
5240 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5242 SMESH::SMESH_subMesh_var subMesh =
5243 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5246 aPythonDump << ", ";
5247 aPythonDump << subMesh;
5249 aResSubSet[ j++ ] = subMesh;
5252 aPythonDump << " ]";
5253 theResOrder[ listIndx++ ] = aResSubSet;
5255 // correct number of lists
5256 theResOrder.length( listIndx );
5259 // finilise python dump
5260 aPythonDump << " ]";
5261 aPythonDump << " = " << _this() << ".GetMeshOrder()";
5265 //================================================================================
5267 // Implementation of SMESH_MeshPartDS
5269 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5270 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5272 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5273 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5275 _meshDS = mesh_i->GetImpl().GetMeshDS();
5277 SetPersistentId( _meshDS->GetPersistentId() );
5279 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5281 // <meshPart> is the whole mesh
5282 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5284 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5285 myGroupSet = _meshDS->GetGroups();
5290 SMESH::long_array_var anIDs = meshPart->GetIDs();
5291 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5292 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5294 for (int i=0; i < anIDs->length(); i++)
5295 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5296 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5301 for (int i=0; i < anIDs->length(); i++)
5302 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5303 if ( _elements[ e->GetType() ].insert( e ).second )
5306 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5307 while ( nIt->more() )
5309 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5310 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5317 _meshDS = 0; // to enforce iteration on _elements and _nodes
5320 // -------------------------------------------------------------------------------------
5321 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5322 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5325 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5326 for ( ; partIt != meshPart.end(); ++partIt )
5327 if ( const SMDS_MeshElement * e = *partIt )
5328 if ( _elements[ e->GetType() ].insert( e ).second )
5331 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5332 while ( nIt->more() )
5334 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5335 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5341 // -------------------------------------------------------------------------------------
5342 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5344 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5346 typedef SMDS_SetIterator
5347 <const SMDS_MeshElement*,
5348 TIDSortedElemSet::const_iterator,
5349 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5350 SMDS_MeshElement::GeomFilter
5353 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5355 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5356 _elements[type].end(),
5357 SMDS_MeshElement::GeomFilter( geomType )));
5359 // -------------------------------------------------------------------------------------
5360 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5362 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5364 typedef SMDS_SetIterator
5365 <const SMDS_MeshElement*,
5366 TIDSortedElemSet::const_iterator,
5367 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5368 SMDS_MeshElement::EntityFilter
5371 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5373 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5374 _elements[type].end(),
5375 SMDS_MeshElement::EntityFilter( entity )));
5377 // -------------------------------------------------------------------------------------
5378 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5380 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5381 if ( type == SMDSAbs_All && !_meshDS )
5383 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5385 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5386 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5388 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5390 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5391 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5393 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5394 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5396 // -------------------------------------------------------------------------------------
5397 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5398 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5400 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5401 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5402 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5404 // -------------------------------------------------------------------------------------
5405 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5406 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5407 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5408 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5409 #undef _GET_ITER_DEFINE
5411 // END Implementation of SMESH_MeshPartDS
5413 //================================================================================