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 //================================================================================
2853 * \brief Export a part of mesh to a med file
2855 //================================================================================
2857 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
2859 CORBA::Boolean auto_groups,
2860 SMESH::MED_VERSION version,
2861 CORBA::Boolean overwrite,
2862 CORBA::Boolean autoDimension,
2863 const GEOM::ListOfFields& fields,
2864 const char* geomAssocFields)
2865 throw (SALOME::SALOME_Exception)
2869 _preMeshInfo->FullLoadFromFile();
2872 bool have0dField = false;
2873 if ( fields.length() > 0 )
2875 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
2876 if ( shapeToMesh->_is_nil() )
2877 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
2879 for ( size_t i = 0; i < fields.length(); ++i )
2881 if ( fields[i]->GetDataType() == GEOM::FDT_String )
2882 THROW_SALOME_CORBA_EXCEPTION
2883 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
2884 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
2885 if ( fieldShape->_is_nil() )
2886 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
2887 if ( !fieldShape->IsSame( shapeToMesh ) )
2888 THROW_SALOME_CORBA_EXCEPTION
2889 ( "Field defined not on shape", SALOME::BAD_PARAM);
2890 if ( fields[i]->GetDimension() == 0 )
2893 if ( geomAssocFields )
2894 for ( int i = 0; geomAssocFields[i]; ++i )
2895 switch ( geomAssocFields[i] ) {
2896 case 'v':case 'e':case 'f':case 's': break;
2897 case 'V':case 'E':case 'F':case 'S': break;
2898 default: THROW_SALOME_CORBA_EXCEPTION
2899 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
2903 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2907 string aMeshName = "Mesh";
2908 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
2909 if ( CORBA::is_nil( meshPart ) ||
2910 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
2912 aMeshName = prepareMeshNameAndGroups(file, overwrite);
2913 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
2914 version, 0, autoDimension, have0dField);
2915 meshDS = _impl->GetMeshDS();
2920 _preMeshInfo->FullLoadFromFile();
2922 PrepareForWriting(file, overwrite);
2924 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2925 if ( !aStudy->_is_nil() ) {
2926 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2927 if ( !SO->_is_nil() ) {
2928 CORBA::String_var name = SO->GetName();
2932 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
2933 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
2934 version, partDS, autoDimension, have0dField);
2935 meshDS = tmpDSDeleter._obj = partDS;
2940 if ( _impl->HasShapeToMesh() )
2942 DriverMED_W_Field fieldWriter;
2943 fieldWriter.SetFile( file );
2944 fieldWriter.SetMeshName( aMeshName );
2945 fieldWriter.AddODOnVertices( have0dField );
2947 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
2951 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
2952 goList->length( fields.length() );
2953 for ( size_t i = 0; i < fields.length(); ++i )
2955 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
2958 TPythonDump() << _this() << ".ExportPartToMED( "
2959 << meshPart << ", r'" << file << "', "
2960 << auto_groups << ", " << version << ", " << overwrite << ", "
2961 << autoDimension << ", " << goList
2962 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
2964 SMESH_CATCH( SMESH::throwCorbaException );
2967 //================================================================================
2969 * Write GEOM fields to MED file
2971 //================================================================================
2973 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
2974 SMESHDS_Mesh* meshDS,
2975 const GEOM::ListOfFields& fields,
2976 const char* geomAssocFields)
2978 #define METH "SMESH_Mesh_i::exportMEDFields() "
2980 if (( fields.length() < 1 ) &&
2981 ( !geomAssocFields || !geomAssocFields[0] ))
2984 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
2985 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
2986 std::vector< int > subIdsByDim[ 4 ];
2987 const double noneDblValue = 0.;
2988 const double noneIntValue = 0;
2990 for ( size_t iF = 0; iF < fields.length(); ++iF )
2994 int dim = fields[ iF ]->GetDimension();
2995 SMDSAbs_ElementType elemType;
2996 TopAbs_ShapeEnum shapeType;
2998 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
2999 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3000 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3001 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3003 continue; // skip fields on whole shape
3005 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3006 if ( dataType == GEOM::FDT_String )
3008 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3009 if ( stepIDs->length() < 1 )
3011 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3012 if ( comps->length() < 1 )
3014 CORBA::String_var name = fields[ iF ]->GetName();
3016 if ( !fieldWriter.Set( meshDS,
3020 ( dataType == GEOM::FDT_Int )))
3023 for ( size_t iC = 0; iC < comps->length(); ++iC )
3024 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3026 // find sub-shape IDs
3028 std::vector< int >& subIds = subIdsByDim[ dim ];
3029 if ( subIds.empty() )
3030 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3031 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3032 subIds.push_back( id );
3036 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3040 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3042 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3043 if ( step->_is_nil() )
3046 CORBA::Long stamp = step->GetStamp();
3047 CORBA::Long id = step->GetID();
3048 fieldWriter.SetDtIt( int( stamp ), int( id ));
3050 // fill dblVals or intVals
3053 case GEOM::FDT_Double:
3055 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3056 if ( dblStep->_is_nil() ) continue;
3057 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3058 if ( vv->length() != subIds.size() )
3059 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3060 for ( size_t i = 0; i < vv->length(); ++i )
3061 dblVals[ subIds[ i ]] = vv[ i ];
3066 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3067 if ( intStep->_is_nil() ) continue;
3068 GEOM::ListOfLong_var vv = intStep->GetValues();
3069 if ( vv->length() != subIds.size() )
3070 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3071 for ( size_t i = 0; i < vv->length(); ++i )
3072 intVals[ subIds[ i ]] = (int) vv[ i ];
3075 case GEOM::FDT_Bool:
3077 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3078 if ( boolStep->_is_nil() ) continue;
3079 GEOM::short_array_var vv = boolStep->GetValues();
3080 if ( vv->length() != subIds.size() )
3081 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3082 for ( size_t i = 0; i < vv->length(); ++i )
3083 intVals[ subIds[ i ]] = (int) vv[ i ];
3089 // pass values to fieldWriter
3090 elemIt = fieldWriter.GetOrderedElems();
3091 if ( dataType == GEOM::FDT_Double )
3092 while ( elemIt->more() )
3094 const SMDS_MeshElement* e = elemIt->next();
3095 const int shapeID = e->getshapeId();
3096 if ( shapeID < 1 || shapeID >= dblVals.size() )
3097 fieldWriter.AddValue( noneDblValue );
3099 fieldWriter.AddValue( dblVals[ shapeID ]);
3102 while ( elemIt->more() )
3104 const SMDS_MeshElement* e = elemIt->next();
3105 const int shapeID = e->getshapeId();
3106 if ( shapeID < 1 || shapeID >= intVals.size() )
3107 fieldWriter.AddValue( noneIntValue );
3109 fieldWriter.AddValue( intVals[ shapeID ]);
3113 fieldWriter.Perform();
3114 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3115 if ( res && res->IsKO() )
3117 if ( res->myComment.empty() )
3118 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3120 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3126 if ( !geomAssocFields || !geomAssocFields[0] )
3129 // write geomAssocFields
3131 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3132 shapeDim[ TopAbs_COMPOUND ] = 3;
3133 shapeDim[ TopAbs_COMPSOLID ] = 3;
3134 shapeDim[ TopAbs_SOLID ] = 3;
3135 shapeDim[ TopAbs_SHELL ] = 2;
3136 shapeDim[ TopAbs_FACE ] = 2;
3137 shapeDim[ TopAbs_WIRE ] = 1;
3138 shapeDim[ TopAbs_EDGE ] = 1;
3139 shapeDim[ TopAbs_VERTEX ] = 0;
3140 shapeDim[ TopAbs_SHAPE ] = 3;
3142 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3144 std::vector< std::string > compNames;
3145 switch ( geomAssocFields[ iF ]) {
3147 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/true );
3148 compNames.push_back( "dim" );
3151 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/true );
3154 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/true );
3157 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/true );
3161 compNames.push_back( "id" );
3162 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3163 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3165 fieldWriter.SetDtIt( -1, -1 );
3167 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3171 if ( compNames.size() == 2 ) // _vertices_
3172 while ( elemIt->more() )
3174 const SMDS_MeshElement* e = elemIt->next();
3175 const int shapeID = e->getshapeId();
3178 fieldWriter.AddValue( -1 );
3179 fieldWriter.AddValue( -1 );
3183 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3184 fieldWriter.AddValue( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]);
3185 fieldWriter.AddValue( shapeID );
3189 while ( elemIt->more() )
3191 const SMDS_MeshElement* e = elemIt->next();
3192 const int shapeID = e->getshapeId();
3194 fieldWriter.AddValue( -1 );
3196 fieldWriter.AddValue( shapeID );
3200 fieldWriter.Perform();
3201 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3202 if ( res && res->IsKO() )
3204 if ( res->myComment.empty() )
3205 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3207 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3210 } // loop on geomAssocFields
3215 //================================================================================
3217 * \brief Export a part of mesh to a DAT file
3219 //================================================================================
3221 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3223 throw (SALOME::SALOME_Exception)
3225 Unexpect aCatch(SALOME_SalomeException);
3227 _preMeshInfo->FullLoadFromFile();
3229 PrepareForWriting(file);
3231 SMESH_MeshPartDS partDS( meshPart );
3232 _impl->ExportDAT(file,&partDS);
3234 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3235 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3237 //================================================================================
3239 * \brief Export a part of mesh to an UNV file
3241 //================================================================================
3243 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3245 throw (SALOME::SALOME_Exception)
3247 Unexpect aCatch(SALOME_SalomeException);
3249 _preMeshInfo->FullLoadFromFile();
3251 PrepareForWriting(file);
3253 SMESH_MeshPartDS partDS( meshPart );
3254 _impl->ExportUNV(file, &partDS);
3256 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3257 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3259 //================================================================================
3261 * \brief Export a part of mesh to an STL file
3263 //================================================================================
3265 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3267 ::CORBA::Boolean isascii)
3268 throw (SALOME::SALOME_Exception)
3270 Unexpect aCatch(SALOME_SalomeException);
3272 _preMeshInfo->FullLoadFromFile();
3274 PrepareForWriting(file);
3276 SMESH_MeshPartDS partDS( meshPart );
3277 _impl->ExportSTL(file, isascii, &partDS);
3279 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3280 << meshPart<< ", r'" << file << "', " << isascii << ")";
3283 //================================================================================
3285 * \brief Export a part of mesh to an STL file
3287 //================================================================================
3289 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3291 CORBA::Boolean overwrite)
3292 throw (SALOME::SALOME_Exception)
3295 Unexpect aCatch(SALOME_SalomeException);
3297 _preMeshInfo->FullLoadFromFile();
3299 PrepareForWriting(file,overwrite);
3301 SMESH_MeshPartDS partDS( meshPart );
3302 _impl->ExportCGNS(file, &partDS);
3304 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3305 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3307 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3311 //================================================================================
3313 * \brief Export a part of mesh to a GMF file
3315 //================================================================================
3317 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3319 bool withRequiredGroups)
3320 throw (SALOME::SALOME_Exception)
3322 Unexpect aCatch(SALOME_SalomeException);
3324 _preMeshInfo->FullLoadFromFile();
3326 PrepareForWriting(file,/*overwrite=*/true);
3328 SMESH_MeshPartDS partDS( meshPart );
3329 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3331 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3332 << meshPart<< ", r'"
3334 << withRequiredGroups << ")";
3337 //=============================================================================
3339 * Return computation progress [0.,1]
3341 //=============================================================================
3343 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3347 return _impl->GetComputeProgress();
3349 SMESH_CATCH( SMESH::doNothing );
3353 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3355 Unexpect aCatch(SALOME_SalomeException);
3357 return _preMeshInfo->NbNodes();
3359 return _impl->NbNodes();
3362 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3364 Unexpect aCatch(SALOME_SalomeException);
3366 return _preMeshInfo->NbElements();
3368 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3371 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3373 Unexpect aCatch(SALOME_SalomeException);
3375 return _preMeshInfo->Nb0DElements();
3377 return _impl->Nb0DElements();
3380 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3382 Unexpect aCatch(SALOME_SalomeException);
3384 return _preMeshInfo->NbBalls();
3386 return _impl->NbBalls();
3389 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3391 Unexpect aCatch(SALOME_SalomeException);
3393 return _preMeshInfo->NbEdges();
3395 return _impl->NbEdges();
3398 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3399 throw(SALOME::SALOME_Exception)
3401 Unexpect aCatch(SALOME_SalomeException);
3403 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3405 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3408 //=============================================================================
3410 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3412 Unexpect aCatch(SALOME_SalomeException);
3414 return _preMeshInfo->NbFaces();
3416 return _impl->NbFaces();
3419 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3421 Unexpect aCatch(SALOME_SalomeException);
3423 return _preMeshInfo->NbTriangles();
3425 return _impl->NbTriangles();
3428 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3430 Unexpect aCatch(SALOME_SalomeException);
3432 return _preMeshInfo->NbBiQuadTriangles();
3434 return _impl->NbBiQuadTriangles();
3437 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3439 Unexpect aCatch(SALOME_SalomeException);
3441 return _preMeshInfo->NbQuadrangles();
3443 return _impl->NbQuadrangles();
3446 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3448 Unexpect aCatch(SALOME_SalomeException);
3450 return _preMeshInfo->NbBiQuadQuadrangles();
3452 return _impl->NbBiQuadQuadrangles();
3455 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3457 Unexpect aCatch(SALOME_SalomeException);
3459 return _preMeshInfo->NbPolygons();
3461 return _impl->NbPolygons();
3464 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3465 throw(SALOME::SALOME_Exception)
3467 Unexpect aCatch(SALOME_SalomeException);
3469 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3471 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3474 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3475 throw(SALOME::SALOME_Exception)
3477 Unexpect aCatch(SALOME_SalomeException);
3479 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3481 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3484 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3485 throw(SALOME::SALOME_Exception)
3487 Unexpect aCatch(SALOME_SalomeException);
3489 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3491 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3494 //=============================================================================
3496 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3498 Unexpect aCatch(SALOME_SalomeException);
3500 return _preMeshInfo->NbVolumes();
3502 return _impl->NbVolumes();
3505 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3507 Unexpect aCatch(SALOME_SalomeException);
3509 return _preMeshInfo->NbTetras();
3511 return _impl->NbTetras();
3514 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3516 Unexpect aCatch(SALOME_SalomeException);
3518 return _preMeshInfo->NbHexas();
3520 return _impl->NbHexas();
3523 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3525 Unexpect aCatch(SALOME_SalomeException);
3527 return _preMeshInfo->NbTriQuadHexas();
3529 return _impl->NbTriQuadraticHexas();
3532 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3534 Unexpect aCatch(SALOME_SalomeException);
3536 return _preMeshInfo->NbPyramids();
3538 return _impl->NbPyramids();
3541 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3543 Unexpect aCatch(SALOME_SalomeException);
3545 return _preMeshInfo->NbPrisms();
3547 return _impl->NbPrisms();
3550 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3552 Unexpect aCatch(SALOME_SalomeException);
3554 return _preMeshInfo->NbHexPrisms();
3556 return _impl->NbHexagonalPrisms();
3559 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3561 Unexpect aCatch(SALOME_SalomeException);
3563 return _preMeshInfo->NbPolyhedrons();
3565 return _impl->NbPolyhedrons();
3568 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3569 throw(SALOME::SALOME_Exception)
3571 Unexpect aCatch(SALOME_SalomeException);
3573 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3575 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3578 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3579 throw(SALOME::SALOME_Exception)
3581 Unexpect aCatch(SALOME_SalomeException);
3583 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3585 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3588 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3589 throw(SALOME::SALOME_Exception)
3591 Unexpect aCatch(SALOME_SalomeException);
3593 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3595 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3598 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3599 throw(SALOME::SALOME_Exception)
3601 Unexpect aCatch(SALOME_SalomeException);
3603 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3605 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3608 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3609 throw(SALOME::SALOME_Exception)
3611 Unexpect aCatch(SALOME_SalomeException);
3613 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3615 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3618 //=============================================================================
3620 * Returns nb of published sub-meshes
3622 //=============================================================================
3624 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3626 Unexpect aCatch(SALOME_SalomeException);
3627 return _mapSubMesh_i.size();
3630 //=============================================================================
3632 * Dumps mesh into a string
3634 //=============================================================================
3636 char* SMESH_Mesh_i::Dump()
3640 return CORBA::string_dup( os.str().c_str() );
3643 //=============================================================================
3645 * Method of SMESH_IDSource interface
3647 //=============================================================================
3649 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3651 return GetElementsId();
3654 //=============================================================================
3656 * Returns ids of all elements
3658 //=============================================================================
3660 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3661 throw (SALOME::SALOME_Exception)
3663 Unexpect aCatch(SALOME_SalomeException);
3665 _preMeshInfo->FullLoadFromFile();
3667 SMESH::long_array_var aResult = new SMESH::long_array();
3668 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3670 if ( aSMESHDS_Mesh == NULL )
3671 return aResult._retn();
3673 long nbElements = NbElements();
3674 aResult->length( nbElements );
3675 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3676 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3677 aResult[i] = anIt->next()->GetID();
3679 return aResult._retn();
3683 //=============================================================================
3685 * Returns ids of all elements of given type
3687 //=============================================================================
3689 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3690 throw (SALOME::SALOME_Exception)
3692 Unexpect aCatch(SALOME_SalomeException);
3694 _preMeshInfo->FullLoadFromFile();
3696 SMESH::long_array_var aResult = new SMESH::long_array();
3697 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3699 if ( aSMESHDS_Mesh == NULL )
3700 return aResult._retn();
3702 long nbElements = NbElements();
3704 // No sense in returning ids of elements along with ids of nodes:
3705 // when theElemType == SMESH::ALL, return node ids only if
3706 // there are no elements
3707 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3708 return GetNodesId();
3710 aResult->length( nbElements );
3714 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3715 while ( i < nbElements && anIt->more() )
3716 aResult[i++] = anIt->next()->GetID();
3718 aResult->length( i );
3720 return aResult._retn();
3723 //=============================================================================
3725 * Returns ids of all nodes
3727 //=============================================================================
3729 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3730 throw (SALOME::SALOME_Exception)
3732 Unexpect aCatch(SALOME_SalomeException);
3734 _preMeshInfo->FullLoadFromFile();
3736 SMESH::long_array_var aResult = new SMESH::long_array();
3737 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3739 if ( aSMESHDS_Mesh == NULL )
3740 return aResult._retn();
3742 long nbNodes = NbNodes();
3743 aResult->length( nbNodes );
3744 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3745 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3746 aResult[i] = anIt->next()->GetID();
3748 return aResult._retn();
3751 //=============================================================================
3755 //=============================================================================
3757 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3758 throw (SALOME::SALOME_Exception)
3760 SMESH::ElementType type;
3764 _preMeshInfo->FullLoadFromFile();
3766 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3768 SMESH_CATCH( SMESH::throwCorbaException );
3773 //=============================================================================
3777 //=============================================================================
3779 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3780 throw (SALOME::SALOME_Exception)
3783 _preMeshInfo->FullLoadFromFile();
3785 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3787 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3789 return ( SMESH::EntityType ) e->GetEntityType();
3792 //=============================================================================
3796 //=============================================================================
3798 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3799 throw (SALOME::SALOME_Exception)
3802 _preMeshInfo->FullLoadFromFile();
3804 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3806 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3808 return ( SMESH::GeometryType ) e->GetGeomType();
3811 //=============================================================================
3813 * Returns ID of elements for given submesh
3815 //=============================================================================
3816 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3817 throw (SALOME::SALOME_Exception)
3819 SMESH::long_array_var aResult = new SMESH::long_array();
3823 _preMeshInfo->FullLoadFromFile();
3825 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3826 if(!SM) return aResult._retn();
3828 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3829 if(!SDSM) return aResult._retn();
3831 aResult->length(SDSM->NbElements());
3833 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3835 while ( eIt->more() ) {
3836 aResult[i++] = eIt->next()->GetID();
3839 SMESH_CATCH( SMESH::throwCorbaException );
3841 return aResult._retn();
3844 //=============================================================================
3846 * Returns ID of nodes for given submesh
3847 * If param all==true - returns all nodes, else -
3848 * returns only nodes on shapes.
3850 //=============================================================================
3852 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3854 throw (SALOME::SALOME_Exception)
3856 SMESH::long_array_var aResult = new SMESH::long_array();
3860 _preMeshInfo->FullLoadFromFile();
3862 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3863 if(!SM) return aResult._retn();
3865 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3866 if(!SDSM) return aResult._retn();
3869 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3870 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3871 while ( nIt->more() ) {
3872 const SMDS_MeshNode* elem = nIt->next();
3873 theElems.insert( elem->GetID() );
3876 else { // all nodes of submesh elements
3877 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3878 while ( eIt->more() ) {
3879 const SMDS_MeshElement* anElem = eIt->next();
3880 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3881 while ( nIt->more() ) {
3882 const SMDS_MeshElement* elem = nIt->next();
3883 theElems.insert( elem->GetID() );
3888 aResult->length(theElems.size());
3889 set<int>::iterator itElem;
3891 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3892 aResult[i++] = *itElem;
3894 SMESH_CATCH( SMESH::throwCorbaException );
3896 return aResult._retn();
3899 //=============================================================================
3901 * Returns type of elements for given submesh
3903 //=============================================================================
3905 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3906 throw (SALOME::SALOME_Exception)
3908 SMESH::ElementType type;
3912 _preMeshInfo->FullLoadFromFile();
3914 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3915 if(!SM) return SMESH::ALL;
3917 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3918 if(!SDSM) return SMESH::ALL;
3920 if(SDSM->NbElements()==0)
3921 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3923 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3924 const SMDS_MeshElement* anElem = eIt->next();
3926 type = ( SMESH::ElementType ) anElem->GetType();
3928 SMESH_CATCH( SMESH::throwCorbaException );
3934 //=============================================================================
3936 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3938 //=============================================================================
3940 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3943 _preMeshInfo->FullLoadFromFile();
3945 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3947 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3952 //=============================================================================
3954 * Get XYZ coordinates of node as list of double
3955 * If there is not node for given ID - returns empty list
3957 //=============================================================================
3959 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3962 _preMeshInfo->FullLoadFromFile();
3964 SMESH::double_array_var aResult = new SMESH::double_array();
3965 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3966 if ( aSMESHDS_Mesh == NULL )
3967 return aResult._retn();
3970 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3972 return aResult._retn();
3976 aResult[0] = aNode->X();
3977 aResult[1] = aNode->Y();
3978 aResult[2] = aNode->Z();
3979 return aResult._retn();
3983 //=============================================================================
3985 * For given node returns list of IDs of inverse elements
3986 * If there is not node for given ID - returns empty list
3988 //=============================================================================
3990 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3993 _preMeshInfo->FullLoadFromFile();
3995 SMESH::long_array_var aResult = new SMESH::long_array();
3996 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3997 if ( aSMESHDS_Mesh == NULL )
3998 return aResult._retn();
4001 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4003 return aResult._retn();
4005 // find inverse elements
4006 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4007 TColStd_SequenceOfInteger IDs;
4008 while(eIt->more()) {
4009 const SMDS_MeshElement* elem = eIt->next();
4010 IDs.Append(elem->GetID());
4012 if(IDs.Length()>0) {
4013 aResult->length(IDs.Length());
4015 for(; i<=IDs.Length(); i++) {
4016 aResult[i-1] = IDs.Value(i);
4019 return aResult._retn();
4022 //=============================================================================
4024 * \brief Return position of a node on shape
4026 //=============================================================================
4028 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4031 _preMeshInfo->FullLoadFromFile();
4033 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4034 aNodePosition->shapeID = 0;
4035 aNodePosition->shapeType = GEOM::SHAPE;
4037 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4038 if ( !mesh ) return aNodePosition;
4040 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4042 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4044 aNodePosition->shapeID = aNode->getshapeId();
4045 switch ( pos->GetTypeOfPosition() ) {
4047 aNodePosition->shapeType = GEOM::EDGE;
4048 aNodePosition->params.length(1);
4049 aNodePosition->params[0] =
4050 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4053 aNodePosition->shapeType = GEOM::FACE;
4054 aNodePosition->params.length(2);
4055 aNodePosition->params[0] =
4056 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4057 aNodePosition->params[1] =
4058 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4060 case SMDS_TOP_VERTEX:
4061 aNodePosition->shapeType = GEOM::VERTEX;
4063 case SMDS_TOP_3DSPACE:
4064 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4065 aNodePosition->shapeType = GEOM::SOLID;
4066 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4067 aNodePosition->shapeType = GEOM::SHELL;
4073 return aNodePosition;
4076 //=============================================================================
4078 * \brief Return position of an element on shape
4080 //=============================================================================
4082 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4085 _preMeshInfo->FullLoadFromFile();
4087 SMESH::ElementPosition anElementPosition;
4088 anElementPosition.shapeID = 0;
4089 anElementPosition.shapeType = GEOM::SHAPE;
4091 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4092 if ( !mesh ) return anElementPosition;
4094 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4096 anElementPosition.shapeID = anElem->getshapeId();
4097 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4098 if ( !aSp.IsNull() ) {
4099 switch ( aSp.ShapeType() ) {
4101 anElementPosition.shapeType = GEOM::EDGE;
4104 anElementPosition.shapeType = GEOM::FACE;
4107 anElementPosition.shapeType = GEOM::VERTEX;
4110 anElementPosition.shapeType = GEOM::SOLID;
4113 anElementPosition.shapeType = GEOM::SHELL;
4119 return anElementPosition;
4122 //=============================================================================
4124 * If given element is node returns IDs of shape from position
4125 * If there is not node for given ID - returns -1
4127 //=============================================================================
4129 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4132 _preMeshInfo->FullLoadFromFile();
4134 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4135 if ( aSMESHDS_Mesh == NULL )
4139 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4141 return aNode->getshapeId();
4148 //=============================================================================
4150 * For given element returns ID of result shape after
4151 * ::FindShape() from SMESH_MeshEditor
4152 * If there is not element for given ID - returns -1
4154 //=============================================================================
4156 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4159 _preMeshInfo->FullLoadFromFile();
4161 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4162 if ( aSMESHDS_Mesh == NULL )
4165 // try to find element
4166 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4170 ::SMESH_MeshEditor aMeshEditor(_impl);
4171 int index = aMeshEditor.FindShape( elem );
4179 //=============================================================================
4181 * Returns number of nodes for given element
4182 * If there is not element for given ID - returns -1
4184 //=============================================================================
4186 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4189 _preMeshInfo->FullLoadFromFile();
4191 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4192 if ( aSMESHDS_Mesh == NULL ) return -1;
4193 // try to find element
4194 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4195 if(!elem) return -1;
4196 return elem->NbNodes();
4200 //=============================================================================
4202 * Returns ID of node by given index for given element
4203 * If there is not element for given ID - returns -1
4204 * If there is not node for given index - returns -2
4206 //=============================================================================
4208 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4211 _preMeshInfo->FullLoadFromFile();
4213 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4214 if ( aSMESHDS_Mesh == NULL ) return -1;
4215 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4216 if(!elem) return -1;
4217 if( index>=elem->NbNodes() || index<0 ) return -1;
4218 return elem->GetNode(index)->GetID();
4221 //=============================================================================
4223 * Returns IDs of nodes of given element
4225 //=============================================================================
4227 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4230 _preMeshInfo->FullLoadFromFile();
4232 SMESH::long_array_var aResult = new SMESH::long_array();
4233 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4235 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4237 aResult->length( elem->NbNodes() );
4238 for ( int i = 0; i < elem->NbNodes(); ++i )
4239 aResult[ i ] = elem->GetNode( i )->GetID();
4242 return aResult._retn();
4245 //=============================================================================
4247 * Returns true if given node is medium node
4248 * in given quadratic element
4250 //=============================================================================
4252 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4255 _preMeshInfo->FullLoadFromFile();
4257 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4258 if ( aSMESHDS_Mesh == NULL ) return false;
4260 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4261 if(!aNode) return false;
4262 // try to find element
4263 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4264 if(!elem) return false;
4266 return elem->IsMediumNode(aNode);
4270 //=============================================================================
4272 * Returns true if given node is medium node
4273 * in one of quadratic elements
4275 //=============================================================================
4277 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4278 SMESH::ElementType theElemType)
4281 _preMeshInfo->FullLoadFromFile();
4283 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4284 if ( aSMESHDS_Mesh == NULL ) return false;
4287 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4288 if(!aNode) return false;
4290 SMESH_MesherHelper aHelper( *(_impl) );
4292 SMDSAbs_ElementType aType;
4293 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4294 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4295 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4296 else aType = SMDSAbs_All;
4298 return aHelper.IsMedium(aNode,aType);
4302 //=============================================================================
4304 * Returns number of edges for given element
4306 //=============================================================================
4308 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4311 _preMeshInfo->FullLoadFromFile();
4313 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4314 if ( aSMESHDS_Mesh == NULL ) return -1;
4315 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4316 if(!elem) return -1;
4317 return elem->NbEdges();
4321 //=============================================================================
4323 * Returns number of faces for given element
4325 //=============================================================================
4327 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4330 _preMeshInfo->FullLoadFromFile();
4332 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4333 if ( aSMESHDS_Mesh == NULL ) return -1;
4334 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4335 if(!elem) return -1;
4336 return elem->NbFaces();
4339 //=======================================================================
4340 //function : GetElemFaceNodes
4341 //purpose : Returns nodes of given face (counted from zero) for given element.
4342 //=======================================================================
4344 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4345 CORBA::Short faceIndex)
4348 _preMeshInfo->FullLoadFromFile();
4350 SMESH::long_array_var aResult = new SMESH::long_array();
4351 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4353 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4355 SMDS_VolumeTool vtool( elem );
4356 if ( faceIndex < vtool.NbFaces() )
4358 aResult->length( vtool.NbFaceNodes( faceIndex ));
4359 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4360 for ( int i = 0; i < aResult->length(); ++i )
4361 aResult[ i ] = nn[ i ]->GetID();
4365 return aResult._retn();
4368 //=======================================================================
4369 //function : GetElemFaceNodes
4370 //purpose : Returns three components of normal of given mesh face.
4371 //=======================================================================
4373 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4374 CORBA::Boolean normalized)
4377 _preMeshInfo->FullLoadFromFile();
4379 SMESH::double_array_var aResult = new SMESH::double_array();
4381 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4384 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4386 aResult->length( 3 );
4387 aResult[ 0 ] = normal.X();
4388 aResult[ 1 ] = normal.Y();
4389 aResult[ 2 ] = normal.Z();
4392 return aResult._retn();
4395 //=======================================================================
4396 //function : FindElementByNodes
4397 //purpose : Returns an element based on all given nodes.
4398 //=======================================================================
4400 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4403 _preMeshInfo->FullLoadFromFile();
4405 CORBA::Long elemID(0);
4406 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4408 vector< const SMDS_MeshNode * > nn( nodes.length() );
4409 for ( int i = 0; i < nodes.length(); ++i )
4410 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4413 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4414 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4415 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4416 _impl->NbVolumes( ORDER_QUADRATIC )))
4417 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4419 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4424 //=============================================================================
4426 * Returns true if given element is polygon
4428 //=============================================================================
4430 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4433 _preMeshInfo->FullLoadFromFile();
4435 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4436 if ( aSMESHDS_Mesh == NULL ) return false;
4437 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4438 if(!elem) return false;
4439 return elem->IsPoly();
4443 //=============================================================================
4445 * Returns true if given element is quadratic
4447 //=============================================================================
4449 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4452 _preMeshInfo->FullLoadFromFile();
4454 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4455 if ( aSMESHDS_Mesh == NULL ) return false;
4456 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4457 if(!elem) return false;
4458 return elem->IsQuadratic();
4461 //=============================================================================
4463 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4465 //=============================================================================
4467 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4470 _preMeshInfo->FullLoadFromFile();
4472 if ( const SMDS_BallElement* ball =
4473 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4474 return ball->GetDiameter();
4479 //=============================================================================
4481 * Returns bary center for given element
4483 //=============================================================================
4485 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4488 _preMeshInfo->FullLoadFromFile();
4490 SMESH::double_array_var aResult = new SMESH::double_array();
4491 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4492 if ( aSMESHDS_Mesh == NULL )
4493 return aResult._retn();
4495 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4497 return aResult._retn();
4499 if(elem->GetType()==SMDSAbs_Volume) {
4500 SMDS_VolumeTool aTool;
4501 if(aTool.Set(elem)) {
4503 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4508 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4510 double x=0., y=0., z=0.;
4511 for(; anIt->more(); ) {
4513 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4527 return aResult._retn();
4530 //================================================================================
4532 * \brief Create a group of elements preventing computation of a sub-shape
4534 //================================================================================
4536 SMESH::ListOfGroups*
4537 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4538 const char* theGroupName )
4539 throw ( SALOME::SALOME_Exception )
4541 Unexpect aCatch(SALOME_SalomeException);
4543 if ( !theGroupName || strlen( theGroupName) == 0 )
4544 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4546 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4548 // submesh by subshape id
4549 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4550 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4553 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4554 if ( error && !error->myBadElements.empty())
4556 // sort bad elements by type
4557 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4558 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4559 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4560 for ( ; elemIt != elemEnd; ++elemIt )
4562 const SMDS_MeshElement* elem = *elemIt;
4563 if ( !elem ) continue;
4565 if ( elem->GetID() < 1 )
4567 // elem is a temporary element, make a real element
4568 vector< const SMDS_MeshNode* > nodes;
4569 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4570 while ( nIt->more() && elem )
4572 nodes.push_back( nIt->next() );
4573 if ( nodes.back()->GetID() < 1 )
4574 elem = 0; // a temporary element on temporary nodes
4578 ::SMESH_MeshEditor editor( _impl );
4579 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4583 elemsByType[ elem->GetType() ].push_back( elem );
4586 // how many groups to create?
4588 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4589 nbTypes += int( !elemsByType[ i ].empty() );
4590 groups->length( nbTypes );
4593 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4595 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4596 if ( elems.empty() ) continue;
4598 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4599 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4601 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4602 SMESH::SMESH_Mesh_var mesh = _this();
4603 SALOMEDS::SObject_wrap aSO =
4604 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4605 GEOM::GEOM_Object::_nil(), theGroupName);
4606 aSO->_is_nil(); // avoid "unused variable" warning
4608 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4609 if ( !grp_i ) continue;
4611 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4612 for ( size_t iE = 0; iE < elems.size(); ++iE )
4613 grpDS->SMDSGroup().Add( elems[ iE ]);
4618 return groups._retn();
4621 //=============================================================================
4623 * Create and publish group servants if any groups were imported or created anyhow
4625 //=============================================================================
4627 void SMESH_Mesh_i::CreateGroupServants()
4629 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4630 SMESH::SMESH_Mesh_var aMesh = _this();
4633 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4634 while ( groupIt->more() )
4636 ::SMESH_Group* group = groupIt->next();
4637 int anId = group->GetGroupDS()->GetID();
4639 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4640 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4642 addedIDs.insert( anId );
4644 SMESH_GroupBase_i* aGroupImpl;
4646 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4647 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4649 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4650 shape = groupOnGeom->GetShape();
4653 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4656 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4657 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4658 aGroupImpl->Register();
4660 // register CORBA object for persistence
4661 int nextId = _gen_i->RegisterObject( groupVar );
4662 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4663 else { nextId = 0; } // avoid "unused variable" warning in release mode
4665 // publishing the groups in the study
4666 if ( !aStudy->_is_nil() ) {
4667 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4668 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4671 if ( !addedIDs.empty() )
4674 set<int>::iterator id = addedIDs.begin();
4675 for ( ; id != addedIDs.end(); ++id )
4677 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4678 int i = std::distance( _mapGroups.begin(), it );
4679 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4684 //=============================================================================
4686 * \brief Return groups cantained in _mapGroups by their IDs
4688 //=============================================================================
4690 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4692 int nbGroups = groupIDs.size();
4693 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4694 aList->length( nbGroups );
4696 list<int>::const_iterator ids = groupIDs.begin();
4697 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4699 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4700 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4701 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4703 aList->length( nbGroups );
4704 return aList._retn();
4707 //=============================================================================
4709 * \brief Return information about imported file
4711 //=============================================================================
4713 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4715 SMESH::MedFileInfo_var res( _medFileInfo );
4716 if ( !res.operator->() ) {
4717 res = new SMESH::MedFileInfo;
4719 res->fileSize = res->major = res->minor = res->release = -1;
4724 //=============================================================================
4726 * \brief Pass names of mesh groups from study to mesh DS
4728 //=============================================================================
4730 void SMESH_Mesh_i::checkGroupNames()
4732 int nbGrp = NbGroups();
4736 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4737 if ( aStudy->_is_nil() )
4738 return; // nothing to do
4740 SMESH::ListOfGroups* grpList = 0;
4741 // avoid dump of "GetGroups"
4743 // store python dump into a local variable inside local scope
4744 SMESH::TPythonDump pDump; // do not delete this line of code
4745 grpList = GetGroups();
4748 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4749 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4752 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4753 if ( aGrpSO->_is_nil() )
4755 // correct name of the mesh group if necessary
4756 const char* guiName = aGrpSO->GetName();
4757 if ( strcmp(guiName, aGrp->GetName()) )
4758 aGrp->SetName( guiName );
4762 //=============================================================================
4764 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4766 //=============================================================================
4767 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4769 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4773 //=============================================================================
4775 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4777 //=============================================================================
4779 char* SMESH_Mesh_i::GetParameters()
4781 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4784 //=============================================================================
4786 * \brief Returns list of notebook variables used for last Mesh operation
4788 //=============================================================================
4789 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4791 SMESH::string_array_var aResult = new SMESH::string_array();
4792 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4794 CORBA::String_var aParameters = GetParameters();
4795 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4796 if ( !aStudy->_is_nil()) {
4797 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4798 if(aSections->length() > 0) {
4799 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4800 aResult->length(aVars.length());
4801 for(int i = 0;i < aVars.length();i++)
4802 aResult[i] = CORBA::string_dup( aVars[i]);
4806 return aResult._retn();
4809 //=======================================================================
4810 //function : GetTypes
4811 //purpose : Returns types of elements it contains
4812 //=======================================================================
4814 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4817 return _preMeshInfo->GetTypes();
4819 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4823 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4824 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4825 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4826 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4827 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4828 types->length( nbTypes );
4830 return types._retn();
4833 //=======================================================================
4834 //function : GetMesh
4835 //purpose : Returns self
4836 //=======================================================================
4838 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4840 return SMESH::SMESH_Mesh::_duplicate( _this() );
4843 //=======================================================================
4844 //function : IsMeshInfoCorrect
4845 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4846 // * happen if mesh data is not yet fully loaded from the file of study.
4847 //=======================================================================
4849 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4851 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4854 //=============================================================================
4856 * \brief Returns number of mesh elements per each \a EntityType
4858 //=============================================================================
4860 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4863 return _preMeshInfo->GetMeshInfo();
4865 SMESH::long_array_var aRes = new SMESH::long_array();
4866 aRes->length(SMESH::Entity_Last);
4867 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4869 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4871 return aRes._retn();
4872 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4873 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4874 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4875 return aRes._retn();
4878 //=============================================================================
4880 * \brief Returns number of mesh elements per each \a ElementType
4882 //=============================================================================
4884 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
4886 SMESH::long_array_var aRes = new SMESH::long_array();
4887 aRes->length(SMESH::NB_ELEMENT_TYPES);
4888 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4891 const SMDS_MeshInfo* meshInfo = 0;
4893 meshInfo = _preMeshInfo;
4894 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
4895 meshInfo = & meshDS->GetMeshInfo();
4898 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4899 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
4901 return aRes._retn();
4904 //=============================================================================
4906 * Collect statistic of mesh elements given by iterator
4908 //=============================================================================
4910 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4911 SMESH::long_array& theInfo)
4913 if (!theItr) return;
4914 while (theItr->more())
4915 theInfo[ theItr->next()->GetEntityType() ]++;
4918 //=============================================================================
4919 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
4920 * SMESH::ElementType type) */
4922 using namespace SMESH::Controls;
4923 //-----------------------------------------------------------------------------
4924 struct PredicateIterator : public SMDS_ElemIterator
4926 SMDS_ElemIteratorPtr _elemIter;
4927 PredicatePtr _predicate;
4928 const SMDS_MeshElement* _elem;
4930 PredicateIterator( SMDS_ElemIteratorPtr iterator,
4931 PredicatePtr predicate):
4932 _elemIter(iterator), _predicate(predicate)
4940 virtual const SMDS_MeshElement* next()
4942 const SMDS_MeshElement* res = _elem;
4944 while ( _elemIter->more() && !_elem )
4946 _elem = _elemIter->next();
4947 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
4954 //-----------------------------------------------------------------------------
4955 struct IDSourceIterator : public SMDS_ElemIterator
4957 const CORBA::Long* _idPtr;
4958 const CORBA::Long* _idEndPtr;
4959 SMESH::long_array_var _idArray;
4960 const SMDS_Mesh* _mesh;
4961 const SMDSAbs_ElementType _type;
4962 const SMDS_MeshElement* _elem;
4964 IDSourceIterator( const SMDS_Mesh* mesh,
4965 const CORBA::Long* ids,
4967 SMDSAbs_ElementType type):
4968 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
4970 if ( _idPtr && nbIds && _mesh )
4973 IDSourceIterator( const SMDS_Mesh* mesh,
4974 SMESH::long_array* idArray,
4975 SMDSAbs_ElementType type):
4976 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
4978 if ( idArray && _mesh )
4980 _idPtr = &_idArray[0];
4981 _idEndPtr = _idPtr + _idArray->length();
4989 virtual const SMDS_MeshElement* next()
4991 const SMDS_MeshElement* res = _elem;
4993 while ( _idPtr < _idEndPtr && !_elem )
4995 if ( _type == SMDSAbs_Node )
4997 _elem = _mesh->FindNode( *_idPtr++ );
4999 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5000 _elem->GetType() != _type )
5008 //-----------------------------------------------------------------------------
5010 struct NodeOfElemIterator : public SMDS_ElemIterator
5012 TColStd_MapOfInteger _checkedNodeIDs;
5013 SMDS_ElemIteratorPtr _elemIter;
5014 SMDS_ElemIteratorPtr _nodeIter;
5015 const SMDS_MeshElement* _node;
5017 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5019 if ( _elemIter && _elemIter->more() )
5021 _nodeIter = _elemIter->next()->nodesIterator();
5029 virtual const SMDS_MeshElement* next()
5031 const SMDS_MeshElement* res = _node;
5033 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5035 if ( _nodeIter->more() )
5037 _node = _nodeIter->next();
5038 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5043 _nodeIter = _elemIter->next()->nodesIterator();
5051 //=============================================================================
5053 * Return iterator on elements of given type in given object
5055 //=============================================================================
5057 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5058 SMESH::ElementType theType)
5060 SMDS_ElemIteratorPtr elemIt;
5061 bool typeOK = false;
5062 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5064 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5065 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5066 if ( !mesh_i ) return elemIt;
5067 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5069 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5071 elemIt = meshDS->elementsIterator( elemType );
5074 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5076 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5079 elemIt = sm->GetElements();
5080 if ( elemType != SMDSAbs_Node )
5082 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5083 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5087 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5089 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5090 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5092 elemIt = groupDS->GetElements();
5093 typeOK = ( groupDS->GetType() == elemType );
5096 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5098 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5100 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5101 if ( pred_i && pred_i->GetPredicate() )
5103 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5104 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5105 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5106 typeOK = ( filterType == elemType );
5112 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5113 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5114 if ( isNodes && elemType != SMDSAbs_Node )
5116 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5119 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5120 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5124 SMESH::long_array_var ids = theObject->GetIDs();
5125 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5127 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5130 if ( elemIt && elemIt->more() && !typeOK )
5132 if ( elemType == SMDSAbs_Node )
5134 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5138 elemIt = SMDS_ElemIteratorPtr();
5144 //=============================================================================
5145 namespace // Finding concurrent hypotheses
5146 //=============================================================================
5150 * \brief mapping of mesh dimension into shape type
5152 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5154 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5156 case 0: aType = TopAbs_VERTEX; break;
5157 case 1: aType = TopAbs_EDGE; break;
5158 case 2: aType = TopAbs_FACE; break;
5160 default:aType = TopAbs_SOLID; break;
5165 //-----------------------------------------------------------------------------
5167 * \brief Internal structure used to find concurent submeshes
5169 * It represents a pair < submesh, concurent dimension >, where
5170 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5171 * with another submesh. In other words, it is dimension of a hypothesis assigned
5178 int _dim; //!< a dimension the algo can build (concurrent dimension)
5179 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5180 TopTools_MapOfShape _shapeMap;
5181 SMESH_subMesh* _subMesh;
5182 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5184 //-----------------------------------------------------------------------------
5185 // Return the algorithm
5186 const SMESH_Algo* GetAlgo() const
5187 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5189 //-----------------------------------------------------------------------------
5191 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5193 const TopoDS_Shape& theShape)
5195 _subMesh = (SMESH_subMesh*)theSubMesh;
5196 SetShape( theDim, theShape );
5199 //-----------------------------------------------------------------------------
5201 void SetShape(const int theDim,
5202 const TopoDS_Shape& theShape)
5205 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5206 if (_dim >= _ownDim)
5207 _shapeMap.Add( theShape );
5209 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5210 for( ; anExp.More(); anExp.Next() )
5211 _shapeMap.Add( anExp.Current() );
5215 //-----------------------------------------------------------------------------
5216 //! Check sharing of sub-shapes
5217 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5218 const TopTools_MapOfShape& theToFind,
5219 const TopAbs_ShapeEnum theType)
5221 bool isShared = false;
5222 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5223 for (; !isShared && anItr.More(); anItr.Next() )
5225 const TopoDS_Shape aSubSh = anItr.Key();
5226 // check for case when concurrent dimensions are same
5227 isShared = theToFind.Contains( aSubSh );
5228 // check for sub-shape with concurrent dimension
5229 TopExp_Explorer anExp( aSubSh, theType );
5230 for ( ; !isShared && anExp.More(); anExp.Next() )
5231 isShared = theToFind.Contains( anExp.Current() );
5236 //-----------------------------------------------------------------------------
5237 //! check algorithms
5238 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5239 const SMESHDS_Hypothesis* theA2)
5241 if ( !theA1 || !theA2 ||
5242 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5243 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5244 return false; // one of the hypothesis is not algorithm
5245 // check algorithm names (should be equal)
5246 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5250 //-----------------------------------------------------------------------------
5251 //! Check if sub-shape hypotheses are concurrent
5252 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5254 if ( _subMesh == theOther->_subMesh )
5255 return false; // same sub-shape - should not be
5257 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5258 // any of the two submeshes is not on COMPOUND shape )
5259 // -> no concurrency
5260 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5261 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5262 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5263 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5264 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5267 // bool checkSubShape = ( _dim >= theOther->_dim )
5268 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5269 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5270 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5271 if ( !checkSubShape )
5274 // check algorithms to be same
5275 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5276 return true; // different algorithms -> concurrency !
5278 // check hypothesises for concurrence (skip first as algorithm)
5280 // pointers should be same, because it is referened from mesh hypothesis partition
5281 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5282 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5283 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5284 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5286 // the submeshes are concurrent if their algorithms has different parameters
5287 return nbSame != theOther->_hypotheses.size() - 1;
5290 // Return true if algorithm of this SMESH_DimHyp is used if no
5291 // sub-mesh order is imposed by the user
5292 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5294 // NeedDiscreteBoundary() algo has a higher priority
5295 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5296 theOther->GetAlgo()->NeedDiscreteBoundary() )
5297 return !this->GetAlgo()->NeedDiscreteBoundary();
5299 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5302 }; // end of SMESH_DimHyp
5303 //-----------------------------------------------------------------------------
5305 typedef list<const SMESH_DimHyp*> TDimHypList;
5307 //-----------------------------------------------------------------------------
5309 void addDimHypInstance(const int theDim,
5310 const TopoDS_Shape& theShape,
5311 const SMESH_Algo* theAlgo,
5312 const SMESH_subMesh* theSubMesh,
5313 const list <const SMESHDS_Hypothesis*>& theHypList,
5314 TDimHypList* theDimHypListArr )
5316 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5317 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5318 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5319 dimHyp->_hypotheses.push_front(theAlgo);
5320 listOfdimHyp.push_back( dimHyp );
5323 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5324 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5325 theHypList.begin(), theHypList.end() );
5328 //-----------------------------------------------------------------------------
5329 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5330 TDimHypList& theListOfConcurr)
5332 if ( theListOfConcurr.empty() )
5334 theListOfConcurr.push_back( theDimHyp );
5338 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5339 while ( hypIt != theListOfConcurr.end() &&
5340 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5342 theListOfConcurr.insert( hypIt, theDimHyp );
5346 //-----------------------------------------------------------------------------
5347 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5348 const TDimHypList& theListOfDimHyp,
5349 TDimHypList& theListOfConcurrHyp,
5350 set<int>& theSetOfConcurrId )
5352 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5353 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5355 const SMESH_DimHyp* curDimHyp = *rIt;
5356 if ( curDimHyp == theDimHyp )
5357 break; // meet own dimHyp pointer in same dimension
5359 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5360 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5362 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5367 //-----------------------------------------------------------------------------
5368 void unionLists(TListOfInt& theListOfId,
5369 TListOfListOfInt& theListOfListOfId,
5372 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5373 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5375 continue; //skip already treated lists
5376 // check if other list has any same submesh object
5377 TListOfInt& otherListOfId = *it;
5378 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5379 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5382 // union two lists (from source into target)
5383 TListOfInt::iterator it2 = otherListOfId.begin();
5384 for ( ; it2 != otherListOfId.end(); it2++ ) {
5385 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5386 theListOfId.push_back(*it2);
5388 // clear source list
5389 otherListOfId.clear();
5392 //-----------------------------------------------------------------------------
5394 //! free memory allocated for dimension-hypothesis objects
5395 void removeDimHyps( TDimHypList* theArrOfList )
5397 for (int i = 0; i < 4; i++ ) {
5398 TDimHypList& listOfdimHyp = theArrOfList[i];
5399 TDimHypList::const_iterator it = listOfdimHyp.begin();
5400 for ( ; it != listOfdimHyp.end(); it++ )
5405 //-----------------------------------------------------------------------------
5407 * \brief find common submeshes with given submesh
5408 * \param theSubMeshList list of already collected submesh to check
5409 * \param theSubMesh given submesh to intersect with other
5410 * \param theCommonSubMeshes collected common submeshes
5412 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5413 const SMESH_subMesh* theSubMesh,
5414 set<const SMESH_subMesh*>& theCommon )
5418 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5419 for ( ; it != theSubMeshList.end(); it++ )
5420 theSubMesh->FindIntersection( *it, theCommon );
5421 theSubMeshList.push_back( theSubMesh );
5422 //theCommon.insert( theSubMesh );
5425 //-----------------------------------------------------------------------------
5426 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5428 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5429 for ( ; listsIt != smLists.end(); ++listsIt )
5431 const TListOfInt& smIDs = *listsIt;
5432 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5440 //=============================================================================
5442 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5444 //=============================================================================
5446 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5448 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5449 if ( isSubMeshInList( submeshID, anOrder ))
5452 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5453 return isSubMeshInList( submeshID, allConurrent );
5456 //=============================================================================
5458 * \brief Return submesh objects list in meshing order
5460 //=============================================================================
5462 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5464 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5466 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5468 return aResult._retn();
5470 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5471 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5472 anOrder.splice( anOrder.end(), allConurrent );
5475 TListOfListOfInt::iterator listIt = anOrder.begin();
5476 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5477 unionLists( *listIt, anOrder, listIndx + 1 );
5479 // convert submesh ids into interface instances
5480 // and dump command into python
5481 convertMeshOrder( anOrder, aResult, false );
5483 return aResult._retn();
5486 //=============================================================================
5488 * \brief Finds concurrent sub-meshes
5490 //=============================================================================
5492 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5494 TListOfListOfInt anOrder;
5495 ::SMESH_Mesh& mesh = GetImpl();
5497 // collect submeshes and detect concurrent algorithms and hypothesises
5498 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5500 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5501 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5502 ::SMESH_subMesh* sm = (*i_sm).second;
5504 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5506 // list of assigned hypothesises
5507 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5508 // Find out dimensions where the submesh can be concurrent.
5509 // We define the dimensions by algo of each of hypotheses in hypList
5510 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5511 for( ; hypIt != hypList.end(); hypIt++ ) {
5512 SMESH_Algo* anAlgo = 0;
5513 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5514 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5515 // hyp it-self is algo
5516 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5518 // try to find algorithm with help of sub-shapes
5519 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5520 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5521 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5524 continue; // no algorithm assigned to a current submesh
5526 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5527 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5529 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5530 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5531 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5533 } // end iterations on submesh
5535 // iterate on created dimension-hypotheses and check for concurrents
5536 for ( int i = 0; i < 4; i++ ) {
5537 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5538 // check for concurrents in own and other dimensions (step-by-step)
5539 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5540 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5541 const SMESH_DimHyp* dimHyp = *dhIt;
5542 TDimHypList listOfConcurr;
5543 set<int> setOfConcurrIds;
5544 // looking for concurrents and collect into own list
5545 for ( int j = i; j < 4; j++ )
5546 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5547 // check if any concurrents found
5548 if ( listOfConcurr.size() > 0 ) {
5549 // add own submesh to list of concurrent
5550 addInOrderOfPriority( dimHyp, listOfConcurr );
5551 list<int> listOfConcurrIds;
5552 TDimHypList::iterator hypIt = listOfConcurr.begin();
5553 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5554 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5555 anOrder.push_back( listOfConcurrIds );
5560 removeDimHyps(dimHypListArr);
5562 // now, minimise the number of concurrent groups
5563 // Here we assume that lists of submeshes can have same submesh
5564 // in case of multi-dimension algorithms, as result
5565 // list with common submesh has to be united into one list
5567 TListOfListOfInt::iterator listIt = anOrder.begin();
5568 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5569 unionLists( *listIt, anOrder, listIndx + 1 );
5575 //=============================================================================
5577 * \brief Set submesh object order
5578 * \param theSubMeshArray submesh array order
5580 //=============================================================================
5582 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5585 _preMeshInfo->ForgetOrLoad();
5588 ::SMESH_Mesh& mesh = GetImpl();
5590 TPythonDump aPythonDump; // prevent dump of called methods
5591 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5593 TListOfListOfInt subMeshOrder;
5594 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5596 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5597 TListOfInt subMeshIds;
5598 aPythonDump << "[ ";
5599 // Collect subMeshes which should be clear
5600 // do it list-by-list, because modification of submesh order
5601 // take effect between concurrent submeshes only
5602 set<const SMESH_subMesh*> subMeshToClear;
5603 list<const SMESH_subMesh*> subMeshList;
5604 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5606 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5608 aPythonDump << ", ";
5609 aPythonDump << subMesh;
5610 subMeshIds.push_back( subMesh->GetId() );
5611 // detect common parts of submeshes
5612 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5613 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5615 aPythonDump << " ]";
5616 subMeshOrder.push_back( subMeshIds );
5618 // clear collected submeshes
5619 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5620 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5621 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5622 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5624 aPythonDump << " ])";
5626 mesh.SetMeshOrder( subMeshOrder );
5632 //=============================================================================
5634 * \brief Convert submesh ids into submesh interfaces
5636 //=============================================================================
5638 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5639 SMESH::submesh_array_array& theResOrder,
5640 const bool theIsDump)
5642 int nbSet = theIdsOrder.size();
5643 TPythonDump aPythonDump; // prevent dump of called methods
5645 aPythonDump << "[ ";
5646 theResOrder.length(nbSet);
5647 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5649 for( ; it != theIdsOrder.end(); it++ ) {
5650 // translate submesh identificators into submesh objects
5651 // takeing into account real number of concurrent lists
5652 const TListOfInt& aSubOrder = (*it);
5653 if (!aSubOrder.size())
5656 aPythonDump << "[ ";
5657 // convert shape indeces into interfaces
5658 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5659 aResSubSet->length(aSubOrder.size());
5660 TListOfInt::const_iterator subIt = aSubOrder.begin();
5662 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5663 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5665 SMESH::SMESH_subMesh_var subMesh =
5666 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5669 aPythonDump << ", ";
5670 aPythonDump << subMesh;
5672 aResSubSet[ j++ ] = subMesh;
5675 aPythonDump << " ]";
5677 theResOrder[ listIndx++ ] = aResSubSet;
5679 // correct number of lists
5680 theResOrder.length( listIndx );
5683 // finilise python dump
5684 aPythonDump << " ]";
5685 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5689 //================================================================================
5691 // Implementation of SMESH_MeshPartDS
5693 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5694 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5696 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5697 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5699 _meshDS = mesh_i->GetImpl().GetMeshDS();
5701 SetPersistentId( _meshDS->GetPersistentId() );
5703 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5705 // <meshPart> is the whole mesh
5706 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5708 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5709 myGroupSet = _meshDS->GetGroups();
5714 SMESH::long_array_var anIDs = meshPart->GetIDs();
5715 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5716 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5718 for (int i=0; i < anIDs->length(); i++)
5719 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5720 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5725 for (int i=0; i < anIDs->length(); i++)
5726 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5727 if ( _elements[ e->GetType() ].insert( e ).second )
5730 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5731 while ( nIt->more() )
5733 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5734 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5741 _meshDS = 0; // to enforce iteration on _elements and _nodes
5744 // -------------------------------------------------------------------------------------
5745 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5746 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5749 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5750 for ( ; partIt != meshPart.end(); ++partIt )
5751 if ( const SMDS_MeshElement * e = *partIt )
5752 if ( _elements[ e->GetType() ].insert( e ).second )
5755 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5756 while ( nIt->more() )
5758 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5759 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5765 // -------------------------------------------------------------------------------------
5766 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5768 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5770 typedef SMDS_SetIterator
5771 <const SMDS_MeshElement*,
5772 TIDSortedElemSet::const_iterator,
5773 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5774 SMDS_MeshElement::GeomFilter
5777 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5779 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5780 _elements[type].end(),
5781 SMDS_MeshElement::GeomFilter( geomType )));
5783 // -------------------------------------------------------------------------------------
5784 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5786 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5788 typedef SMDS_SetIterator
5789 <const SMDS_MeshElement*,
5790 TIDSortedElemSet::const_iterator,
5791 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5792 SMDS_MeshElement::EntityFilter
5795 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5797 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5798 _elements[type].end(),
5799 SMDS_MeshElement::EntityFilter( entity )));
5801 // -------------------------------------------------------------------------------------
5802 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5804 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5805 if ( type == SMDSAbs_All && !_meshDS )
5807 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5809 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5810 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5812 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5814 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5815 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5817 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5818 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5820 // -------------------------------------------------------------------------------------
5821 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5822 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5824 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5825 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5826 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5828 // -------------------------------------------------------------------------------------
5829 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5830 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5831 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5832 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5833 #undef _GET_ITER_DEFINE
5835 // END Implementation of SMESH_MeshPartDS
5837 //================================================================================