1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_Filter_i.hxx"
45 #include "SMESH_Gen_i.hxx"
46 #include "SMESH_Group.hxx"
47 #include "SMESH_Group_i.hxx"
48 #include "SMESH_MeshAlgos.hxx"
49 #include "SMESH_MeshEditor.hxx"
50 #include "SMESH_MeshEditor_i.hxx"
51 #include "SMESH_MeshPartDS.hxx"
52 #include "SMESH_MesherHelper.hxx"
53 #include "SMESH_PreMeshInfo.hxx"
54 #include "SMESH_PythonDump.hxx"
55 #include "SMESH_subMesh_i.hxx"
58 #include <SALOMEDS_Attributes_wrap.hxx>
59 #include <SALOMEDS_wrap.hxx>
60 #include <SALOME_NamingService.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <Utils_SINGLETON.hxx>
63 #include <utilities.h>
65 #include <GEOMImpl_Types.hxx>
66 #include <GEOM_wrap.hxx>
69 #include <BRep_Builder.hxx>
70 #include <OSD_Directory.hxx>
71 #include <OSD_File.hxx>
72 #include <OSD_Path.hxx>
73 #include <OSD_Protection.hxx>
74 #include <Standard_OutOfMemory.hxx>
75 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
76 #include <TColStd_MapOfInteger.hxx>
77 #include <TColStd_SequenceOfInteger.hxx>
78 #include <TCollection_AsciiString.hxx>
80 #include <TopExp_Explorer.hxx>
81 #include <TopTools_MapIteratorOfMapOfShape.hxx>
82 #include <TopTools_MapOfShape.hxx>
83 #include <TopoDS_Compound.hxx>
93 // to pass CORBA exception through SMESH_TRY
94 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
96 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
99 static int MYDEBUG = 0;
101 static int MYDEBUG = 0;
105 using SMESH::TPythonDump;
107 int SMESH_Mesh_i::_idGenerator = 0;
109 //=============================================================================
113 //=============================================================================
115 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
117 CORBA::Long studyId )
118 : SALOME::GenericObj_i( thePOA )
120 MESSAGE("SMESH_Mesh_i");
123 _id = _idGenerator++;
126 _previewEditor = NULL;
130 //=============================================================================
134 //=============================================================================
136 SMESH_Mesh_i::~SMESH_Mesh_i()
138 MESSAGE("~SMESH_Mesh_i");
141 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
142 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
143 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
145 aGroup->UnRegister();
146 SMESH::SMESH_GroupBase_var( itGr->second );
151 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
152 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
153 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
155 aSubMesh->UnRegister();
156 SMESH::SMESH_subMesh_var( itSM->second );
158 _mapSubMeshIor.clear();
160 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
161 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
162 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
163 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
164 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
165 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
168 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
172 delete _editor; _editor = NULL;
173 delete _previewEditor; _previewEditor = NULL;
174 delete _impl; _impl = NULL;
175 delete _preMeshInfo; _preMeshInfo = NULL;
178 //=============================================================================
182 * Associates <this> mesh with <theShape> and puts a reference
183 * to <theShape> into the current study;
184 * the previous shape is substituted by the new one.
186 //=============================================================================
188 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
189 throw (SALOME::SALOME_Exception)
191 Unexpect aCatch(SALOME_SalomeException);
193 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
195 catch(SALOME_Exception & S_ex) {
196 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
198 // to track changes of GEOM groups
199 SMESH::SMESH_Mesh_var mesh = _this();
200 addGeomGroupData( theShapeObject, mesh );
203 //================================================================================
205 * \brief return true if mesh has a shape to build a shape on
207 //================================================================================
209 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
210 throw (SALOME::SALOME_Exception)
212 Unexpect aCatch(SALOME_SalomeException);
215 res = _impl->HasShapeToMesh();
217 catch(SALOME_Exception & S_ex) {
218 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
223 //=======================================================================
224 //function : GetShapeToMesh
226 //=======================================================================
228 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
229 throw (SALOME::SALOME_Exception)
231 Unexpect aCatch(SALOME_SalomeException);
232 GEOM::GEOM_Object_var aShapeObj;
234 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
236 aShapeObj = _gen_i->ShapeToGeomObject( S );
238 catch(SALOME_Exception & S_ex) {
239 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
241 return aShapeObj._retn();
244 //================================================================================
246 * \brief Return false if the mesh is not yet fully loaded from the study file
248 //================================================================================
250 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
252 Unexpect aCatch(SALOME_SalomeException);
253 return !_preMeshInfo;
256 //================================================================================
258 * \brief Load full mesh data from the study file
260 //================================================================================
262 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
264 Unexpect aCatch(SALOME_SalomeException);
266 _preMeshInfo->FullLoadFromFile();
269 //================================================================================
271 * \brief Remove all nodes and elements
273 //================================================================================
275 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
277 Unexpect aCatch(SALOME_SalomeException);
279 _preMeshInfo->ForgetAllData();
283 CheckGeomGroupModif(); // issue 20145
285 catch(SALOME_Exception & S_ex) {
286 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
288 _impl->GetMeshDS()->Modified();
290 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
293 //================================================================================
295 * \brief Remove all nodes and elements for indicated shape
297 //================================================================================
299 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
300 throw (SALOME::SALOME_Exception)
302 Unexpect aCatch(SALOME_SalomeException);
304 _preMeshInfo->FullLoadFromFile();
307 _impl->ClearSubMesh( ShapeID );
309 catch(SALOME_Exception & S_ex) {
310 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
312 _impl->GetMeshDS()->Modified();
314 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
317 //=============================================================================
319 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
321 //=============================================================================
323 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
325 SMESH::DriverMED_ReadStatus res;
328 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
329 res = SMESH::DRS_OK; break;
330 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
331 res = SMESH::DRS_EMPTY; break;
332 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
333 res = SMESH::DRS_WARN_RENUMBER; break;
334 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
335 res = SMESH::DRS_WARN_SKIP_ELEM; break;
336 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
337 res = SMESH::DRS_WARN_DESCENDING; break;
338 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
340 res = SMESH::DRS_FAIL; break;
345 //=============================================================================
347 * Convert ::SMESH_ComputeError to SMESH::ComputeError
349 //=============================================================================
351 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
353 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
354 errVar->subShapeID = -1;
355 errVar->hasBadMesh = false;
357 if ( !errorPtr || errorPtr->IsOK() )
359 errVar->code = SMESH::COMPERR_OK;
363 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
364 errVar->comment = errorPtr->myComment.c_str();
366 return errVar._retn();
369 //=============================================================================
373 * Imports mesh data from MED file
375 //=============================================================================
377 SMESH::DriverMED_ReadStatus
378 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
379 throw ( SALOME::SALOME_Exception )
381 Unexpect aCatch(SALOME_SalomeException);
384 status = _impl->MEDToMesh( theFileName, theMeshName );
386 catch( SALOME_Exception& S_ex ) {
387 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
390 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
393 CreateGroupServants();
395 int major, minor, release;
396 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
397 major = minor = release = -1;
398 _medFileInfo = new SMESH::MedFileInfo();
399 _medFileInfo->fileName = theFileName;
400 _medFileInfo->fileSize = 0;
401 _medFileInfo->major = major;
402 _medFileInfo->minor = minor;
403 _medFileInfo->release = release;
406 if ( ::_stati64( theFileName, &d ) != -1 )
409 if ( ::stat64( theFileName, &d ) != -1 )
411 _medFileInfo->fileSize = d.st_size;
413 return ConvertDriverMEDReadStatus(status);
416 //================================================================================
418 * \brief Imports mesh data from the CGNS file
420 //================================================================================
422 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
423 const int theMeshIndex,
424 std::string& theMeshName )
425 throw ( SALOME::SALOME_Exception )
427 Unexpect aCatch(SALOME_SalomeException);
430 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
432 catch( SALOME_Exception& S_ex ) {
433 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
436 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
439 CreateGroupServants();
441 return ConvertDriverMEDReadStatus(status);
444 //================================================================================
446 * \brief Return string representation of a MED file version comprising nbDigits
448 //================================================================================
450 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
452 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
454 return CORBA::string_dup( ver.c_str() );
457 //=============================================================================
461 * Imports mesh data from MED file
463 //=============================================================================
465 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
466 throw ( SALOME::SALOME_Exception )
470 // Read mesh with name = <theMeshName> into SMESH_Mesh
471 _impl->UNVToMesh( theFileName );
473 CreateGroupServants();
475 SMESH_CATCH( SMESH::throwCorbaException );
480 //=============================================================================
484 * Imports mesh data from STL file
486 //=============================================================================
487 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
488 throw ( SALOME::SALOME_Exception )
492 // Read mesh with name = <theMeshName> into SMESH_Mesh
493 _impl->STLToMesh( theFileName );
495 SMESH_CATCH( SMESH::throwCorbaException );
500 //================================================================================
502 * \brief Function used in SMESH_CATCH by ImportGMFFile()
504 //================================================================================
508 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
510 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
514 //================================================================================
516 * \brief Imports data from a GMF file and returns an error description
518 //================================================================================
520 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
521 bool theMakeRequiredGroups )
522 throw (SALOME::SALOME_Exception)
524 SMESH_ComputeErrorPtr error;
527 #define SMESH_CAUGHT error =
530 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
532 SMESH_CATCH( exceptionToComputeError );
536 CreateGroupServants();
538 return ConvertComputeError( error );
541 //=============================================================================
545 //=============================================================================
547 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
549 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
550 (SMESH_Hypothesis::Hypothesis_Status theStatus)
553 RETURNCASE( HYP_OK );
554 RETURNCASE( HYP_MISSING );
555 RETURNCASE( HYP_CONCURENT );
556 RETURNCASE( HYP_BAD_PARAMETER );
557 RETURNCASE( HYP_HIDDEN_ALGO );
558 RETURNCASE( HYP_HIDING_ALGO );
559 RETURNCASE( HYP_UNKNOWN_FATAL );
560 RETURNCASE( HYP_INCOMPATIBLE );
561 RETURNCASE( HYP_NOTCONFORM );
562 RETURNCASE( HYP_ALREADY_EXIST );
563 RETURNCASE( HYP_BAD_DIM );
564 RETURNCASE( HYP_BAD_SUBSHAPE );
565 RETURNCASE( HYP_BAD_GEOMETRY );
566 RETURNCASE( HYP_NEED_SHAPE );
569 return SMESH::HYP_UNKNOWN_FATAL;
572 //=============================================================================
576 * calls internal addHypothesis() and then adds a reference to <anHyp> under
577 * the SObject actually having a reference to <aSubShape>.
578 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
580 //=============================================================================
582 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
583 SMESH::SMESH_Hypothesis_ptr anHyp)
584 throw(SALOME::SALOME_Exception)
586 Unexpect aCatch(SALOME_SalomeException);
588 _preMeshInfo->ForgetOrLoad();
590 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
592 SMESH::SMESH_Mesh_var mesh( _this() );
593 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
595 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
596 _gen_i->AddHypothesisToShape( study, mesh, aSubShapeObject, anHyp );
598 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
600 // Update Python script
601 //if(_impl->HasShapeToMesh())
603 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
604 << aSubShapeObject << ", " << anHyp << " )";
607 // TPythonDump() << "status = " << mesh << ".AddHypothesis( "<< anHyp << " )";
610 return ConvertHypothesisStatus(status);
613 //=============================================================================
617 //=============================================================================
619 SMESH_Hypothesis::Hypothesis_Status
620 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
621 SMESH::SMESH_Hypothesis_ptr anHyp)
623 if(MYDEBUG) MESSAGE("addHypothesis");
625 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
626 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
628 if (CORBA::is_nil( anHyp ))
629 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
631 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
634 TopoDS_Shape myLocSubShape;
635 //use PseudoShape in case if mesh has no shape
637 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
639 myLocSubShape = _impl->GetShapeToMesh();
641 const int hypId = anHyp->GetId();
642 status = _impl->AddHypothesis(myLocSubShape, hypId);
643 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
644 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
646 // assure there is a corresponding submesh
647 if ( !_impl->IsMainShape( myLocSubShape )) {
648 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
649 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
650 SMESH::SMESH_subMesh_var( createSubMesh( aSubShapeObject ));
654 catch(SALOME_Exception & S_ex)
656 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
661 //=============================================================================
665 //=============================================================================
667 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
668 SMESH::SMESH_Hypothesis_ptr anHyp)
669 throw(SALOME::SALOME_Exception)
671 Unexpect aCatch(SALOME_SalomeException);
673 _preMeshInfo->ForgetOrLoad();
675 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
676 SMESH::SMESH_Mesh_var mesh = _this();
678 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
680 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
681 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShapeObject, anHyp );
683 // Update Python script
684 if(_impl->HasShapeToMesh())
685 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
686 << aSubShapeObject << ", " << anHyp << " )";
688 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
691 return ConvertHypothesisStatus(status);
694 //=============================================================================
698 //=============================================================================
700 SMESH_Hypothesis::Hypothesis_Status
701 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
702 SMESH::SMESH_Hypothesis_ptr anHyp)
704 if(MYDEBUG) MESSAGE("removeHypothesis()");
706 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
707 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
709 if (CORBA::is_nil( anHyp ))
710 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
712 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
715 TopoDS_Shape myLocSubShape;
716 //use PseudoShape in case if mesh has no shape
717 if( _impl->HasShapeToMesh() )
718 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject );
720 myLocSubShape = _impl->GetShapeToMesh();
722 const int hypId = anHyp->GetId();
723 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
724 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
726 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
730 catch(SALOME_Exception & S_ex)
732 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
737 //=============================================================================
741 //=============================================================================
743 SMESH::ListOfHypothesis *
744 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
745 throw(SALOME::SALOME_Exception)
747 Unexpect aCatch(SALOME_SalomeException);
748 if (MYDEBUG) MESSAGE("GetHypothesisList");
749 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
750 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
752 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
755 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
756 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
757 myLocSubShape = _impl->GetShapeToMesh();
758 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
759 int i = 0, n = aLocalList.size();
762 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
763 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
764 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
766 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
767 if ( id_hypptr != _mapHypo.end() )
768 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
772 catch(SALOME_Exception & S_ex) {
773 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
776 return aList._retn();
779 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
781 Unexpect aCatch(SALOME_SalomeException);
782 if (MYDEBUG) MESSAGE("GetSubMeshes");
784 SMESH::submesh_array_var aList = new SMESH::submesh_array();
787 TPythonDump aPythonDump;
788 if ( !_mapSubMeshIor.empty() )
792 aList->length( _mapSubMeshIor.size() );
794 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
795 for ( ; it != _mapSubMeshIor.end(); it++ ) {
796 if ( CORBA::is_nil( it->second )) continue;
797 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
799 if (i > 1) aPythonDump << ", ";
800 aPythonDump << it->second;
804 catch(SALOME_Exception & S_ex) {
805 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
808 // Update Python script
809 if ( !_mapSubMeshIor.empty() )
810 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
812 return aList._retn();
815 //=============================================================================
819 //=============================================================================
821 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
822 const char* theName )
823 throw(SALOME::SALOME_Exception)
825 Unexpect aCatch(SALOME_SalomeException);
826 if (CORBA::is_nil(aSubShapeObject))
827 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
829 SMESH::SMESH_subMesh_var subMesh;
830 SMESH::SMESH_Mesh_var aMesh = _this();
832 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
834 //Get or Create the SMESH_subMesh object implementation
836 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
838 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
840 TopoDS_Iterator it( myLocSubShape );
842 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
844 subMesh = getSubMesh( subMeshId );
846 // create a new subMesh object servant if there is none for the shape
847 if ( subMesh->_is_nil() )
848 subMesh = createSubMesh( aSubShapeObject );
849 if ( _gen_i->CanPublishInStudy( subMesh ))
851 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
852 SALOMEDS::SObject_wrap aSO =
853 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShapeObject, theName );
854 if ( !aSO->_is_nil()) {
855 // Update Python script
856 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
857 << aSubShapeObject << ", '" << theName << "' )";
861 catch(SALOME_Exception & S_ex) {
862 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
864 return subMesh._retn();
867 //=============================================================================
871 //=============================================================================
873 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
874 throw (SALOME::SALOME_Exception)
878 if ( theSubMesh->_is_nil() )
881 GEOM::GEOM_Object_var aSubShapeObject;
882 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
883 if ( !aStudy->_is_nil() ) {
884 // Remove submesh's SObject
885 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
886 if ( !anSO->_is_nil() ) {
887 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
888 SALOMEDS::SObject_wrap anObj, aRef;
889 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
890 anObj->ReferencedObject( aRef.inout() ))
892 CORBA::Object_var obj = aRef->GetObject();
893 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
895 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
896 // aSubShapeObject = theSubMesh->GetSubShape();
898 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
899 builder->RemoveObjectWithChildren( anSO );
901 // Update Python script
902 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
906 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
908 _preMeshInfo->ForgetOrLoad();
910 SMESH_CATCH( SMESH::throwCorbaException );
913 //=============================================================================
917 //=============================================================================
919 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
920 const char* theName )
921 throw(SALOME::SALOME_Exception)
923 Unexpect aCatch(SALOME_SalomeException);
925 _preMeshInfo->FullLoadFromFile();
927 SMESH::SMESH_Group_var aNewGroup =
928 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
930 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
932 SMESH::SMESH_Mesh_var mesh = _this();
933 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
934 SALOMEDS::SObject_wrap aSO =
935 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
936 if ( !aSO->_is_nil())
937 // Update Python script
938 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
939 << theElemType << ", '" << theName << "' )";
941 return aNewGroup._retn();
944 //=============================================================================
948 //=============================================================================
949 SMESH::SMESH_GroupOnGeom_ptr
950 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
952 GEOM::GEOM_Object_ptr theGeomObj)
953 throw(SALOME::SALOME_Exception)
955 Unexpect aCatch(SALOME_SalomeException);
957 _preMeshInfo->FullLoadFromFile();
959 SMESH::SMESH_GroupOnGeom_var aNewGroup;
961 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
962 if ( !aShape.IsNull() )
965 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
967 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
969 SMESH::SMESH_Mesh_var mesh = _this();
970 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
971 SALOMEDS::SObject_wrap aSO =
972 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
973 if ( !aSO->_is_nil())
974 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
975 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
979 return aNewGroup._retn();
982 //================================================================================
984 * \brief Creates a group whose contents is defined by filter
985 * \param theElemType - group type
986 * \param theName - group name
987 * \param theFilter - the filter
988 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
990 //================================================================================
992 SMESH::SMESH_GroupOnFilter_ptr
993 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
995 SMESH::Filter_ptr theFilter )
996 throw (SALOME::SALOME_Exception)
998 Unexpect aCatch(SALOME_SalomeException);
1000 _preMeshInfo->FullLoadFromFile();
1002 if ( CORBA::is_nil( theFilter ))
1003 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1005 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1007 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1009 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1010 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1013 if ( !aNewGroup->_is_nil() )
1014 aNewGroup->SetFilter( theFilter );
1016 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1018 SMESH::SMESH_Mesh_var mesh = _this();
1019 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1020 SALOMEDS::SObject_wrap aSO =
1021 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1023 if ( !aSO->_is_nil())
1024 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1025 << theElemType << ", '" << theName << "', " << theFilter << " )";
1027 return aNewGroup._retn();
1030 //=============================================================================
1034 //=============================================================================
1036 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1037 throw (SALOME::SALOME_Exception)
1039 if ( theGroup->_is_nil() )
1044 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1048 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1049 if ( !aStudy->_is_nil() )
1051 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1052 if ( !aGroupSO->_is_nil() )
1054 // Update Python script
1055 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1057 // Remove group's SObject
1058 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1059 builder->RemoveObjectWithChildren( aGroupSO );
1063 // Remove the group from SMESH data structures
1064 removeGroup( aGroup->GetLocalID() );
1066 SMESH_CATCH( SMESH::throwCorbaException );
1069 //=============================================================================
1071 * Remove group with its contents
1073 //=============================================================================
1075 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1076 throw (SALOME::SALOME_Exception)
1080 _preMeshInfo->FullLoadFromFile();
1082 if ( theGroup->_is_nil() )
1086 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1087 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1088 while ( elemIt->more() )
1089 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1091 TPythonDump pyDump; // Supress dump from RemoveGroup()
1093 // Update Python script (theGroup must be alive for this)
1094 pyDump << SMESH::SMESH_Mesh_var(_this())
1095 << ".RemoveGroupWithContents( " << theGroup << " )";
1098 RemoveGroup( theGroup );
1100 SMESH_CATCH( SMESH::throwCorbaException );
1103 //================================================================================
1105 * \brief Get the list of groups existing in the mesh
1106 * \retval SMESH::ListOfGroups * - list of groups
1108 //================================================================================
1110 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1112 Unexpect aCatch(SALOME_SalomeException);
1113 if (MYDEBUG) MESSAGE("GetGroups");
1115 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1118 TPythonDump aPythonDump;
1119 if ( !_mapGroups.empty() )
1121 aPythonDump << "[ ";
1123 aList->length( _mapGroups.size() );
1125 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1126 for ( ; it != _mapGroups.end(); it++ ) {
1127 if ( CORBA::is_nil( it->second )) continue;
1128 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1130 if (i > 1) aPythonDump << ", ";
1131 aPythonDump << it->second;
1135 catch(SALOME_Exception & S_ex) {
1136 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1138 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1140 return aList._retn();
1143 //=============================================================================
1145 * Get number of groups existing in the mesh
1147 //=============================================================================
1149 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1151 Unexpect aCatch(SALOME_SalomeException);
1152 return _mapGroups.size();
1155 //=============================================================================
1157 * New group including all mesh elements present in initial groups is created.
1159 //=============================================================================
1161 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1162 SMESH::SMESH_GroupBase_ptr theGroup2,
1163 const char* theName )
1164 throw (SALOME::SALOME_Exception)
1166 SMESH::SMESH_Group_var aResGrp;
1170 _preMeshInfo->FullLoadFromFile();
1172 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1173 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1175 if ( theGroup1->GetType() != theGroup2->GetType() )
1176 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1181 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1182 if ( aResGrp->_is_nil() )
1183 return SMESH::SMESH_Group::_nil();
1185 aResGrp->AddFrom( theGroup1 );
1186 aResGrp->AddFrom( theGroup2 );
1188 // Update Python script
1189 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1190 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1192 SMESH_CATCH( SMESH::throwCorbaException );
1194 return aResGrp._retn();
1197 //=============================================================================
1199 * \brief New group including all mesh elements present in initial groups is created.
1200 * \param theGroups list of groups
1201 * \param theName name of group to be created
1202 * \return pointer to the new group
1204 //=============================================================================
1206 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1207 const char* theName )
1208 throw (SALOME::SALOME_Exception)
1210 SMESH::SMESH_Group_var aResGrp;
1213 _preMeshInfo->FullLoadFromFile();
1216 return SMESH::SMESH_Group::_nil();
1221 SMESH::ElementType aType = SMESH::ALL;
1222 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1224 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1225 if ( CORBA::is_nil( aGrp ) )
1227 if ( aType == SMESH::ALL )
1228 aType = aGrp->GetType();
1229 else if ( aType != aGrp->GetType() )
1230 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1233 if ( aType == SMESH::ALL )
1234 return SMESH::SMESH_Group::_nil();
1239 aResGrp = CreateGroup( aType, theName );
1240 if ( aResGrp->_is_nil() )
1241 return SMESH::SMESH_Group::_nil();
1243 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1244 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1246 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1247 if ( !CORBA::is_nil( aGrp ) )
1249 aResGrp->AddFrom( aGrp );
1250 if ( g > 0 ) pyDump << ", ";
1254 pyDump << " ], '" << theName << "' )";
1256 SMESH_CATCH( SMESH::throwCorbaException );
1258 return aResGrp._retn();
1261 //=============================================================================
1263 * New group is created. All mesh elements that are
1264 * present in both initial groups are added to the new one.
1266 //=============================================================================
1268 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1269 SMESH::SMESH_GroupBase_ptr theGroup2,
1270 const char* theName )
1271 throw (SALOME::SALOME_Exception)
1273 SMESH::SMESH_Group_var aResGrp;
1278 _preMeshInfo->FullLoadFromFile();
1280 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1281 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1283 if ( theGroup1->GetType() != theGroup2->GetType() )
1284 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1288 // Create Intersection
1289 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1290 if ( aResGrp->_is_nil() )
1291 return aResGrp._retn();
1293 SMESHDS_GroupBase* groupDS1 = 0;
1294 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1295 groupDS1 = grp_i->GetGroupDS();
1297 SMESHDS_GroupBase* groupDS2 = 0;
1298 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1299 groupDS2 = grp_i->GetGroupDS();
1301 SMESHDS_Group* resGroupDS = 0;
1302 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1303 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1305 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1307 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1308 while ( elemIt1->more() )
1310 const SMDS_MeshElement* e = elemIt1->next();
1311 if ( groupDS2->Contains( e ))
1312 resGroupDS->SMDSGroup().Add( e );
1315 // Update Python script
1316 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1317 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1319 SMESH_CATCH( SMESH::throwCorbaException );
1321 return aResGrp._retn();
1324 //=============================================================================
1326 \brief Intersect list of groups. New group is created. All mesh elements that
1327 are present in all initial groups simultaneously are added to the new one.
1328 \param theGroups list of groups
1329 \param theName name of group to be created
1330 \return pointer on the group
1332 //=============================================================================
1333 SMESH::SMESH_Group_ptr
1334 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1335 const char* theName )
1336 throw (SALOME::SALOME_Exception)
1338 SMESH::SMESH_Group_var aResGrp;
1343 _preMeshInfo->FullLoadFromFile();
1346 return SMESH::SMESH_Group::_nil();
1348 // check types and get SMESHDS_GroupBase's
1349 SMESH::ElementType aType = SMESH::ALL;
1350 vector< SMESHDS_GroupBase* > groupVec;
1351 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1353 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1354 if ( CORBA::is_nil( aGrp ) )
1356 if ( aType == SMESH::ALL )
1357 aType = aGrp->GetType();
1358 else if ( aType != aGrp->GetType() )
1359 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1362 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1363 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1365 if ( grpDS->IsEmpty() )
1370 groupVec.push_back( grpDS );
1373 if ( aType == SMESH::ALL ) // all groups are nil
1374 return SMESH::SMESH_Group::_nil();
1379 aResGrp = CreateGroup( aType, theName );
1381 SMESHDS_Group* resGroupDS = 0;
1382 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1383 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1384 if ( !resGroupDS || groupVec.empty() )
1385 return aResGrp._retn();
1388 size_t i, nb = groupVec.size();
1389 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1390 while ( elemIt1->more() )
1392 const SMDS_MeshElement* e = elemIt1->next();
1394 for ( i = 1; ( i < nb && inAll ); ++i )
1395 inAll = groupVec[i]->Contains( e );
1398 resGroupDS->SMDSGroup().Add( e );
1401 // Update Python script
1402 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1403 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1405 SMESH_CATCH( SMESH::throwCorbaException );
1407 return aResGrp._retn();
1410 //=============================================================================
1412 * New group is created. All mesh elements that are present in
1413 * a main group but is not present in a tool group are added to the new one
1415 //=============================================================================
1417 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1418 SMESH::SMESH_GroupBase_ptr theGroup2,
1419 const char* theName )
1420 throw (SALOME::SALOME_Exception)
1422 SMESH::SMESH_Group_var aResGrp;
1427 _preMeshInfo->FullLoadFromFile();
1429 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1430 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1432 if ( theGroup1->GetType() != theGroup2->GetType() )
1433 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1437 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1438 if ( aResGrp->_is_nil() )
1439 return aResGrp._retn();
1441 SMESHDS_GroupBase* groupDS1 = 0;
1442 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1443 groupDS1 = grp_i->GetGroupDS();
1445 SMESHDS_GroupBase* groupDS2 = 0;
1446 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1447 groupDS2 = grp_i->GetGroupDS();
1449 SMESHDS_Group* resGroupDS = 0;
1450 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1451 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1453 if ( groupDS1 && groupDS2 && resGroupDS )
1455 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1456 while ( elemIt1->more() )
1458 const SMDS_MeshElement* e = elemIt1->next();
1459 if ( !groupDS2->Contains( e ))
1460 resGroupDS->SMDSGroup().Add( e );
1463 // Update Python script
1464 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1465 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1467 SMESH_CATCH( SMESH::throwCorbaException );
1469 return aResGrp._retn();
1472 //=============================================================================
1474 \brief Cut lists of groups. New group is created. All mesh elements that are
1475 present in main groups but do not present in tool groups are added to the new one
1476 \param theMainGroups list of main groups
1477 \param theToolGroups list of tool groups
1478 \param theName name of group to be created
1479 \return pointer on the group
1481 //=============================================================================
1482 SMESH::SMESH_Group_ptr
1483 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1484 const SMESH::ListOfGroups& theToolGroups,
1485 const char* theName )
1486 throw (SALOME::SALOME_Exception)
1488 SMESH::SMESH_Group_var aResGrp;
1493 _preMeshInfo->FullLoadFromFile();
1496 return SMESH::SMESH_Group::_nil();
1498 // check types and get SMESHDS_GroupBase's
1499 SMESH::ElementType aType = SMESH::ALL;
1500 vector< SMESHDS_GroupBase* > toolGroupVec;
1501 vector< SMDS_ElemIteratorPtr > mainIterVec;
1503 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1505 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1506 if ( CORBA::is_nil( aGrp ) )
1508 if ( aType == SMESH::ALL )
1509 aType = aGrp->GetType();
1510 else if ( aType != aGrp->GetType() )
1511 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1513 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1514 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1515 if ( !grpDS->IsEmpty() )
1516 mainIterVec.push_back( grpDS->GetElements() );
1518 if ( aType == SMESH::ALL ) // all main groups are nil
1519 return SMESH::SMESH_Group::_nil();
1520 if ( mainIterVec.empty() ) // all main groups are empty
1521 return aResGrp._retn();
1523 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1525 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1526 if ( CORBA::is_nil( aGrp ) )
1528 if ( aType != aGrp->GetType() )
1529 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1531 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1532 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1533 toolGroupVec.push_back( grpDS );
1539 aResGrp = CreateGroup( aType, theName );
1541 SMESHDS_Group* resGroupDS = 0;
1542 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1543 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1545 return aResGrp._retn();
1548 size_t i, nb = toolGroupVec.size();
1549 SMDS_ElemIteratorPtr mainElemIt
1550 ( new SMDS_IteratorOnIterators
1551 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1552 while ( mainElemIt->more() )
1554 const SMDS_MeshElement* e = mainElemIt->next();
1556 for ( i = 0; ( i < nb && !isIn ); ++i )
1557 isIn = toolGroupVec[i]->Contains( e );
1560 resGroupDS->SMDSGroup().Add( e );
1563 // Update Python script
1564 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1565 << ".CutListOfGroups( " << theMainGroups
1566 << theToolGroups << ", '" << theName << "' )";
1568 SMESH_CATCH( SMESH::throwCorbaException );
1570 return aResGrp._retn();
1573 //=============================================================================
1575 \brief Create groups of entities from existing groups of superior dimensions
1577 1) extract all nodes from each group,
1578 2) combine all elements of specified dimension laying on these nodes.
1579 \param theGroups list of source groups
1580 \param theElemType dimension of elements
1581 \param theName name of new group
1582 \return pointer on new group
1586 //=============================================================================
1588 SMESH::SMESH_Group_ptr
1589 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1590 SMESH::ElementType theElemType,
1591 const char* theName )
1592 throw (SALOME::SALOME_Exception)
1594 SMESH::SMESH_Group_var aResGrp;
1598 _preMeshInfo->FullLoadFromFile();
1600 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1602 if ( !theName || !aMeshDS )
1603 return SMESH::SMESH_Group::_nil();
1605 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1611 aResGrp = CreateGroup( theElemType, theName );
1612 if ( aResGrp->_is_nil() )
1613 return SMESH::SMESH_Group::_nil();
1615 SMESHDS_GroupBase* groupBaseDS =
1616 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1617 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1619 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1621 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1622 if ( CORBA::is_nil( aGrp ) )
1625 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1626 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1628 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1630 while ( elIt->more() ) {
1631 const SMDS_MeshElement* el = elIt->next();
1632 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1633 while ( nIt->more() )
1634 resGroupCore.Add( nIt->next() );
1637 else // get elements of theElemType based on nodes of every element of group
1639 while ( elIt->more() )
1641 const SMDS_MeshElement* el = elIt->next(); // an element of group
1642 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1643 TIDSortedElemSet checkedElems;
1644 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1645 while ( nIt->more() )
1647 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1648 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1649 // check nodes of elements of theElemType around el
1650 while ( elOfTypeIt->more() )
1652 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1653 if ( !checkedElems.insert( elOfType ).second ) continue;
1655 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1656 bool allNodesOK = true;
1657 while ( nIt2->more() && allNodesOK )
1658 allNodesOK = elNodes.count( nIt2->next() );
1660 resGroupCore.Add( elOfType );
1667 // Update Python script
1668 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1669 << ".CreateDimGroup( "
1670 << theGroups << ", " << theElemType << ", '" << theName << "' )";
1672 SMESH_CATCH( SMESH::throwCorbaException );
1674 return aResGrp._retn();
1677 //================================================================================
1679 * \brief Remember GEOM group data
1681 //================================================================================
1683 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1684 CORBA::Object_ptr theSmeshObj)
1686 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1689 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1690 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1691 if ( groupSO->_is_nil() )
1694 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1695 GEOM::GEOM_IGroupOperations_wrap groupOp =
1696 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1697 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1700 _geomGroupData.push_back( TGeomGroupData() );
1701 TGeomGroupData & groupData = _geomGroupData.back();
1703 CORBA::String_var entry = groupSO->GetID();
1704 groupData._groupEntry = entry.in();
1706 for ( int i = 0; i < ids->length(); ++i )
1707 groupData._indices.insert( ids[i] );
1709 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1712 //================================================================================
1714 * Remove GEOM group data relating to removed smesh object
1716 //================================================================================
1718 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1720 list<TGeomGroupData>::iterator
1721 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1722 for ( ; data != dataEnd; ++data ) {
1723 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1724 _geomGroupData.erase( data );
1730 //================================================================================
1732 * \brief Return new group contents if it has been changed and update group data
1734 //================================================================================
1736 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1738 TopoDS_Shape newShape;
1741 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1742 if ( study->_is_nil() ) return newShape; // means "not changed"
1743 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1744 if ( !groupSO->_is_nil() )
1746 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1747 if ( CORBA::is_nil( groupObj )) return newShape;
1748 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1750 // get indices of group items
1751 set<int> curIndices;
1752 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1753 GEOM::GEOM_IGroupOperations_wrap groupOp =
1754 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1755 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1756 for ( int i = 0; i < ids->length(); ++i )
1757 curIndices.insert( ids[i] );
1759 if ( groupData._indices == curIndices )
1760 return newShape; // group not changed
1763 groupData._indices = curIndices;
1765 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1766 if ( !geomClient ) return newShape;
1767 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1768 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1769 newShape = _gen_i->GeomObjectToShape( geomGroup );
1772 if ( newShape.IsNull() ) {
1773 // geom group becomes empty - return empty compound
1774 TopoDS_Compound compound;
1775 BRep_Builder().MakeCompound(compound);
1776 newShape = compound;
1783 //=============================================================================
1785 * \brief Storage of shape and index used in CheckGeomGroupModif()
1787 //=============================================================================
1788 struct TIndexedShape
1791 TopoDS_Shape _shape;
1792 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1795 //=============================================================================
1797 * \brief Update objects depending on changed geom groups
1799 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1800 * issue 0020210: Update of a smesh group after modification of the associated geom group
1802 //=============================================================================
1804 void SMESH_Mesh_i::CheckGeomGroupModif()
1806 if ( !_impl->HasShapeToMesh() ) return;
1808 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1809 if ( study->_is_nil() ) return;
1811 CORBA::Long nbEntities = NbNodes() + NbElements();
1813 // Check if group contents changed
1815 typedef map< string, TopoDS_Shape > TEntry2Geom;
1816 TEntry2Geom newGroupContents;
1818 list<TGeomGroupData>::iterator
1819 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1820 for ( ; data != dataEnd; ++data )
1822 pair< TEntry2Geom::iterator, bool > it_new =
1823 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1824 bool processedGroup = !it_new.second;
1825 TopoDS_Shape& newShape = it_new.first->second;
1826 if ( !processedGroup )
1827 newShape = newGroupShape( *data );
1828 if ( newShape.IsNull() )
1829 continue; // no changes
1832 _preMeshInfo->ForgetOrLoad();
1834 if ( processedGroup ) { // update group indices
1835 list<TGeomGroupData>::iterator data2 = data;
1836 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1837 data->_indices = data2->_indices;
1840 // Update SMESH objects according to new GEOM group contents
1842 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1843 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1845 int oldID = submesh->GetId();
1846 if ( !_mapSubMeshIor.count( oldID ))
1848 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1850 // update hypotheses
1851 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1852 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1853 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1855 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1856 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1858 // care of submeshes
1859 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1860 int newID = newSubmesh->GetId();
1861 if ( newID != oldID ) {
1862 _mapSubMesh [ newID ] = newSubmesh;
1863 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1864 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1865 _mapSubMesh. erase(oldID);
1866 _mapSubMesh_i. erase(oldID);
1867 _mapSubMeshIor.erase(oldID);
1868 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1873 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1874 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1875 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1877 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1879 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1880 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1881 ds->SetShape( newShape );
1886 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1887 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1889 // Remove groups and submeshes basing on removed sub-shapes
1891 TopTools_MapOfShape newShapeMap;
1892 TopoDS_Iterator shapeIt( newShape );
1893 for ( ; shapeIt.More(); shapeIt.Next() )
1894 newShapeMap.Add( shapeIt.Value() );
1896 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1897 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1899 if ( newShapeMap.Contains( shapeIt.Value() ))
1901 TopTools_IndexedMapOfShape oldShapeMap;
1902 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1903 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1905 const TopoDS_Shape& oldShape = oldShapeMap(i);
1906 int oldInd = meshDS->ShapeToIndex( oldShape );
1908 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1909 if ( i_smIor != _mapSubMeshIor.end() ) {
1910 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1913 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1914 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1916 // check if a group bases on oldInd shape
1917 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1918 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1919 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1920 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1922 RemoveGroup( i_grp->second ); // several groups can base on same shape
1923 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1928 // Reassign hypotheses and update groups after setting the new shape to mesh
1930 // collect anassigned hypotheses
1931 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1932 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1933 TShapeHypList assignedHyps;
1934 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1936 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1937 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1938 if ( !hyps.empty() ) {
1939 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1940 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1941 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1944 // collect shapes supporting groups
1945 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1946 TShapeTypeList groupData;
1947 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1948 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1949 for ( ; grIt != groups.end(); ++grIt )
1951 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1953 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1955 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1956 _impl->ShapeToMesh( newShape );
1958 // reassign hypotheses
1959 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1960 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1962 TIndexedShape& geom = indS_hyps->first;
1963 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1964 int oldID = geom._index;
1965 int newID = meshDS->ShapeToIndex( geom._shape );
1966 if ( oldID == 1 ) { // main shape
1968 geom._shape = newShape;
1972 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1973 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1974 // care of submeshes
1975 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1976 if ( newID != oldID ) {
1977 _mapSubMesh [ newID ] = newSubmesh;
1978 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1979 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1980 _mapSubMesh. erase(oldID);
1981 _mapSubMesh_i. erase(oldID);
1982 _mapSubMeshIor.erase(oldID);
1983 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1987 TShapeTypeList::iterator geomType = groupData.begin();
1988 for ( ; geomType != groupData.end(); ++geomType )
1990 const TIndexedShape& geom = geomType->first;
1991 int oldID = geom._index;
1992 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1995 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1996 CORBA::String_var name = groupSO->GetName();
1998 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2000 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2001 group_i->changeLocalId( newID );
2004 break; // everything has been updated
2007 } // loop on group data
2011 CORBA::Long newNbEntities = NbNodes() + NbElements();
2012 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2013 if ( newNbEntities != nbEntities )
2015 // Add all SObjects with icons to soToUpdateIcons
2016 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2018 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2019 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2020 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2022 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2023 i_gr != _mapGroups.end(); ++i_gr ) // groups
2024 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2027 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2028 for ( ; so != soToUpdateIcons.end(); ++so )
2029 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2032 //=============================================================================
2034 * \brief Create standalone group from a group on geometry or filter
2036 //=============================================================================
2038 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2039 throw (SALOME::SALOME_Exception)
2041 SMESH::SMESH_Group_var aGroup;
2046 _preMeshInfo->FullLoadFromFile();
2048 if ( theGroup->_is_nil() )
2049 return aGroup._retn();
2051 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2053 return aGroup._retn();
2055 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2057 const int anId = aGroupToRem->GetLocalID();
2058 if ( !_impl->ConvertToStandalone( anId ) )
2059 return aGroup._retn();
2060 removeGeomGroupData( theGroup );
2062 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2064 // remove old instance of group from own map
2065 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2066 _mapGroups.erase( anId );
2068 SALOMEDS::StudyBuilder_var builder;
2069 SALOMEDS::SObject_wrap aGroupSO;
2070 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2071 if ( !aStudy->_is_nil() ) {
2072 builder = aStudy->NewBuilder();
2073 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2074 if ( !aGroupSO->_is_nil() )
2076 // remove reference to geometry
2077 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2078 for ( ; chItr->More(); chItr->Next() )
2079 // Remove group's child SObject
2080 builder->RemoveObject( chItr->Value() );
2082 // Update Python script
2083 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2084 << ".ConvertToStandalone( " << aGroupSO << " )";
2086 // change icon of Group on Filter
2089 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2090 const int isEmpty = ( elemTypes->length() == 0 );
2093 SALOMEDS::GenericAttribute_wrap anAttr =
2094 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2095 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2096 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2102 // remember new group in own map
2103 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2104 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2106 // register CORBA object for persistence
2107 _gen_i->RegisterObject( aGroup );
2109 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2110 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2111 //aGroup->Register();
2112 aGroupToRem->UnRegister();
2114 SMESH_CATCH( SMESH::throwCorbaException );
2116 return aGroup._retn();
2119 //=============================================================================
2123 //=============================================================================
2125 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2127 if(MYDEBUG) MESSAGE( "createSubMesh" );
2128 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2129 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2130 const int subMeshId = mySubMesh->GetId();
2132 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2133 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2135 _mapSubMesh [subMeshId] = mySubMesh;
2136 _mapSubMesh_i [subMeshId] = subMeshServant;
2137 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2139 subMeshServant->Register();
2141 // register CORBA object for persistence
2142 int nextId = _gen_i->RegisterObject( subMesh );
2143 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2144 else { nextId = 0; } // avoid "unused variable" warning
2146 // to track changes of GEOM groups
2147 addGeomGroupData( theSubShapeObject, subMesh );
2149 return subMesh._retn();
2152 //=======================================================================
2153 //function : getSubMesh
2155 //=======================================================================
2157 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2159 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2160 if ( it == _mapSubMeshIor.end() )
2161 return SMESH::SMESH_subMesh::_nil();
2163 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2166 //=============================================================================
2170 //=============================================================================
2172 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2173 GEOM::GEOM_Object_ptr theSubShapeObject )
2175 bool isHypChanged = false;
2176 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2177 return isHypChanged;
2179 const int subMeshId = theSubMesh->GetId();
2181 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2183 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2185 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2188 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2189 isHypChanged = !hyps.empty();
2190 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2191 for ( ; hyp != hyps.end(); ++hyp )
2192 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2199 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2200 isHypChanged = ( aHypList->length() > 0 );
2201 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2202 removeHypothesis( theSubShapeObject, aHypList[i] );
2205 catch( const SALOME::SALOME_Exception& ) {
2206 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2208 removeGeomGroupData( theSubShapeObject );
2212 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2213 if ( id_smi != _mapSubMesh_i.end() )
2214 id_smi->second->UnRegister();
2216 // remove a CORBA object
2217 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2218 if ( id_smptr != _mapSubMeshIor.end() )
2219 SMESH::SMESH_subMesh_var( id_smptr->second );
2221 _mapSubMesh.erase(subMeshId);
2222 _mapSubMesh_i.erase(subMeshId);
2223 _mapSubMeshIor.erase(subMeshId);
2225 return isHypChanged;
2228 //=============================================================================
2232 //=============================================================================
2234 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2235 const char* theName,
2236 const TopoDS_Shape& theShape,
2237 const SMESH_PredicatePtr& thePredicate )
2239 std::string newName;
2240 if ( !theName || strlen( theName ) == 0 )
2242 std::set< std::string > presentNames;
2243 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2244 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2246 CORBA::String_var name = i_gr->second->GetName();
2247 presentNames.insert( name.in() );
2250 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2251 } while ( !presentNames.insert( newName ).second );
2252 theName = newName.c_str();
2255 SMESH::SMESH_GroupBase_var aGroup;
2256 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2258 SMESH_GroupBase_i* aGroupImpl;
2259 if ( !theShape.IsNull() )
2260 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2261 else if ( thePredicate )
2262 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2264 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2266 aGroup = aGroupImpl->_this();
2267 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2268 aGroupImpl->Register();
2270 // register CORBA object for persistence
2271 int nextId = _gen_i->RegisterObject( aGroup );
2272 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2273 else { nextId = 0; } // avoid "unused variable" warning in release mode
2275 // to track changes of GEOM groups
2276 if ( !theShape.IsNull() ) {
2277 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2278 addGeomGroupData( geom, aGroup );
2281 return aGroup._retn();
2284 //=============================================================================
2286 * SMESH_Mesh_i::removeGroup
2288 * Should be called by ~SMESH_Group_i()
2290 //=============================================================================
2292 void SMESH_Mesh_i::removeGroup( const int theId )
2294 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2295 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2296 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2297 _mapGroups.erase( theId );
2298 removeGeomGroupData( group );
2299 if ( !_impl->RemoveGroup( theId ))
2301 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2302 RemoveGroup( group );
2304 group->UnRegister();
2308 //=============================================================================
2312 //=============================================================================
2314 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2315 throw(SALOME::SALOME_Exception)
2317 SMESH::log_array_var aLog;
2321 _preMeshInfo->FullLoadFromFile();
2323 list < SMESHDS_Command * >logDS = _impl->GetLog();
2324 aLog = new SMESH::log_array;
2326 int lg = logDS.size();
2329 list < SMESHDS_Command * >::iterator its = logDS.begin();
2330 while(its != logDS.end()){
2331 SMESHDS_Command *com = *its;
2332 int comType = com->GetType();
2334 int lgcom = com->GetNumber();
2336 const list < int >&intList = com->GetIndexes();
2337 int inum = intList.size();
2339 list < int >::const_iterator ii = intList.begin();
2340 const list < double >&coordList = com->GetCoords();
2341 int rnum = coordList.size();
2343 list < double >::const_iterator ir = coordList.begin();
2344 aLog[indexLog].commandType = comType;
2345 aLog[indexLog].number = lgcom;
2346 aLog[indexLog].coords.length(rnum);
2347 aLog[indexLog].indexes.length(inum);
2348 for(int i = 0; i < rnum; i++){
2349 aLog[indexLog].coords[i] = *ir;
2350 //MESSAGE(" "<<i<<" "<<ir.Value());
2353 for(int i = 0; i < inum; i++){
2354 aLog[indexLog].indexes[i] = *ii;
2355 //MESSAGE(" "<<i<<" "<<ii.Value());
2364 SMESH_CATCH( SMESH::throwCorbaException );
2366 return aLog._retn();
2370 //=============================================================================
2374 //=============================================================================
2376 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2380 SMESH_CATCH( SMESH::throwCorbaException );
2383 //=============================================================================
2387 //=============================================================================
2389 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2394 //=============================================================================
2398 //=============================================================================
2400 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2405 //=============================================================================
2408 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2409 // issue 0020918: groups removal is caused by hyp modification
2410 // issue 0021208: to forget not loaded mesh data at hyp modification
2411 struct TCallUp_i : public SMESH_Mesh::TCallUp
2413 SMESH_Mesh_i* _mesh;
2414 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2415 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2416 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2417 virtual void Load () { _mesh->Load(); }
2421 //================================================================================
2423 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2425 //================================================================================
2427 void SMESH_Mesh_i::onHypothesisModified()
2430 _preMeshInfo->ForgetOrLoad();
2433 //=============================================================================
2437 //=============================================================================
2439 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2441 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2444 _impl->SetCallUp( new TCallUp_i(this));
2447 //=============================================================================
2451 //=============================================================================
2453 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2455 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2459 //=============================================================================
2461 * Return mesh editor
2463 //=============================================================================
2465 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2466 throw (SALOME::SALOME_Exception)
2468 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2472 _preMeshInfo->FullLoadFromFile();
2474 // Create MeshEditor
2476 _editor = new SMESH_MeshEditor_i( this, false );
2477 aMeshEdVar = _editor->_this();
2479 // Update Python script
2480 TPythonDump() << _editor << " = "
2481 << SMESH::SMESH_Mesh_var(_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 if ( !_previewEditor )
2504 _previewEditor = new SMESH_MeshEditor_i( this, true );
2505 aMeshEdVar = _previewEditor->_this();
2507 SMESH_CATCH( SMESH::throwCorbaException );
2509 return aMeshEdVar._retn();
2512 //================================================================================
2514 * \brief Return true if the mesh has been edited since a last total re-compute
2515 * and those modifications may prevent successful partial re-compute
2517 //================================================================================
2519 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2521 Unexpect aCatch(SALOME_SalomeException);
2522 return _impl->HasModificationsToDiscard();
2525 //================================================================================
2527 * \brief Returns a random unique color
2529 //================================================================================
2531 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2533 const int MAX_ATTEMPTS = 100;
2535 double tolerance = 0.5;
2536 SALOMEDS::Color col;
2540 // generate random color
2541 double red = (double)rand() / RAND_MAX;
2542 double green = (double)rand() / RAND_MAX;
2543 double blue = (double)rand() / RAND_MAX;
2544 // check existence in the list of the existing colors
2545 bool matched = false;
2546 std::list<SALOMEDS::Color>::const_iterator it;
2547 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2548 SALOMEDS::Color color = *it;
2549 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2550 matched = tol < tolerance;
2552 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2553 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2561 //=============================================================================
2563 * Sets auto-color mode. If it is on, groups get unique random colors
2565 //=============================================================================
2567 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2569 Unexpect aCatch(SALOME_SalomeException);
2570 _impl->SetAutoColor(theAutoColor);
2572 TPythonDump pyDump; // not to dump group->SetColor() from below code
2573 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2575 std::list<SALOMEDS::Color> aReservedColors;
2576 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2577 for ( ; it != _mapGroups.end(); it++ ) {
2578 if ( CORBA::is_nil( it->second )) continue;
2579 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2580 it->second->SetColor( aColor );
2581 aReservedColors.push_back( aColor );
2585 //=============================================================================
2587 * Returns true if auto-color mode is on
2589 //=============================================================================
2591 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2593 Unexpect aCatch(SALOME_SalomeException);
2594 return _impl->GetAutoColor();
2597 //=============================================================================
2599 * Checks if there are groups with equal names
2601 //=============================================================================
2603 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2605 return _impl->HasDuplicatedGroupNamesMED();
2608 //================================================================================
2610 * \brief Care of a file before exporting mesh into it
2612 //================================================================================
2614 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2616 TCollection_AsciiString aFullName ((char*)file);
2617 OSD_Path aPath (aFullName);
2618 OSD_File aFile (aPath);
2619 if (aFile.Exists()) {
2620 // existing filesystem node
2621 if (aFile.KindOfFile() == OSD_FILE) {
2622 if (aFile.IsWriteable()) {
2627 if (aFile.Failed()) {
2628 TCollection_AsciiString msg ("File ");
2629 msg += aFullName + " cannot be replaced.";
2630 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2633 TCollection_AsciiString msg ("File ");
2634 msg += aFullName + " cannot be overwritten.";
2635 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2638 TCollection_AsciiString msg ("Location ");
2639 msg += aFullName + " is not a file.";
2640 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2643 // nonexisting file; check if it can be created
2645 aFile.Build(OSD_WriteOnly, OSD_Protection());
2646 if (aFile.Failed()) {
2647 TCollection_AsciiString msg ("You cannot create the file ");
2648 msg += aFullName + ". Check the directory existance and access rights.";
2649 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2657 //================================================================================
2659 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2660 * \param file - file name
2661 * \param overwrite - to erase the file or not
2662 * \retval string - mesh name
2664 //================================================================================
2666 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2667 CORBA::Boolean overwrite)
2670 PrepareForWriting(file, overwrite);
2671 string aMeshName = "Mesh";
2672 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2673 if ( !aStudy->_is_nil() ) {
2674 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2675 if ( !aMeshSO->_is_nil() ) {
2676 CORBA::String_var name = aMeshSO->GetName();
2678 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2679 if ( !aStudy->GetProperties()->IsLocked() )
2681 SALOMEDS::GenericAttribute_wrap anAttr;
2682 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2683 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2684 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2685 ASSERT(!aFileName->_is_nil());
2686 aFileName->SetValue(file);
2687 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2688 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2689 ASSERT(!aFileType->_is_nil());
2690 aFileType->SetValue("FICHIERMED");
2694 // Update Python script
2695 // set name of mesh before export
2696 TPythonDump() << _gen_i << ".SetName("
2697 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2699 // check names of groups
2705 //================================================================================
2707 * \brief Export to med file
2709 //================================================================================
2711 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2712 CORBA::Boolean auto_groups,
2713 SMESH::MED_VERSION theVersion,
2714 CORBA::Boolean overwrite,
2715 CORBA::Boolean autoDimension)
2716 throw(SALOME::SALOME_Exception)
2720 _preMeshInfo->FullLoadFromFile();
2722 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2723 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2725 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2726 << file << "', " << auto_groups << ", "
2727 << theVersion << ", " << overwrite << ", "
2728 << autoDimension << " )";
2730 SMESH_CATCH( SMESH::throwCorbaException );
2733 //================================================================================
2735 * \brief Export a mesh to a med file
2737 //================================================================================
2739 void SMESH_Mesh_i::ExportToMED (const char* file,
2740 CORBA::Boolean auto_groups,
2741 SMESH::MED_VERSION theVersion)
2742 throw(SALOME::SALOME_Exception)
2744 ExportToMEDX(file,auto_groups,theVersion,true);
2747 //================================================================================
2749 * \brief Export a mesh to a med file
2751 //================================================================================
2753 void SMESH_Mesh_i::ExportMED (const char* file,
2754 CORBA::Boolean auto_groups)
2755 throw(SALOME::SALOME_Exception)
2757 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2760 //================================================================================
2762 * \brief Export a mesh to a SAUV file
2764 //================================================================================
2766 void SMESH_Mesh_i::ExportSAUV (const char* file,
2767 CORBA::Boolean auto_groups)
2768 throw(SALOME::SALOME_Exception)
2770 Unexpect aCatch(SALOME_SalomeException);
2772 _preMeshInfo->FullLoadFromFile();
2774 string aMeshName = prepareMeshNameAndGroups(file, true);
2775 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2776 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2777 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2781 //================================================================================
2783 * \brief Export a mesh to a DAT file
2785 //================================================================================
2787 void SMESH_Mesh_i::ExportDAT (const char *file)
2788 throw(SALOME::SALOME_Exception)
2790 Unexpect aCatch(SALOME_SalomeException);
2792 _preMeshInfo->FullLoadFromFile();
2794 // Update Python script
2795 // check names of groups
2797 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2800 PrepareForWriting(file);
2801 _impl->ExportDAT(file);
2804 //================================================================================
2806 * \brief Export a mesh to an UNV file
2808 //================================================================================
2810 void SMESH_Mesh_i::ExportUNV (const char *file)
2811 throw(SALOME::SALOME_Exception)
2813 Unexpect aCatch(SALOME_SalomeException);
2815 _preMeshInfo->FullLoadFromFile();
2817 // Update Python script
2818 // check names of groups
2820 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2823 PrepareForWriting(file);
2824 _impl->ExportUNV(file);
2827 //================================================================================
2829 * \brief Export a mesh to an STL file
2831 //================================================================================
2833 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2834 throw(SALOME::SALOME_Exception)
2836 Unexpect aCatch(SALOME_SalomeException);
2838 _preMeshInfo->FullLoadFromFile();
2840 // Update Python script
2841 // check names of groups
2843 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2844 << ".ExportSTL( r'" << file << "', " << isascii << " )";
2847 PrepareForWriting(file);
2848 _impl->ExportSTL(file, isascii);
2851 namespace // utils used by ExportPartToMED()
2853 // remover of 0d elements temporary added by ExportPartToMED()
2856 std::vector< const SMDS_MeshElement* > _0dElems;
2857 SMESHDS_Mesh* _mesh;
2858 OdRemover( SMESHDS_Mesh* mesh ): _mesh( mesh ) {}
2860 for ( size_t i = 0; i < _0dElems.size(); ++i )
2863 SMESHDS_SubMesh* sm = _mesh->MeshElements( _0dElems[i]->getshapeId() );
2864 _mesh->RemoveFreeElement( _0dElems[i], sm, false );
2870 //================================================================================
2872 * \brief Export a part of mesh to a med file
2874 //================================================================================
2876 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
2878 CORBA::Boolean auto_groups,
2879 SMESH::MED_VERSION version,
2880 CORBA::Boolean overwrite,
2881 CORBA::Boolean autoDimension,
2882 const GEOM::ListOfFields& fields,
2883 const char* geomAssocFields)
2884 throw (SALOME::SALOME_Exception)
2888 _preMeshInfo->FullLoadFromFile();
2891 bool have0dField = false;
2892 if ( fields.length() > 0 )
2894 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
2895 if ( shapeToMesh->_is_nil() )
2896 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
2898 for ( size_t i = 0; i < fields.length(); ++i )
2900 if ( fields[i]->GetDataType() == GEOM::FDT_String )
2901 THROW_SALOME_CORBA_EXCEPTION
2902 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
2903 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
2904 if ( fieldShape->_is_nil() )
2905 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
2906 if ( !fieldShape->IsSame( shapeToMesh ) )
2907 THROW_SALOME_CORBA_EXCEPTION
2908 ( "Field defined not on shape", SALOME::BAD_PARAM);
2909 if ( fields[i]->GetDimension() == 0 )
2912 if ( geomAssocFields )
2913 for ( int i = 0; geomAssocFields[i]; ++i )
2914 switch ( geomAssocFields[i] ) {
2915 case 'v':case 'e':case 'f':case 's': break;
2916 case 'V':case 'E':case 'F':case 'S': break;
2917 default: THROW_SALOME_CORBA_EXCEPTION
2918 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
2922 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2924 OdRemover a0dRemover( meshDS );
2927 // temporary add 0D elements on all nodes on vertices
2928 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2930 if ( meshDS->IndexToShape( i ).ShapeType() != TopAbs_VERTEX )
2932 if ( SMESHDS_SubMesh* sm = meshDS->MeshElements(i) ) {
2933 SMDS_NodeIteratorPtr nIt= sm->GetNodes();
2936 const SMDS_MeshNode* n = nIt->next();
2937 if ( n->NbInverseElements( SMDSAbs_0DElement ) == 0 )
2939 a0dRemover._0dElems.push_back( meshDS->Add0DElement( n ));
2940 sm->AddElement( a0dRemover._0dElems.back() );
2949 string aMeshName = "Mesh";
2950 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
2951 if ( CORBA::is_nil( meshPart ) ||
2952 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
2954 aMeshName = prepareMeshNameAndGroups(file, overwrite);
2955 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
2957 meshDS = _impl->GetMeshDS();
2962 _preMeshInfo->FullLoadFromFile();
2964 PrepareForWriting(file, overwrite);
2966 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2967 if ( !aStudy->_is_nil() ) {
2968 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2969 if ( !SO->_is_nil() ) {
2970 CORBA::String_var name = SO->GetName();
2974 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
2975 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, partDS, autoDimension );
2977 meshDS = tmpDSDeleter._obj = partDS;
2982 if ( _impl->HasShapeToMesh() )
2984 DriverMED_W_Field fieldWriter;
2985 fieldWriter.SetFile( file );
2986 fieldWriter.SetMeshName( aMeshName );
2988 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
2992 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
2993 goList->length( fields.length() );
2994 for ( size_t i = 0; i < fields.length(); ++i )
2996 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
2999 TPythonDump() << _this() << ".ExportPartToMED( "
3000 << meshPart << ", r'" << file << "', "
3001 << auto_groups << ", " << version << ", " << overwrite << ", "
3002 << autoDimension << ", " << goList
3003 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3005 SMESH_CATCH( SMESH::throwCorbaException );
3008 //================================================================================
3010 * Write GEOM fields to MED file
3012 //================================================================================
3014 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3015 SMESHDS_Mesh* meshDS,
3016 const GEOM::ListOfFields& fields,
3017 const char* geomAssocFields)
3019 #define METH "SMESH_Mesh_i::exportMEDFields() "
3021 if (( fields.length() < 1 ) &&
3022 ( !geomAssocFields || !geomAssocFields[0] ))
3025 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3026 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3027 std::vector< int > subIdsByDim[ 4 ];
3028 const double noneDblValue = 0.;
3029 const double noneIntValue = 0;
3031 for ( size_t iF = 0; iF < fields.length(); ++iF )
3035 int dim = fields[ iF ]->GetDimension();
3036 SMDSAbs_ElementType elemType;
3037 TopAbs_ShapeEnum shapeType;
3039 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3040 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3041 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3042 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3044 continue; // skip fields on whole shape
3046 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3047 if ( dataType == GEOM::FDT_String )
3049 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3050 if ( stepIDs->length() < 1 )
3052 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3053 if ( comps->length() < 1 )
3055 CORBA::String_var name = fields[ iF ]->GetName();
3057 if ( !fieldWriter.Set( meshDS,
3061 ( dataType == GEOM::FDT_Int )))
3064 for ( size_t iC = 0; iC < comps->length(); ++iC )
3065 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3067 // find sub-shape IDs
3069 std::vector< int >& subIds = subIdsByDim[ dim ];
3070 if ( subIds.empty() )
3071 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3072 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3073 subIds.push_back( id );
3077 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3081 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3083 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3084 if ( step->_is_nil() )
3087 CORBA::Long stamp = step->GetStamp();
3088 CORBA::Long id = step->GetID();
3089 fieldWriter.SetDtIt( int( stamp ), int( id ));
3091 // fill dblVals or intVals
3094 case GEOM::FDT_Double:
3096 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3097 if ( dblStep->_is_nil() ) continue;
3098 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3099 if ( vv->length() != subIds.size() )
3100 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3101 for ( size_t i = 0; i < vv->length(); ++i )
3102 dblVals[ subIds[ i ]] = vv[ i ];
3107 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3108 if ( intStep->_is_nil() ) continue;
3109 GEOM::ListOfLong_var vv = intStep->GetValues();
3110 if ( vv->length() != subIds.size() )
3111 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3112 for ( size_t i = 0; i < vv->length(); ++i )
3113 intVals[ subIds[ i ]] = (int) vv[ i ];
3116 case GEOM::FDT_Bool:
3118 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3119 if ( boolStep->_is_nil() ) continue;
3120 GEOM::short_array_var vv = boolStep->GetValues();
3121 if ( vv->length() != subIds.size() )
3122 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3123 for ( size_t i = 0; i < vv->length(); ++i )
3124 intVals[ subIds[ i ]] = (int) vv[ i ];
3130 // pass values to fieldWriter
3131 elemIt = fieldWriter.GetOrderedElems();
3132 if ( dataType == GEOM::FDT_Double )
3133 while ( elemIt->more() )
3135 const SMDS_MeshElement* e = elemIt->next();
3136 const int shapeID = e->getshapeId();
3137 if ( shapeID < 1 || shapeID >= dblVals.size() )
3138 fieldWriter.AddValue( noneDblValue );
3140 fieldWriter.AddValue( dblVals[ shapeID ]);
3143 while ( elemIt->more() )
3145 const SMDS_MeshElement* e = elemIt->next();
3146 const int shapeID = e->getshapeId();
3147 if ( shapeID < 1 || shapeID >= intVals.size() )
3148 fieldWriter.AddValue( noneIntValue );
3150 fieldWriter.AddValue( intVals[ shapeID ]);
3154 fieldWriter.Perform();
3155 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3156 if ( res && res->IsKO() )
3158 if ( res->myComment.empty() )
3159 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3161 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3167 if ( !geomAssocFields || !geomAssocFields[0] )
3170 // write geomAssocFields
3172 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3173 shapeDim[ TopAbs_COMPOUND ] = 3;
3174 shapeDim[ TopAbs_COMPSOLID ] = 3;
3175 shapeDim[ TopAbs_SOLID ] = 3;
3176 shapeDim[ TopAbs_SHELL ] = 2;
3177 shapeDim[ TopAbs_FACE ] = 2;
3178 shapeDim[ TopAbs_WIRE ] = 1;
3179 shapeDim[ TopAbs_EDGE ] = 1;
3180 shapeDim[ TopAbs_VERTEX ] = 0;
3181 shapeDim[ TopAbs_SHAPE ] = 3;
3183 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3185 std::vector< std::string > compNames;
3186 switch ( geomAssocFields[ iF ]) {
3188 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/true );
3189 compNames.push_back( "dim" );
3192 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/true );
3195 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/true );
3198 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/true );
3202 compNames.push_back( "id" );
3203 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3204 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3206 fieldWriter.SetDtIt( -1, -1 );
3208 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3212 if ( compNames.size() == 2 ) // _vertices_
3213 while ( elemIt->more() )
3215 const SMDS_MeshElement* e = elemIt->next();
3216 const int shapeID = e->getshapeId();
3219 fieldWriter.AddValue( -1 );
3220 fieldWriter.AddValue( -1 );
3224 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3225 fieldWriter.AddValue( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]);
3226 fieldWriter.AddValue( shapeID );
3230 while ( elemIt->more() )
3232 const SMDS_MeshElement* e = elemIt->next();
3233 const int shapeID = e->getshapeId();
3235 fieldWriter.AddValue( -1 );
3237 fieldWriter.AddValue( shapeID );
3241 fieldWriter.Perform();
3242 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3243 if ( res && res->IsKO() )
3245 if ( res->myComment.empty() )
3246 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3248 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3251 } // loop on geomAssocFields
3256 //================================================================================
3258 * \brief Export a part of mesh to a DAT file
3260 //================================================================================
3262 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3264 throw (SALOME::SALOME_Exception)
3266 Unexpect aCatch(SALOME_SalomeException);
3268 _preMeshInfo->FullLoadFromFile();
3270 PrepareForWriting(file);
3272 SMESH_MeshPartDS partDS( meshPart );
3273 _impl->ExportDAT(file,&partDS);
3275 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3276 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3278 //================================================================================
3280 * \brief Export a part of mesh to an UNV file
3282 //================================================================================
3284 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3286 throw (SALOME::SALOME_Exception)
3288 Unexpect aCatch(SALOME_SalomeException);
3290 _preMeshInfo->FullLoadFromFile();
3292 PrepareForWriting(file);
3294 SMESH_MeshPartDS partDS( meshPart );
3295 _impl->ExportUNV(file, &partDS);
3297 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3298 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3300 //================================================================================
3302 * \brief Export a part of mesh to an STL file
3304 //================================================================================
3306 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3308 ::CORBA::Boolean isascii)
3309 throw (SALOME::SALOME_Exception)
3311 Unexpect aCatch(SALOME_SalomeException);
3313 _preMeshInfo->FullLoadFromFile();
3315 PrepareForWriting(file);
3317 SMESH_MeshPartDS partDS( meshPart );
3318 _impl->ExportSTL(file, isascii, &partDS);
3320 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3321 << meshPart<< ", r'" << file << "', " << isascii << ")";
3324 //================================================================================
3326 * \brief Export a part of mesh to an STL file
3328 //================================================================================
3330 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3332 CORBA::Boolean overwrite)
3333 throw (SALOME::SALOME_Exception)
3336 Unexpect aCatch(SALOME_SalomeException);
3338 _preMeshInfo->FullLoadFromFile();
3340 PrepareForWriting(file,overwrite);
3342 SMESH_MeshPartDS partDS( meshPart );
3343 _impl->ExportCGNS(file, &partDS);
3345 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3346 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3348 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3352 //================================================================================
3354 * \brief Export a part of mesh to a GMF file
3356 //================================================================================
3358 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3360 bool withRequiredGroups)
3361 throw (SALOME::SALOME_Exception)
3363 Unexpect aCatch(SALOME_SalomeException);
3365 _preMeshInfo->FullLoadFromFile();
3367 PrepareForWriting(file,/*overwrite=*/true);
3369 SMESH_MeshPartDS partDS( meshPart );
3370 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3372 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3373 << meshPart<< ", r'"
3375 << withRequiredGroups << ")";
3378 //=============================================================================
3380 * Return computation progress [0.,1]
3382 //=============================================================================
3384 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3388 return _impl->GetComputeProgress();
3390 SMESH_CATCH( SMESH::doNothing );
3394 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3396 Unexpect aCatch(SALOME_SalomeException);
3398 return _preMeshInfo->NbNodes();
3400 return _impl->NbNodes();
3403 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3405 Unexpect aCatch(SALOME_SalomeException);
3407 return _preMeshInfo->NbElements();
3409 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3412 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3414 Unexpect aCatch(SALOME_SalomeException);
3416 return _preMeshInfo->Nb0DElements();
3418 return _impl->Nb0DElements();
3421 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3423 Unexpect aCatch(SALOME_SalomeException);
3425 return _preMeshInfo->NbBalls();
3427 return _impl->NbBalls();
3430 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3432 Unexpect aCatch(SALOME_SalomeException);
3434 return _preMeshInfo->NbEdges();
3436 return _impl->NbEdges();
3439 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3440 throw(SALOME::SALOME_Exception)
3442 Unexpect aCatch(SALOME_SalomeException);
3444 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3446 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3449 //=============================================================================
3451 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3453 Unexpect aCatch(SALOME_SalomeException);
3455 return _preMeshInfo->NbFaces();
3457 return _impl->NbFaces();
3460 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3462 Unexpect aCatch(SALOME_SalomeException);
3464 return _preMeshInfo->NbTriangles();
3466 return _impl->NbTriangles();
3469 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3471 Unexpect aCatch(SALOME_SalomeException);
3473 return _preMeshInfo->NbBiQuadTriangles();
3475 return _impl->NbBiQuadTriangles();
3478 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3480 Unexpect aCatch(SALOME_SalomeException);
3482 return _preMeshInfo->NbQuadrangles();
3484 return _impl->NbQuadrangles();
3487 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3489 Unexpect aCatch(SALOME_SalomeException);
3491 return _preMeshInfo->NbBiQuadQuadrangles();
3493 return _impl->NbBiQuadQuadrangles();
3496 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3498 Unexpect aCatch(SALOME_SalomeException);
3500 return _preMeshInfo->NbPolygons();
3502 return _impl->NbPolygons();
3505 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3506 throw(SALOME::SALOME_Exception)
3508 Unexpect aCatch(SALOME_SalomeException);
3510 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3512 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3515 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3516 throw(SALOME::SALOME_Exception)
3518 Unexpect aCatch(SALOME_SalomeException);
3520 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3522 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3525 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3526 throw(SALOME::SALOME_Exception)
3528 Unexpect aCatch(SALOME_SalomeException);
3530 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3532 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3535 //=============================================================================
3537 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3539 Unexpect aCatch(SALOME_SalomeException);
3541 return _preMeshInfo->NbVolumes();
3543 return _impl->NbVolumes();
3546 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3548 Unexpect aCatch(SALOME_SalomeException);
3550 return _preMeshInfo->NbTetras();
3552 return _impl->NbTetras();
3555 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3557 Unexpect aCatch(SALOME_SalomeException);
3559 return _preMeshInfo->NbHexas();
3561 return _impl->NbHexas();
3564 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3566 Unexpect aCatch(SALOME_SalomeException);
3568 return _preMeshInfo->NbTriQuadHexas();
3570 return _impl->NbTriQuadraticHexas();
3573 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3575 Unexpect aCatch(SALOME_SalomeException);
3577 return _preMeshInfo->NbPyramids();
3579 return _impl->NbPyramids();
3582 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3584 Unexpect aCatch(SALOME_SalomeException);
3586 return _preMeshInfo->NbPrisms();
3588 return _impl->NbPrisms();
3591 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3593 Unexpect aCatch(SALOME_SalomeException);
3595 return _preMeshInfo->NbHexPrisms();
3597 return _impl->NbHexagonalPrisms();
3600 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3602 Unexpect aCatch(SALOME_SalomeException);
3604 return _preMeshInfo->NbPolyhedrons();
3606 return _impl->NbPolyhedrons();
3609 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3610 throw(SALOME::SALOME_Exception)
3612 Unexpect aCatch(SALOME_SalomeException);
3614 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3616 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3619 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3620 throw(SALOME::SALOME_Exception)
3622 Unexpect aCatch(SALOME_SalomeException);
3624 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3626 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3629 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3630 throw(SALOME::SALOME_Exception)
3632 Unexpect aCatch(SALOME_SalomeException);
3634 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3636 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3639 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3640 throw(SALOME::SALOME_Exception)
3642 Unexpect aCatch(SALOME_SalomeException);
3644 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3646 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3649 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3650 throw(SALOME::SALOME_Exception)
3652 Unexpect aCatch(SALOME_SalomeException);
3654 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3656 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3659 //=============================================================================
3661 * Returns nb of published sub-meshes
3663 //=============================================================================
3665 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3667 Unexpect aCatch(SALOME_SalomeException);
3668 return _mapSubMesh_i.size();
3671 //=============================================================================
3673 * Dumps mesh into a string
3675 //=============================================================================
3677 char* SMESH_Mesh_i::Dump()
3681 return CORBA::string_dup( os.str().c_str() );
3684 //=============================================================================
3686 * Method of SMESH_IDSource interface
3688 //=============================================================================
3690 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3692 return GetElementsId();
3695 //=============================================================================
3697 * Returns ids of all elements
3699 //=============================================================================
3701 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3702 throw (SALOME::SALOME_Exception)
3704 Unexpect aCatch(SALOME_SalomeException);
3706 _preMeshInfo->FullLoadFromFile();
3708 SMESH::long_array_var aResult = new SMESH::long_array();
3709 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3711 if ( aSMESHDS_Mesh == NULL )
3712 return aResult._retn();
3714 long nbElements = NbElements();
3715 aResult->length( nbElements );
3716 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3717 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3718 aResult[i] = anIt->next()->GetID();
3720 return aResult._retn();
3724 //=============================================================================
3726 * Returns ids of all elements of given type
3728 //=============================================================================
3730 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3731 throw (SALOME::SALOME_Exception)
3733 Unexpect aCatch(SALOME_SalomeException);
3735 _preMeshInfo->FullLoadFromFile();
3737 SMESH::long_array_var aResult = new SMESH::long_array();
3738 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3740 if ( aSMESHDS_Mesh == NULL )
3741 return aResult._retn();
3743 long nbElements = NbElements();
3745 // No sense in returning ids of elements along with ids of nodes:
3746 // when theElemType == SMESH::ALL, return node ids only if
3747 // there are no elements
3748 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3749 return GetNodesId();
3751 aResult->length( nbElements );
3755 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3756 while ( i < nbElements && anIt->more() )
3757 aResult[i++] = anIt->next()->GetID();
3759 aResult->length( i );
3761 return aResult._retn();
3764 //=============================================================================
3766 * Returns ids of all nodes
3768 //=============================================================================
3770 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3771 throw (SALOME::SALOME_Exception)
3773 Unexpect aCatch(SALOME_SalomeException);
3775 _preMeshInfo->FullLoadFromFile();
3777 SMESH::long_array_var aResult = new SMESH::long_array();
3778 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3780 if ( aSMESHDS_Mesh == NULL )
3781 return aResult._retn();
3783 long nbNodes = NbNodes();
3784 aResult->length( nbNodes );
3785 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3786 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3787 aResult[i] = anIt->next()->GetID();
3789 return aResult._retn();
3792 //=============================================================================
3796 //=============================================================================
3798 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3799 throw (SALOME::SALOME_Exception)
3801 SMESH::ElementType type;
3805 _preMeshInfo->FullLoadFromFile();
3807 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3809 SMESH_CATCH( SMESH::throwCorbaException );
3814 //=============================================================================
3818 //=============================================================================
3820 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3821 throw (SALOME::SALOME_Exception)
3824 _preMeshInfo->FullLoadFromFile();
3826 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3828 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3830 return ( SMESH::EntityType ) e->GetEntityType();
3833 //=============================================================================
3837 //=============================================================================
3839 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3840 throw (SALOME::SALOME_Exception)
3843 _preMeshInfo->FullLoadFromFile();
3845 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3847 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3849 return ( SMESH::GeometryType ) e->GetGeomType();
3852 //=============================================================================
3854 * Returns ID of elements for given submesh
3856 //=============================================================================
3857 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3858 throw (SALOME::SALOME_Exception)
3860 SMESH::long_array_var aResult = new SMESH::long_array();
3864 _preMeshInfo->FullLoadFromFile();
3866 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3867 if(!SM) return aResult._retn();
3869 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3870 if(!SDSM) return aResult._retn();
3872 aResult->length(SDSM->NbElements());
3874 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3876 while ( eIt->more() ) {
3877 aResult[i++] = eIt->next()->GetID();
3880 SMESH_CATCH( SMESH::throwCorbaException );
3882 return aResult._retn();
3885 //=============================================================================
3887 * Returns ID of nodes for given submesh
3888 * If param all==true - returns all nodes, else -
3889 * returns only nodes on shapes.
3891 //=============================================================================
3893 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3895 throw (SALOME::SALOME_Exception)
3897 SMESH::long_array_var aResult = new SMESH::long_array();
3901 _preMeshInfo->FullLoadFromFile();
3903 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3904 if(!SM) return aResult._retn();
3906 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3907 if(!SDSM) return aResult._retn();
3910 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3911 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3912 while ( nIt->more() ) {
3913 const SMDS_MeshNode* elem = nIt->next();
3914 theElems.insert( elem->GetID() );
3917 else { // all nodes of submesh elements
3918 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3919 while ( eIt->more() ) {
3920 const SMDS_MeshElement* anElem = eIt->next();
3921 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3922 while ( nIt->more() ) {
3923 const SMDS_MeshElement* elem = nIt->next();
3924 theElems.insert( elem->GetID() );
3929 aResult->length(theElems.size());
3930 set<int>::iterator itElem;
3932 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3933 aResult[i++] = *itElem;
3935 SMESH_CATCH( SMESH::throwCorbaException );
3937 return aResult._retn();
3940 //=============================================================================
3942 * Returns type of elements for given submesh
3944 //=============================================================================
3946 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3947 throw (SALOME::SALOME_Exception)
3949 SMESH::ElementType type;
3953 _preMeshInfo->FullLoadFromFile();
3955 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3956 if(!SM) return SMESH::ALL;
3958 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3959 if(!SDSM) return SMESH::ALL;
3961 if(SDSM->NbElements()==0)
3962 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3964 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3965 const SMDS_MeshElement* anElem = eIt->next();
3967 type = ( SMESH::ElementType ) anElem->GetType();
3969 SMESH_CATCH( SMESH::throwCorbaException );
3975 //=============================================================================
3977 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3979 //=============================================================================
3981 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3984 _preMeshInfo->FullLoadFromFile();
3986 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3988 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3993 //=============================================================================
3995 * Get XYZ coordinates of node as list of double
3996 * If there is not node for given ID - returns empty list
3998 //=============================================================================
4000 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4003 _preMeshInfo->FullLoadFromFile();
4005 SMESH::double_array_var aResult = new SMESH::double_array();
4006 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4007 if ( aSMESHDS_Mesh == NULL )
4008 return aResult._retn();
4011 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4013 return aResult._retn();
4017 aResult[0] = aNode->X();
4018 aResult[1] = aNode->Y();
4019 aResult[2] = aNode->Z();
4020 return aResult._retn();
4024 //=============================================================================
4026 * For given node returns list of IDs of inverse elements
4027 * If there is not node for given ID - returns empty list
4029 //=============================================================================
4031 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4034 _preMeshInfo->FullLoadFromFile();
4036 SMESH::long_array_var aResult = new SMESH::long_array();
4037 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4038 if ( aSMESHDS_Mesh == NULL )
4039 return aResult._retn();
4042 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4044 return aResult._retn();
4046 // find inverse elements
4047 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4048 TColStd_SequenceOfInteger IDs;
4049 while(eIt->more()) {
4050 const SMDS_MeshElement* elem = eIt->next();
4051 IDs.Append(elem->GetID());
4053 if(IDs.Length()>0) {
4054 aResult->length(IDs.Length());
4056 for(; i<=IDs.Length(); i++) {
4057 aResult[i-1] = IDs.Value(i);
4060 return aResult._retn();
4063 //=============================================================================
4065 * \brief Return position of a node on shape
4067 //=============================================================================
4069 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4072 _preMeshInfo->FullLoadFromFile();
4074 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4075 aNodePosition->shapeID = 0;
4076 aNodePosition->shapeType = GEOM::SHAPE;
4078 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4079 if ( !mesh ) return aNodePosition;
4081 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4083 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4085 aNodePosition->shapeID = aNode->getshapeId();
4086 switch ( pos->GetTypeOfPosition() ) {
4088 aNodePosition->shapeType = GEOM::EDGE;
4089 aNodePosition->params.length(1);
4090 aNodePosition->params[0] =
4091 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4094 aNodePosition->shapeType = GEOM::FACE;
4095 aNodePosition->params.length(2);
4096 aNodePosition->params[0] =
4097 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4098 aNodePosition->params[1] =
4099 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4101 case SMDS_TOP_VERTEX:
4102 aNodePosition->shapeType = GEOM::VERTEX;
4104 case SMDS_TOP_3DSPACE:
4105 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4106 aNodePosition->shapeType = GEOM::SOLID;
4107 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4108 aNodePosition->shapeType = GEOM::SHELL;
4114 return aNodePosition;
4117 //=============================================================================
4119 * \brief Return position of an element on shape
4121 //=============================================================================
4123 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4126 _preMeshInfo->FullLoadFromFile();
4128 SMESH::ElementPosition anElementPosition;
4129 anElementPosition.shapeID = 0;
4130 anElementPosition.shapeType = GEOM::SHAPE;
4132 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4133 if ( !mesh ) return anElementPosition;
4135 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4137 anElementPosition.shapeID = anElem->getshapeId();
4138 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4139 if ( !aSp.IsNull() ) {
4140 switch ( aSp.ShapeType() ) {
4142 anElementPosition.shapeType = GEOM::EDGE;
4145 anElementPosition.shapeType = GEOM::FACE;
4148 anElementPosition.shapeType = GEOM::VERTEX;
4151 anElementPosition.shapeType = GEOM::SOLID;
4154 anElementPosition.shapeType = GEOM::SHELL;
4160 return anElementPosition;
4163 //=============================================================================
4165 * If given element is node returns IDs of shape from position
4166 * If there is not node for given ID - returns -1
4168 //=============================================================================
4170 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4173 _preMeshInfo->FullLoadFromFile();
4175 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4176 if ( aSMESHDS_Mesh == NULL )
4180 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4182 return aNode->getshapeId();
4189 //=============================================================================
4191 * For given element returns ID of result shape after
4192 * ::FindShape() from SMESH_MeshEditor
4193 * If there is not element for given ID - returns -1
4195 //=============================================================================
4197 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4200 _preMeshInfo->FullLoadFromFile();
4202 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4203 if ( aSMESHDS_Mesh == NULL )
4206 // try to find element
4207 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4211 ::SMESH_MeshEditor aMeshEditor(_impl);
4212 int index = aMeshEditor.FindShape( elem );
4220 //=============================================================================
4222 * Returns number of nodes for given element
4223 * If there is not element for given ID - returns -1
4225 //=============================================================================
4227 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4230 _preMeshInfo->FullLoadFromFile();
4232 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4233 if ( aSMESHDS_Mesh == NULL ) return -1;
4234 // try to find element
4235 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4236 if(!elem) return -1;
4237 return elem->NbNodes();
4241 //=============================================================================
4243 * Returns ID of node by given index for given element
4244 * If there is not element for given ID - returns -1
4245 * If there is not node for given index - returns -2
4247 //=============================================================================
4249 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4252 _preMeshInfo->FullLoadFromFile();
4254 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4255 if ( aSMESHDS_Mesh == NULL ) return -1;
4256 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4257 if(!elem) return -1;
4258 if( index>=elem->NbNodes() || index<0 ) return -1;
4259 return elem->GetNode(index)->GetID();
4262 //=============================================================================
4264 * Returns IDs of nodes of given element
4266 //=============================================================================
4268 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4271 _preMeshInfo->FullLoadFromFile();
4273 SMESH::long_array_var aResult = new SMESH::long_array();
4274 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4276 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4278 aResult->length( elem->NbNodes() );
4279 for ( int i = 0; i < elem->NbNodes(); ++i )
4280 aResult[ i ] = elem->GetNode( i )->GetID();
4283 return aResult._retn();
4286 //=============================================================================
4288 * Returns true if given node is medium node
4289 * in given quadratic element
4291 //=============================================================================
4293 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4296 _preMeshInfo->FullLoadFromFile();
4298 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4299 if ( aSMESHDS_Mesh == NULL ) return false;
4301 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4302 if(!aNode) return false;
4303 // try to find element
4304 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4305 if(!elem) return false;
4307 return elem->IsMediumNode(aNode);
4311 //=============================================================================
4313 * Returns true if given node is medium node
4314 * in one of quadratic elements
4316 //=============================================================================
4318 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4319 SMESH::ElementType theElemType)
4322 _preMeshInfo->FullLoadFromFile();
4324 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4325 if ( aSMESHDS_Mesh == NULL ) return false;
4328 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4329 if(!aNode) return false;
4331 SMESH_MesherHelper aHelper( *(_impl) );
4333 SMDSAbs_ElementType aType;
4334 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4335 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4336 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4337 else aType = SMDSAbs_All;
4339 return aHelper.IsMedium(aNode,aType);
4343 //=============================================================================
4345 * Returns number of edges for given element
4347 //=============================================================================
4349 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4352 _preMeshInfo->FullLoadFromFile();
4354 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4355 if ( aSMESHDS_Mesh == NULL ) return -1;
4356 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4357 if(!elem) return -1;
4358 return elem->NbEdges();
4362 //=============================================================================
4364 * Returns number of faces for given element
4366 //=============================================================================
4368 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4371 _preMeshInfo->FullLoadFromFile();
4373 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4374 if ( aSMESHDS_Mesh == NULL ) return -1;
4375 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4376 if(!elem) return -1;
4377 return elem->NbFaces();
4380 //=======================================================================
4381 //function : GetElemFaceNodes
4382 //purpose : Returns nodes of given face (counted from zero) for given element.
4383 //=======================================================================
4385 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4386 CORBA::Short faceIndex)
4389 _preMeshInfo->FullLoadFromFile();
4391 SMESH::long_array_var aResult = new SMESH::long_array();
4392 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4394 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4396 SMDS_VolumeTool vtool( elem );
4397 if ( faceIndex < vtool.NbFaces() )
4399 aResult->length( vtool.NbFaceNodes( faceIndex ));
4400 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4401 for ( int i = 0; i < aResult->length(); ++i )
4402 aResult[ i ] = nn[ i ]->GetID();
4406 return aResult._retn();
4409 //=======================================================================
4410 //function : GetElemFaceNodes
4411 //purpose : Returns three components of normal of given mesh face.
4412 //=======================================================================
4414 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4415 CORBA::Boolean normalized)
4418 _preMeshInfo->FullLoadFromFile();
4420 SMESH::double_array_var aResult = new SMESH::double_array();
4422 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4425 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4427 aResult->length( 3 );
4428 aResult[ 0 ] = normal.X();
4429 aResult[ 1 ] = normal.Y();
4430 aResult[ 2 ] = normal.Z();
4433 return aResult._retn();
4436 //=======================================================================
4437 //function : FindElementByNodes
4438 //purpose : Returns an element based on all given nodes.
4439 //=======================================================================
4441 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4444 _preMeshInfo->FullLoadFromFile();
4446 CORBA::Long elemID(0);
4447 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4449 vector< const SMDS_MeshNode * > nn( nodes.length() );
4450 for ( int i = 0; i < nodes.length(); ++i )
4451 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4454 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4455 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4456 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4457 _impl->NbVolumes( ORDER_QUADRATIC )))
4458 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4460 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4465 //=============================================================================
4467 * Returns true if given element is polygon
4469 //=============================================================================
4471 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4474 _preMeshInfo->FullLoadFromFile();
4476 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4477 if ( aSMESHDS_Mesh == NULL ) return false;
4478 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4479 if(!elem) return false;
4480 return elem->IsPoly();
4484 //=============================================================================
4486 * Returns true if given element is quadratic
4488 //=============================================================================
4490 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4493 _preMeshInfo->FullLoadFromFile();
4495 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4496 if ( aSMESHDS_Mesh == NULL ) return false;
4497 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4498 if(!elem) return false;
4499 return elem->IsQuadratic();
4502 //=============================================================================
4504 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4506 //=============================================================================
4508 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4511 _preMeshInfo->FullLoadFromFile();
4513 if ( const SMDS_BallElement* ball =
4514 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4515 return ball->GetDiameter();
4520 //=============================================================================
4522 * Returns bary center for given element
4524 //=============================================================================
4526 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4529 _preMeshInfo->FullLoadFromFile();
4531 SMESH::double_array_var aResult = new SMESH::double_array();
4532 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4533 if ( aSMESHDS_Mesh == NULL )
4534 return aResult._retn();
4536 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4538 return aResult._retn();
4540 if(elem->GetType()==SMDSAbs_Volume) {
4541 SMDS_VolumeTool aTool;
4542 if(aTool.Set(elem)) {
4544 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4549 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4551 double x=0., y=0., z=0.;
4552 for(; anIt->more(); ) {
4554 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4568 return aResult._retn();
4571 //================================================================================
4573 * \brief Create a group of elements preventing computation of a sub-shape
4575 //================================================================================
4577 SMESH::ListOfGroups*
4578 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4579 const char* theGroupName )
4580 throw ( SALOME::SALOME_Exception )
4582 Unexpect aCatch(SALOME_SalomeException);
4584 if ( !theGroupName || strlen( theGroupName) == 0 )
4585 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4587 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4589 // submesh by subshape id
4590 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4591 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4594 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4595 if ( error && !error->myBadElements.empty())
4597 // sort bad elements by type
4598 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4599 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4600 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4601 for ( ; elemIt != elemEnd; ++elemIt )
4603 const SMDS_MeshElement* elem = *elemIt;
4604 if ( !elem ) continue;
4606 if ( elem->GetID() < 1 )
4608 // elem is a temporary element, make a real element
4609 vector< const SMDS_MeshNode* > nodes;
4610 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4611 while ( nIt->more() && elem )
4613 nodes.push_back( nIt->next() );
4614 if ( nodes.back()->GetID() < 1 )
4615 elem = 0; // a temporary element on temporary nodes
4619 ::SMESH_MeshEditor editor( _impl );
4620 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4624 elemsByType[ elem->GetType() ].push_back( elem );
4627 // how many groups to create?
4629 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4630 nbTypes += int( !elemsByType[ i ].empty() );
4631 groups->length( nbTypes );
4634 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4636 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4637 if ( elems.empty() ) continue;
4639 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4640 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4642 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4643 SMESH::SMESH_Mesh_var mesh = _this();
4644 SALOMEDS::SObject_wrap aSO =
4645 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4646 GEOM::GEOM_Object::_nil(), theGroupName);
4647 aSO->_is_nil(); // avoid "unused variable" warning
4649 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4650 if ( !grp_i ) continue;
4652 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4653 for ( size_t iE = 0; iE < elems.size(); ++iE )
4654 grpDS->SMDSGroup().Add( elems[ iE ]);
4659 return groups._retn();
4662 //=============================================================================
4664 * Create and publish group servants if any groups were imported or created anyhow
4666 //=============================================================================
4668 void SMESH_Mesh_i::CreateGroupServants()
4670 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4671 SMESH::SMESH_Mesh_var aMesh = _this();
4674 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4675 while ( groupIt->more() )
4677 ::SMESH_Group* group = groupIt->next();
4678 int anId = group->GetGroupDS()->GetID();
4680 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4681 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4683 addedIDs.insert( anId );
4685 SMESH_GroupBase_i* aGroupImpl;
4687 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4688 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4690 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4691 shape = groupOnGeom->GetShape();
4694 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4697 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4698 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4699 aGroupImpl->Register();
4701 // register CORBA object for persistence
4702 int nextId = _gen_i->RegisterObject( groupVar );
4703 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4704 else { nextId = 0; } // avoid "unused variable" warning in release mode
4706 // publishing the groups in the study
4707 if ( !aStudy->_is_nil() ) {
4708 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4709 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4712 if ( !addedIDs.empty() )
4715 set<int>::iterator id = addedIDs.begin();
4716 for ( ; id != addedIDs.end(); ++id )
4718 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4719 int i = std::distance( _mapGroups.begin(), it );
4720 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4725 //=============================================================================
4727 * \brief Return groups cantained in _mapGroups by their IDs
4729 //=============================================================================
4731 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4733 int nbGroups = groupIDs.size();
4734 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4735 aList->length( nbGroups );
4737 list<int>::const_iterator ids = groupIDs.begin();
4738 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4740 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4741 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4742 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4744 aList->length( nbGroups );
4745 return aList._retn();
4748 //=============================================================================
4750 * \brief Return information about imported file
4752 //=============================================================================
4754 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4756 SMESH::MedFileInfo_var res( _medFileInfo );
4757 if ( !res.operator->() ) {
4758 res = new SMESH::MedFileInfo;
4760 res->fileSize = res->major = res->minor = res->release = -1;
4765 //=============================================================================
4767 * \brief Pass names of mesh groups from study to mesh DS
4769 //=============================================================================
4771 void SMESH_Mesh_i::checkGroupNames()
4773 int nbGrp = NbGroups();
4777 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4778 if ( aStudy->_is_nil() )
4779 return; // nothing to do
4781 SMESH::ListOfGroups* grpList = 0;
4782 // avoid dump of "GetGroups"
4784 // store python dump into a local variable inside local scope
4785 SMESH::TPythonDump pDump; // do not delete this line of code
4786 grpList = GetGroups();
4789 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4790 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4793 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4794 if ( aGrpSO->_is_nil() )
4796 // correct name of the mesh group if necessary
4797 const char* guiName = aGrpSO->GetName();
4798 if ( strcmp(guiName, aGrp->GetName()) )
4799 aGrp->SetName( guiName );
4803 //=============================================================================
4805 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4807 //=============================================================================
4808 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4810 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4814 //=============================================================================
4816 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4818 //=============================================================================
4820 char* SMESH_Mesh_i::GetParameters()
4822 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4825 //=============================================================================
4827 * \brief Returns list of notebook variables used for last Mesh operation
4829 //=============================================================================
4830 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4832 SMESH::string_array_var aResult = new SMESH::string_array();
4833 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4835 CORBA::String_var aParameters = GetParameters();
4836 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4837 if ( !aStudy->_is_nil()) {
4838 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4839 if(aSections->length() > 0) {
4840 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4841 aResult->length(aVars.length());
4842 for(int i = 0;i < aVars.length();i++)
4843 aResult[i] = CORBA::string_dup( aVars[i]);
4847 return aResult._retn();
4850 //=======================================================================
4851 //function : GetTypes
4852 //purpose : Returns types of elements it contains
4853 //=======================================================================
4855 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4858 return _preMeshInfo->GetTypes();
4860 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4864 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4865 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4866 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4867 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4868 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4869 types->length( nbTypes );
4871 return types._retn();
4874 //=======================================================================
4875 //function : GetMesh
4876 //purpose : Returns self
4877 //=======================================================================
4879 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4881 return SMESH::SMESH_Mesh::_duplicate( _this() );
4884 //=======================================================================
4885 //function : IsMeshInfoCorrect
4886 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4887 // * happen if mesh data is not yet fully loaded from the file of study.
4888 //=======================================================================
4890 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4892 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4895 //=============================================================================
4897 * \brief Returns number of mesh elements per each \a EntityType
4899 //=============================================================================
4901 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4904 return _preMeshInfo->GetMeshInfo();
4906 SMESH::long_array_var aRes = new SMESH::long_array();
4907 aRes->length(SMESH::Entity_Last);
4908 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4910 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4912 return aRes._retn();
4913 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4914 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4915 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4916 return aRes._retn();
4919 //=============================================================================
4921 * \brief Returns number of mesh elements per each \a ElementType
4923 //=============================================================================
4925 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
4927 SMESH::long_array_var aRes = new SMESH::long_array();
4928 aRes->length(SMESH::NB_ELEMENT_TYPES);
4929 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4932 const SMDS_MeshInfo* meshInfo = 0;
4934 meshInfo = _preMeshInfo;
4935 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
4936 meshInfo = & meshDS->GetMeshInfo();
4939 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4940 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
4942 return aRes._retn();
4945 //=============================================================================
4947 * Collect statistic of mesh elements given by iterator
4949 //=============================================================================
4951 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4952 SMESH::long_array& theInfo)
4954 if (!theItr) return;
4955 while (theItr->more())
4956 theInfo[ theItr->next()->GetEntityType() ]++;
4959 //=============================================================================
4960 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
4961 * SMESH::ElementType type) */
4963 using namespace SMESH::Controls;
4964 //-----------------------------------------------------------------------------
4965 struct PredicateIterator : public SMDS_ElemIterator
4967 SMDS_ElemIteratorPtr _elemIter;
4968 PredicatePtr _predicate;
4969 const SMDS_MeshElement* _elem;
4971 PredicateIterator( SMDS_ElemIteratorPtr iterator,
4972 PredicatePtr predicate):
4973 _elemIter(iterator), _predicate(predicate)
4981 virtual const SMDS_MeshElement* next()
4983 const SMDS_MeshElement* res = _elem;
4985 while ( _elemIter->more() && !_elem )
4987 _elem = _elemIter->next();
4988 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
4995 //-----------------------------------------------------------------------------
4996 struct IDSourceIterator : public SMDS_ElemIterator
4998 const CORBA::Long* _idPtr;
4999 const CORBA::Long* _idEndPtr;
5000 SMESH::long_array_var _idArray;
5001 const SMDS_Mesh* _mesh;
5002 const SMDSAbs_ElementType _type;
5003 const SMDS_MeshElement* _elem;
5005 IDSourceIterator( const SMDS_Mesh* mesh,
5006 const CORBA::Long* ids,
5008 SMDSAbs_ElementType type):
5009 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5011 if ( _idPtr && nbIds && _mesh )
5014 IDSourceIterator( const SMDS_Mesh* mesh,
5015 SMESH::long_array* idArray,
5016 SMDSAbs_ElementType type):
5017 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5019 if ( idArray && _mesh )
5021 _idPtr = &_idArray[0];
5022 _idEndPtr = _idPtr + _idArray->length();
5030 virtual const SMDS_MeshElement* next()
5032 const SMDS_MeshElement* res = _elem;
5034 while ( _idPtr < _idEndPtr && !_elem )
5036 if ( _type == SMDSAbs_Node )
5038 _elem = _mesh->FindNode( *_idPtr++ );
5040 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5041 _elem->GetType() != _type )
5049 //-----------------------------------------------------------------------------
5051 struct NodeOfElemIterator : public SMDS_ElemIterator
5053 TColStd_MapOfInteger _checkedNodeIDs;
5054 SMDS_ElemIteratorPtr _elemIter;
5055 SMDS_ElemIteratorPtr _nodeIter;
5056 const SMDS_MeshElement* _node;
5058 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5060 if ( _elemIter && _elemIter->more() )
5062 _nodeIter = _elemIter->next()->nodesIterator();
5070 virtual const SMDS_MeshElement* next()
5072 const SMDS_MeshElement* res = _node;
5074 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5076 if ( _nodeIter->more() )
5078 _node = _nodeIter->next();
5079 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5084 _nodeIter = _elemIter->next()->nodesIterator();
5092 //=============================================================================
5094 * Return iterator on elements of given type in given object
5096 //=============================================================================
5098 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5099 SMESH::ElementType theType)
5101 SMDS_ElemIteratorPtr elemIt;
5102 bool typeOK = false;
5103 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5105 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5106 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5107 if ( !mesh_i ) return elemIt;
5108 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5110 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5112 elemIt = meshDS->elementsIterator( elemType );
5115 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5117 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5120 elemIt = sm->GetElements();
5121 if ( elemType != SMDSAbs_Node )
5123 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5124 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5128 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5130 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5131 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5133 elemIt = groupDS->GetElements();
5134 typeOK = ( groupDS->GetType() == elemType );
5137 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5139 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5141 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5142 if ( pred_i && pred_i->GetPredicate() )
5144 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5145 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5146 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5147 typeOK = ( filterType == elemType );
5153 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5154 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5155 if ( isNodes && elemType != SMDSAbs_Node )
5157 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5160 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5161 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5165 SMESH::long_array_var ids = theObject->GetIDs();
5166 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5168 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5171 if ( elemIt && elemIt->more() && !typeOK )
5173 if ( elemType == SMDSAbs_Node )
5175 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5179 elemIt = SMDS_ElemIteratorPtr();
5185 //=============================================================================
5186 namespace // Finding concurrent hypotheses
5187 //=============================================================================
5191 * \brief mapping of mesh dimension into shape type
5193 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5195 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5197 case 0: aType = TopAbs_VERTEX; break;
5198 case 1: aType = TopAbs_EDGE; break;
5199 case 2: aType = TopAbs_FACE; break;
5201 default:aType = TopAbs_SOLID; break;
5206 //-----------------------------------------------------------------------------
5208 * \brief Internal structure used to find concurent submeshes
5210 * It represents a pair < submesh, concurent dimension >, where
5211 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5212 * with another submesh. In other words, it is dimension of a hypothesis assigned
5219 int _dim; //!< a dimension the algo can build (concurrent dimension)
5220 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5221 TopTools_MapOfShape _shapeMap;
5222 SMESH_subMesh* _subMesh;
5223 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5225 //-----------------------------------------------------------------------------
5226 // Return the algorithm
5227 const SMESH_Algo* GetAlgo() const
5228 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5230 //-----------------------------------------------------------------------------
5232 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5234 const TopoDS_Shape& theShape)
5236 _subMesh = (SMESH_subMesh*)theSubMesh;
5237 SetShape( theDim, theShape );
5240 //-----------------------------------------------------------------------------
5242 void SetShape(const int theDim,
5243 const TopoDS_Shape& theShape)
5246 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5247 if (_dim >= _ownDim)
5248 _shapeMap.Add( theShape );
5250 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5251 for( ; anExp.More(); anExp.Next() )
5252 _shapeMap.Add( anExp.Current() );
5256 //-----------------------------------------------------------------------------
5257 //! Check sharing of sub-shapes
5258 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5259 const TopTools_MapOfShape& theToFind,
5260 const TopAbs_ShapeEnum theType)
5262 bool isShared = false;
5263 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5264 for (; !isShared && anItr.More(); anItr.Next() )
5266 const TopoDS_Shape aSubSh = anItr.Key();
5267 // check for case when concurrent dimensions are same
5268 isShared = theToFind.Contains( aSubSh );
5269 // check for sub-shape with concurrent dimension
5270 TopExp_Explorer anExp( aSubSh, theType );
5271 for ( ; !isShared && anExp.More(); anExp.Next() )
5272 isShared = theToFind.Contains( anExp.Current() );
5277 //-----------------------------------------------------------------------------
5278 //! check algorithms
5279 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5280 const SMESHDS_Hypothesis* theA2)
5282 if ( !theA1 || !theA2 ||
5283 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5284 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5285 return false; // one of the hypothesis is not algorithm
5286 // check algorithm names (should be equal)
5287 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5291 //-----------------------------------------------------------------------------
5292 //! Check if sub-shape hypotheses are concurrent
5293 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5295 if ( _subMesh == theOther->_subMesh )
5296 return false; // same sub-shape - should not be
5298 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5299 // any of the two submeshes is not on COMPOUND shape )
5300 // -> no concurrency
5301 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5302 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5303 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5304 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5305 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5308 // bool checkSubShape = ( _dim >= theOther->_dim )
5309 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5310 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5311 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5312 if ( !checkSubShape )
5315 // check algorithms to be same
5316 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5317 return true; // different algorithms -> concurrency !
5319 // check hypothesises for concurrence (skip first as algorithm)
5321 // pointers should be same, because it is referened from mesh hypothesis partition
5322 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5323 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5324 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5325 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5327 // the submeshes are concurrent if their algorithms has different parameters
5328 return nbSame != theOther->_hypotheses.size() - 1;
5331 // Return true if algorithm of this SMESH_DimHyp is used if no
5332 // sub-mesh order is imposed by the user
5333 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5335 // NeedDiscreteBoundary() algo has a higher priority
5336 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5337 theOther->GetAlgo()->NeedDiscreteBoundary() )
5338 return !this->GetAlgo()->NeedDiscreteBoundary();
5340 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5343 }; // end of SMESH_DimHyp
5344 //-----------------------------------------------------------------------------
5346 typedef list<const SMESH_DimHyp*> TDimHypList;
5348 //-----------------------------------------------------------------------------
5350 void addDimHypInstance(const int theDim,
5351 const TopoDS_Shape& theShape,
5352 const SMESH_Algo* theAlgo,
5353 const SMESH_subMesh* theSubMesh,
5354 const list <const SMESHDS_Hypothesis*>& theHypList,
5355 TDimHypList* theDimHypListArr )
5357 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5358 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5359 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5360 dimHyp->_hypotheses.push_front(theAlgo);
5361 listOfdimHyp.push_back( dimHyp );
5364 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5365 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5366 theHypList.begin(), theHypList.end() );
5369 //-----------------------------------------------------------------------------
5370 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5371 TDimHypList& theListOfConcurr)
5373 if ( theListOfConcurr.empty() )
5375 theListOfConcurr.push_back( theDimHyp );
5379 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5380 while ( hypIt != theListOfConcurr.end() &&
5381 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5383 theListOfConcurr.insert( hypIt, theDimHyp );
5387 //-----------------------------------------------------------------------------
5388 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5389 const TDimHypList& theListOfDimHyp,
5390 TDimHypList& theListOfConcurrHyp,
5391 set<int>& theSetOfConcurrId )
5393 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5394 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5396 const SMESH_DimHyp* curDimHyp = *rIt;
5397 if ( curDimHyp == theDimHyp )
5398 break; // meet own dimHyp pointer in same dimension
5400 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5401 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5403 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5408 //-----------------------------------------------------------------------------
5409 void unionLists(TListOfInt& theListOfId,
5410 TListOfListOfInt& theListOfListOfId,
5413 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5414 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5416 continue; //skip already treated lists
5417 // check if other list has any same submesh object
5418 TListOfInt& otherListOfId = *it;
5419 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5420 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5423 // union two lists (from source into target)
5424 TListOfInt::iterator it2 = otherListOfId.begin();
5425 for ( ; it2 != otherListOfId.end(); it2++ ) {
5426 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5427 theListOfId.push_back(*it2);
5429 // clear source list
5430 otherListOfId.clear();
5433 //-----------------------------------------------------------------------------
5435 //! free memory allocated for dimension-hypothesis objects
5436 void removeDimHyps( TDimHypList* theArrOfList )
5438 for (int i = 0; i < 4; i++ ) {
5439 TDimHypList& listOfdimHyp = theArrOfList[i];
5440 TDimHypList::const_iterator it = listOfdimHyp.begin();
5441 for ( ; it != listOfdimHyp.end(); it++ )
5446 //-----------------------------------------------------------------------------
5448 * \brief find common submeshes with given submesh
5449 * \param theSubMeshList list of already collected submesh to check
5450 * \param theSubMesh given submesh to intersect with other
5451 * \param theCommonSubMeshes collected common submeshes
5453 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5454 const SMESH_subMesh* theSubMesh,
5455 set<const SMESH_subMesh*>& theCommon )
5459 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5460 for ( ; it != theSubMeshList.end(); it++ )
5461 theSubMesh->FindIntersection( *it, theCommon );
5462 theSubMeshList.push_back( theSubMesh );
5463 //theCommon.insert( theSubMesh );
5466 //-----------------------------------------------------------------------------
5467 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5469 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5470 for ( ; listsIt != smLists.end(); ++listsIt )
5472 const TListOfInt& smIDs = *listsIt;
5473 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5481 //=============================================================================
5483 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5485 //=============================================================================
5487 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5489 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5490 if ( isSubMeshInList( submeshID, anOrder ))
5493 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5494 return isSubMeshInList( submeshID, allConurrent );
5497 //=============================================================================
5499 * \brief Return submesh objects list in meshing order
5501 //=============================================================================
5503 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5505 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5507 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5509 return aResult._retn();
5511 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5512 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5513 anOrder.splice( anOrder.end(), allConurrent );
5516 TListOfListOfInt::iterator listIt = anOrder.begin();
5517 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5518 unionLists( *listIt, anOrder, listIndx + 1 );
5520 // convert submesh ids into interface instances
5521 // and dump command into python
5522 convertMeshOrder( anOrder, aResult, false );
5524 return aResult._retn();
5527 //=============================================================================
5529 * \brief Finds concurrent sub-meshes
5531 //=============================================================================
5533 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5535 TListOfListOfInt anOrder;
5536 ::SMESH_Mesh& mesh = GetImpl();
5538 // collect submeshes and detect concurrent algorithms and hypothesises
5539 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5541 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5542 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5543 ::SMESH_subMesh* sm = (*i_sm).second;
5545 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5547 // list of assigned hypothesises
5548 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5549 // Find out dimensions where the submesh can be concurrent.
5550 // We define the dimensions by algo of each of hypotheses in hypList
5551 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5552 for( ; hypIt != hypList.end(); hypIt++ ) {
5553 SMESH_Algo* anAlgo = 0;
5554 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5555 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5556 // hyp it-self is algo
5557 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5559 // try to find algorithm with help of sub-shapes
5560 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5561 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5562 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5565 continue; // no algorithm assigned to a current submesh
5567 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5568 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5570 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5571 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5572 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5574 } // end iterations on submesh
5576 // iterate on created dimension-hypotheses and check for concurrents
5577 for ( int i = 0; i < 4; i++ ) {
5578 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5579 // check for concurrents in own and other dimensions (step-by-step)
5580 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5581 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5582 const SMESH_DimHyp* dimHyp = *dhIt;
5583 TDimHypList listOfConcurr;
5584 set<int> setOfConcurrIds;
5585 // looking for concurrents and collect into own list
5586 for ( int j = i; j < 4; j++ )
5587 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5588 // check if any concurrents found
5589 if ( listOfConcurr.size() > 0 ) {
5590 // add own submesh to list of concurrent
5591 addInOrderOfPriority( dimHyp, listOfConcurr );
5592 list<int> listOfConcurrIds;
5593 TDimHypList::iterator hypIt = listOfConcurr.begin();
5594 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5595 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5596 anOrder.push_back( listOfConcurrIds );
5601 removeDimHyps(dimHypListArr);
5603 // now, minimise the number of concurrent groups
5604 // Here we assume that lists of submeshes can have same submesh
5605 // in case of multi-dimension algorithms, as result
5606 // list with common submesh has to be united into one list
5608 TListOfListOfInt::iterator listIt = anOrder.begin();
5609 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5610 unionLists( *listIt, anOrder, listIndx + 1 );
5616 //=============================================================================
5618 * \brief Set submesh object order
5619 * \param theSubMeshArray submesh array order
5621 //=============================================================================
5623 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5626 _preMeshInfo->ForgetOrLoad();
5629 ::SMESH_Mesh& mesh = GetImpl();
5631 TPythonDump aPythonDump; // prevent dump of called methods
5632 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5634 TListOfListOfInt subMeshOrder;
5635 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5637 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5638 TListOfInt subMeshIds;
5639 aPythonDump << "[ ";
5640 // Collect subMeshes which should be clear
5641 // do it list-by-list, because modification of submesh order
5642 // take effect between concurrent submeshes only
5643 set<const SMESH_subMesh*> subMeshToClear;
5644 list<const SMESH_subMesh*> subMeshList;
5645 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5647 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5649 aPythonDump << ", ";
5650 aPythonDump << subMesh;
5651 subMeshIds.push_back( subMesh->GetId() );
5652 // detect common parts of submeshes
5653 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5654 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5656 aPythonDump << " ]";
5657 subMeshOrder.push_back( subMeshIds );
5659 // clear collected submeshes
5660 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5661 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5662 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5663 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5665 aPythonDump << " ])";
5667 mesh.SetMeshOrder( subMeshOrder );
5673 //=============================================================================
5675 * \brief Convert submesh ids into submesh interfaces
5677 //=============================================================================
5679 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5680 SMESH::submesh_array_array& theResOrder,
5681 const bool theIsDump)
5683 int nbSet = theIdsOrder.size();
5684 TPythonDump aPythonDump; // prevent dump of called methods
5686 aPythonDump << "[ ";
5687 theResOrder.length(nbSet);
5688 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5690 for( ; it != theIdsOrder.end(); it++ ) {
5691 // translate submesh identificators into submesh objects
5692 // takeing into account real number of concurrent lists
5693 const TListOfInt& aSubOrder = (*it);
5694 if (!aSubOrder.size())
5697 aPythonDump << "[ ";
5698 // convert shape indeces into interfaces
5699 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5700 aResSubSet->length(aSubOrder.size());
5701 TListOfInt::const_iterator subIt = aSubOrder.begin();
5703 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5704 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5706 SMESH::SMESH_subMesh_var subMesh =
5707 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5710 aPythonDump << ", ";
5711 aPythonDump << subMesh;
5713 aResSubSet[ j++ ] = subMesh;
5716 aPythonDump << " ]";
5718 theResOrder[ listIndx++ ] = aResSubSet;
5720 // correct number of lists
5721 theResOrder.length( listIndx );
5724 // finilise python dump
5725 aPythonDump << " ]";
5726 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5730 //================================================================================
5732 // Implementation of SMESH_MeshPartDS
5734 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5735 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5737 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5738 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5740 _meshDS = mesh_i->GetImpl().GetMeshDS();
5742 SetPersistentId( _meshDS->GetPersistentId() );
5744 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5746 // <meshPart> is the whole mesh
5747 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5749 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5750 myGroupSet = _meshDS->GetGroups();
5755 SMESH::long_array_var anIDs = meshPart->GetIDs();
5756 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5757 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5759 for (int i=0; i < anIDs->length(); i++)
5760 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5761 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5766 for (int i=0; i < anIDs->length(); i++)
5767 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5768 if ( _elements[ e->GetType() ].insert( e ).second )
5771 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5772 while ( nIt->more() )
5774 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5775 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5782 _meshDS = 0; // to enforce iteration on _elements and _nodes
5785 // -------------------------------------------------------------------------------------
5786 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5787 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5790 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5791 for ( ; partIt != meshPart.end(); ++partIt )
5792 if ( const SMDS_MeshElement * e = *partIt )
5793 if ( _elements[ e->GetType() ].insert( e ).second )
5796 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5797 while ( nIt->more() )
5799 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5800 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5806 // -------------------------------------------------------------------------------------
5807 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5809 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5811 typedef SMDS_SetIterator
5812 <const SMDS_MeshElement*,
5813 TIDSortedElemSet::const_iterator,
5814 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5815 SMDS_MeshElement::GeomFilter
5818 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5820 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5821 _elements[type].end(),
5822 SMDS_MeshElement::GeomFilter( geomType )));
5824 // -------------------------------------------------------------------------------------
5825 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5827 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5829 typedef SMDS_SetIterator
5830 <const SMDS_MeshElement*,
5831 TIDSortedElemSet::const_iterator,
5832 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5833 SMDS_MeshElement::EntityFilter
5836 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5838 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5839 _elements[type].end(),
5840 SMDS_MeshElement::EntityFilter( entity )));
5842 // -------------------------------------------------------------------------------------
5843 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5845 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5846 if ( type == SMDSAbs_All && !_meshDS )
5848 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5850 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5851 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5853 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5855 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5856 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5858 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5859 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5861 // -------------------------------------------------------------------------------------
5862 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5863 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5865 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5866 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5867 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5869 // -------------------------------------------------------------------------------------
5870 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5871 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5872 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5873 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5874 #undef _GET_ITER_DEFINE
5876 // END Implementation of SMESH_MeshPartDS
5878 //================================================================================