1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_SMESHDS_Mesh.h"
30 #include "MED_Factory.hxx"
31 #include "SMDS_EdgePosition.hxx"
32 #include "SMDS_ElemIterator.hxx"
33 #include "SMDS_FacePosition.hxx"
34 #include "SMDS_IteratorOnIterators.hxx"
35 #include "SMDS_MeshGroup.hxx"
36 #include "SMDS_SetIterator.hxx"
37 #include "SMDS_VolumeTool.hxx"
38 #include "SMESHDS_Command.hxx"
39 #include "SMESHDS_CommandType.hxx"
40 #include "SMESHDS_Group.hxx"
41 #include "SMESHDS_GroupOnGeom.hxx"
42 #include "SMESH_Controls.hxx"
43 #include "SMESH_Filter_i.hxx"
44 #include "SMESH_Gen_i.hxx"
45 #include "SMESH_Group.hxx"
46 #include "SMESH_Group_i.hxx"
47 #include "SMESH_MeshAlgos.hxx"
48 #include "SMESH_MeshEditor.hxx"
49 #include "SMESH_MeshEditor_i.hxx"
50 #include "SMESH_MeshPartDS.hxx"
51 #include "SMESH_MesherHelper.hxx"
52 #include "SMESH_PreMeshInfo.hxx"
53 #include "SMESH_PythonDump.hxx"
54 #include "SMESH_subMesh_i.hxx"
57 #include <SALOMEDS_Attributes_wrap.hxx>
58 #include <SALOMEDS_wrap.hxx>
59 #include <SALOME_NamingService.hxx>
60 #include <Utils_ExceptHandlers.hxx>
61 #include <Utils_SINGLETON.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <OSD_Directory.hxx>
70 #include <OSD_File.hxx>
71 #include <OSD_Path.hxx>
72 #include <OSD_Protection.hxx>
73 #include <Standard_OutOfMemory.hxx>
74 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
75 #include <TColStd_MapOfInteger.hxx>
76 #include <TColStd_SequenceOfInteger.hxx>
77 #include <TCollection_AsciiString.hxx>
79 #include <TopExp_Explorer.hxx>
80 #include <TopTools_MapIteratorOfMapOfShape.hxx>
81 #include <TopTools_MapOfShape.hxx>
82 #include <TopoDS_Compound.hxx>
92 // to pass CORBA exception through SMESH_TRY
93 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
95 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
98 static int MYDEBUG = 0;
100 static int MYDEBUG = 0;
104 using SMESH::TPythonDump;
106 int SMESH_Mesh_i::_idGenerator = 0;
108 //=============================================================================
112 //=============================================================================
114 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
116 CORBA::Long studyId )
117 : SALOME::GenericObj_i( thePOA )
119 MESSAGE("SMESH_Mesh_i");
122 _id = _idGenerator++;
125 _previewEditor = NULL;
129 //=============================================================================
133 //=============================================================================
135 SMESH_Mesh_i::~SMESH_Mesh_i()
137 MESSAGE("~SMESH_Mesh_i");
140 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
141 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
142 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
144 aGroup->UnRegister();
145 SMESH::SMESH_GroupBase_var( itGr->second );
150 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
151 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
152 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
154 aSubMesh->UnRegister();
155 SMESH::SMESH_subMesh_var( itSM->second );
157 _mapSubMeshIor.clear();
159 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
160 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
161 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
162 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
163 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
164 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
167 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
171 delete _editor; _editor = NULL;
172 delete _previewEditor; _previewEditor = NULL;
173 delete _impl; _impl = NULL;
174 delete _preMeshInfo; _preMeshInfo = NULL;
177 //=============================================================================
181 * Associates <this> mesh with <theShape> and puts a reference
182 * to <theShape> into the current study;
183 * the previous shape is substituted by the new one.
185 //=============================================================================
187 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
188 throw (SALOME::SALOME_Exception)
190 Unexpect aCatch(SALOME_SalomeException);
192 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
194 catch(SALOME_Exception & S_ex) {
195 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
197 // to track changes of GEOM groups
198 SMESH::SMESH_Mesh_var mesh = _this();
199 addGeomGroupData( theShapeObject, mesh );
202 //================================================================================
204 * \brief return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 throw (SALOME::SALOME_Exception)
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //=======================================================================
223 //function : GetShapeToMesh
225 //=======================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 throw (SALOME::SALOME_Exception)
230 Unexpect aCatch(SALOME_SalomeException);
231 GEOM::GEOM_Object_var aShapeObj;
233 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 catch(SALOME_Exception & S_ex) {
238 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
240 return aShapeObj._retn();
243 //================================================================================
245 * \brief Return false if the mesh is not yet fully loaded from the study file
247 //================================================================================
249 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
251 Unexpect aCatch(SALOME_SalomeException);
252 return !_preMeshInfo;
255 //================================================================================
257 * \brief Load full mesh data from the study file
259 //================================================================================
261 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
263 Unexpect aCatch(SALOME_SalomeException);
265 _preMeshInfo->FullLoadFromFile();
268 //================================================================================
270 * \brief Remove all nodes and elements
272 //================================================================================
274 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->ForgetAllData();
282 CheckGeomGroupModif(); // issue 20145
284 catch(SALOME_Exception & S_ex) {
285 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
287 _impl->GetMeshDS()->Modified();
289 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
292 //================================================================================
294 * \brief Remove all nodes and elements for indicated shape
296 //================================================================================
298 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
299 throw (SALOME::SALOME_Exception)
301 Unexpect aCatch(SALOME_SalomeException);
303 _preMeshInfo->FullLoadFromFile();
306 _impl->ClearSubMesh( ShapeID );
308 catch(SALOME_Exception & S_ex) {
309 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
311 _impl->GetMeshDS()->Modified();
313 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
316 //=============================================================================
318 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
320 //=============================================================================
322 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
324 SMESH::DriverMED_ReadStatus res;
327 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
328 res = SMESH::DRS_OK; break;
329 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
330 res = SMESH::DRS_EMPTY; break;
331 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
332 res = SMESH::DRS_WARN_RENUMBER; break;
333 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
334 res = SMESH::DRS_WARN_SKIP_ELEM; break;
335 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
336 res = SMESH::DRS_WARN_DESCENDING; break;
337 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
339 res = SMESH::DRS_FAIL; break;
344 //=============================================================================
346 * Convert ::SMESH_ComputeError to SMESH::ComputeError
348 //=============================================================================
350 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
352 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
353 errVar->subShapeID = -1;
354 errVar->hasBadMesh = false;
356 if ( !errorPtr || errorPtr->IsOK() )
358 errVar->code = SMESH::COMPERR_OK;
362 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
363 errVar->comment = errorPtr->myComment.c_str();
365 return errVar._retn();
368 //=============================================================================
372 * Imports mesh data from MED file
374 //=============================================================================
376 SMESH::DriverMED_ReadStatus
377 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
378 throw ( SALOME::SALOME_Exception )
380 Unexpect aCatch(SALOME_SalomeException);
383 status = _impl->MEDToMesh( theFileName, theMeshName );
385 catch( SALOME_Exception& S_ex ) {
386 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
389 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
392 CreateGroupServants();
394 int major, minor, release;
395 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
396 major = minor = release = -1;
397 _medFileInfo = new SMESH::MedFileInfo();
398 _medFileInfo->fileName = theFileName;
399 _medFileInfo->fileSize = 0;
400 _medFileInfo->major = major;
401 _medFileInfo->minor = minor;
402 _medFileInfo->release = release;
405 if ( ::_stati64( theFileName, &d ) != -1 )
408 if ( ::stat64( theFileName, &d ) != -1 )
410 _medFileInfo->fileSize = d.st_size;
412 return ConvertDriverMEDReadStatus(status);
415 //================================================================================
417 * \brief Imports mesh data from the CGNS file
419 //================================================================================
421 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
422 const int theMeshIndex,
423 std::string& theMeshName )
424 throw ( SALOME::SALOME_Exception )
426 Unexpect aCatch(SALOME_SalomeException);
429 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
431 catch( SALOME_Exception& S_ex ) {
432 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
435 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
438 CreateGroupServants();
440 return ConvertDriverMEDReadStatus(status);
443 //================================================================================
445 * \brief Return string representation of a MED file version comprising nbDigits
447 //================================================================================
449 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
451 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
453 return CORBA::string_dup( ver.c_str() );
456 //=============================================================================
460 * Imports mesh data from MED file
462 //=============================================================================
464 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
465 throw ( SALOME::SALOME_Exception )
469 // Read mesh with name = <theMeshName> into SMESH_Mesh
470 _impl->UNVToMesh( theFileName );
472 CreateGroupServants();
474 SMESH_CATCH( SMESH::throwCorbaException );
479 //=============================================================================
483 * Imports mesh data from STL file
485 //=============================================================================
486 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
487 throw ( SALOME::SALOME_Exception )
491 // Read mesh with name = <theMeshName> into SMESH_Mesh
492 _impl->STLToMesh( theFileName );
494 SMESH_CATCH( SMESH::throwCorbaException );
499 //================================================================================
501 * \brief Function used in SMESH_CATCH by ImportGMFFile()
503 //================================================================================
507 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
509 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
513 //================================================================================
515 * \brief Imports data from a GMF file and returns an error description
517 //================================================================================
519 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
520 bool theMakeRequiredGroups )
521 throw (SALOME::SALOME_Exception)
523 SMESH_ComputeErrorPtr error;
526 #define SMESH_CAUGHT error =
529 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
531 SMESH_CATCH( exceptionToComputeError );
535 CreateGroupServants();
537 return ConvertComputeError( error );
540 //=============================================================================
544 //=============================================================================
546 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
548 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
549 (SMESH_Hypothesis::Hypothesis_Status theStatus)
552 RETURNCASE( HYP_OK );
553 RETURNCASE( HYP_MISSING );
554 RETURNCASE( HYP_CONCURENT );
555 RETURNCASE( HYP_BAD_PARAMETER );
556 RETURNCASE( HYP_HIDDEN_ALGO );
557 RETURNCASE( HYP_HIDING_ALGO );
558 RETURNCASE( HYP_UNKNOWN_FATAL );
559 RETURNCASE( HYP_INCOMPATIBLE );
560 RETURNCASE( HYP_NOTCONFORM );
561 RETURNCASE( HYP_ALREADY_EXIST );
562 RETURNCASE( HYP_BAD_DIM );
563 RETURNCASE( HYP_BAD_SUBSHAPE );
564 RETURNCASE( HYP_BAD_GEOMETRY );
565 RETURNCASE( HYP_NEED_SHAPE );
568 return SMESH::HYP_UNKNOWN_FATAL;
571 //=============================================================================
575 * calls internal addHypothesis() and then adds a reference to <anHyp> under
576 * the SObject actually having a reference to <aSubShape>.
577 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
579 //=============================================================================
581 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
582 SMESH::SMESH_Hypothesis_ptr anHyp)
583 throw(SALOME::SALOME_Exception)
585 Unexpect aCatch(SALOME_SalomeException);
587 _preMeshInfo->ForgetOrLoad();
589 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
591 SMESH::SMESH_Mesh_var mesh( _this() );
592 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
594 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
595 _gen_i->AddHypothesisToShape( study, mesh, aSubShapeObject, anHyp );
597 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
599 // Update Python script
600 //if(_impl->HasShapeToMesh())
602 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
603 << aSubShapeObject << ", " << anHyp << " )";
606 // TPythonDump() << "status = " << mesh << ".AddHypothesis( "<< anHyp << " )";
609 return ConvertHypothesisStatus(status);
612 //=============================================================================
616 //=============================================================================
618 SMESH_Hypothesis::Hypothesis_Status
619 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
620 SMESH::SMESH_Hypothesis_ptr anHyp)
622 if(MYDEBUG) MESSAGE("addHypothesis");
624 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
625 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
627 if (CORBA::is_nil( anHyp ))
628 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
630 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
633 TopoDS_Shape myLocSubShape;
634 //use PseudoShape in case if mesh has no shape
636 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
638 myLocSubShape = _impl->GetShapeToMesh();
640 const int hypId = anHyp->GetId();
641 status = _impl->AddHypothesis(myLocSubShape, hypId);
642 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
643 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
645 // assure there is a corresponding submesh
646 if ( !_impl->IsMainShape( myLocSubShape )) {
647 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
648 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
649 SMESH::SMESH_subMesh_var( createSubMesh( aSubShapeObject ));
653 catch(SALOME_Exception & S_ex)
655 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
660 //=============================================================================
664 //=============================================================================
666 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
667 SMESH::SMESH_Hypothesis_ptr anHyp)
668 throw(SALOME::SALOME_Exception)
670 Unexpect aCatch(SALOME_SalomeException);
672 _preMeshInfo->ForgetOrLoad();
674 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
675 SMESH::SMESH_Mesh_var mesh = _this();
677 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
679 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
680 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShapeObject, anHyp );
682 // Update Python script
683 if(_impl->HasShapeToMesh())
684 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
685 << aSubShapeObject << ", " << anHyp << " )";
687 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
690 return ConvertHypothesisStatus(status);
693 //=============================================================================
697 //=============================================================================
699 SMESH_Hypothesis::Hypothesis_Status
700 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
701 SMESH::SMESH_Hypothesis_ptr anHyp)
703 if(MYDEBUG) MESSAGE("removeHypothesis()");
705 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
706 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
708 if (CORBA::is_nil( anHyp ))
709 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
711 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
714 TopoDS_Shape myLocSubShape;
715 //use PseudoShape in case if mesh has no shape
716 if( _impl->HasShapeToMesh() )
717 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject );
719 myLocSubShape = _impl->GetShapeToMesh();
721 const int hypId = anHyp->GetId();
722 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
723 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
725 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
729 catch(SALOME_Exception & S_ex)
731 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
736 //=============================================================================
740 //=============================================================================
742 SMESH::ListOfHypothesis *
743 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
744 throw(SALOME::SALOME_Exception)
746 Unexpect aCatch(SALOME_SalomeException);
747 if (MYDEBUG) MESSAGE("GetHypothesisList");
748 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
749 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
751 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
754 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
755 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
756 myLocSubShape = _impl->GetShapeToMesh();
757 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
758 int i = 0, n = aLocalList.size();
761 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
762 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
763 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
765 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
766 if ( id_hypptr != _mapHypo.end() )
767 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
771 catch(SALOME_Exception & S_ex) {
772 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
775 return aList._retn();
778 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
780 Unexpect aCatch(SALOME_SalomeException);
781 if (MYDEBUG) MESSAGE("GetSubMeshes");
783 SMESH::submesh_array_var aList = new SMESH::submesh_array();
786 TPythonDump aPythonDump;
787 if ( !_mapSubMeshIor.empty() )
791 aList->length( _mapSubMeshIor.size() );
793 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
794 for ( ; it != _mapSubMeshIor.end(); it++ ) {
795 if ( CORBA::is_nil( it->second )) continue;
796 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
798 if (i > 1) aPythonDump << ", ";
799 aPythonDump << it->second;
803 catch(SALOME_Exception & S_ex) {
804 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
807 // Update Python script
808 if ( !_mapSubMeshIor.empty() )
809 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
811 return aList._retn();
814 //=============================================================================
818 //=============================================================================
820 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
821 const char* theName )
822 throw(SALOME::SALOME_Exception)
824 Unexpect aCatch(SALOME_SalomeException);
825 if (CORBA::is_nil(aSubShapeObject))
826 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
828 SMESH::SMESH_subMesh_var subMesh;
829 SMESH::SMESH_Mesh_var aMesh = _this();
831 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
833 //Get or Create the SMESH_subMesh object implementation
835 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
837 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
839 TopoDS_Iterator it( myLocSubShape );
841 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
843 subMesh = getSubMesh( subMeshId );
845 // create a new subMesh object servant if there is none for the shape
846 if ( subMesh->_is_nil() )
847 subMesh = createSubMesh( aSubShapeObject );
848 if ( _gen_i->CanPublishInStudy( subMesh ))
850 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
851 SALOMEDS::SObject_wrap aSO =
852 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShapeObject, theName );
853 if ( !aSO->_is_nil()) {
854 // Update Python script
855 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
856 << aSubShapeObject << ", '" << theName << "' )";
860 catch(SALOME_Exception & S_ex) {
861 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
863 return subMesh._retn();
866 //=============================================================================
870 //=============================================================================
872 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
873 throw (SALOME::SALOME_Exception)
877 if ( theSubMesh->_is_nil() )
880 GEOM::GEOM_Object_var aSubShapeObject;
881 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
882 if ( !aStudy->_is_nil() ) {
883 // Remove submesh's SObject
884 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
885 if ( !anSO->_is_nil() ) {
886 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
887 SALOMEDS::SObject_wrap anObj, aRef;
888 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
889 anObj->ReferencedObject( aRef.inout() ))
891 CORBA::Object_var obj = aRef->GetObject();
892 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
894 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
895 // aSubShapeObject = theSubMesh->GetSubShape();
897 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
898 builder->RemoveObjectWithChildren( anSO );
900 // Update Python script
901 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
905 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
907 _preMeshInfo->ForgetOrLoad();
909 SMESH_CATCH( SMESH::throwCorbaException );
912 //=============================================================================
916 //=============================================================================
918 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
919 const char* theName )
920 throw(SALOME::SALOME_Exception)
922 Unexpect aCatch(SALOME_SalomeException);
924 _preMeshInfo->FullLoadFromFile();
926 SMESH::SMESH_Group_var aNewGroup =
927 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
929 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
931 SMESH::SMESH_Mesh_var mesh = _this();
932 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
933 SALOMEDS::SObject_wrap aSO =
934 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
935 if ( !aSO->_is_nil())
936 // Update Python script
937 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
938 << theElemType << ", '" << theName << "' )";
940 return aNewGroup._retn();
943 //=============================================================================
947 //=============================================================================
948 SMESH::SMESH_GroupOnGeom_ptr
949 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
951 GEOM::GEOM_Object_ptr theGeomObj)
952 throw(SALOME::SALOME_Exception)
954 Unexpect aCatch(SALOME_SalomeException);
956 _preMeshInfo->FullLoadFromFile();
958 SMESH::SMESH_GroupOnGeom_var aNewGroup;
960 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
961 if ( !aShape.IsNull() )
964 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
966 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
968 SMESH::SMESH_Mesh_var mesh = _this();
969 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
970 SALOMEDS::SObject_wrap aSO =
971 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
972 if ( !aSO->_is_nil())
973 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
974 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
978 return aNewGroup._retn();
981 //================================================================================
983 * \brief Creates a group whose contents is defined by filter
984 * \param theElemType - group type
985 * \param theName - group name
986 * \param theFilter - the filter
987 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
989 //================================================================================
991 SMESH::SMESH_GroupOnFilter_ptr
992 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
994 SMESH::Filter_ptr theFilter )
995 throw (SALOME::SALOME_Exception)
997 Unexpect aCatch(SALOME_SalomeException);
999 _preMeshInfo->FullLoadFromFile();
1001 if ( CORBA::is_nil( theFilter ))
1002 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1004 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1006 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1008 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1009 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1012 if ( !aNewGroup->_is_nil() )
1013 aNewGroup->SetFilter( theFilter );
1015 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1017 SMESH::SMESH_Mesh_var mesh = _this();
1018 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1019 SALOMEDS::SObject_wrap aSO =
1020 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1022 if ( !aSO->_is_nil())
1023 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1024 << theElemType << ", '" << theName << "', " << theFilter << " )";
1026 return aNewGroup._retn();
1029 //=============================================================================
1033 //=============================================================================
1035 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1036 throw (SALOME::SALOME_Exception)
1038 if ( theGroup->_is_nil() )
1043 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1047 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1048 if ( !aStudy->_is_nil() )
1050 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1051 if ( !aGroupSO->_is_nil() )
1053 // Update Python script
1054 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1056 // Remove group's SObject
1057 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1058 builder->RemoveObjectWithChildren( aGroupSO );
1062 // Remove the group from SMESH data structures
1063 removeGroup( aGroup->GetLocalID() );
1065 SMESH_CATCH( SMESH::throwCorbaException );
1068 //=============================================================================
1070 * Remove group with its contents
1072 //=============================================================================
1074 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1075 throw (SALOME::SALOME_Exception)
1079 _preMeshInfo->FullLoadFromFile();
1081 if ( theGroup->_is_nil() )
1085 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1086 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1087 while ( elemIt->more() )
1088 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1090 TPythonDump pyDump; // Supress dump from RemoveGroup()
1092 // Update Python script (theGroup must be alive for this)
1093 pyDump << SMESH::SMESH_Mesh_var(_this())
1094 << ".RemoveGroupWithContents( " << theGroup << " )";
1097 RemoveGroup( theGroup );
1099 SMESH_CATCH( SMESH::throwCorbaException );
1102 //================================================================================
1104 * \brief Get the list of groups existing in the mesh
1105 * \retval SMESH::ListOfGroups * - list of groups
1107 //================================================================================
1109 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1111 Unexpect aCatch(SALOME_SalomeException);
1112 if (MYDEBUG) MESSAGE("GetGroups");
1114 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1117 TPythonDump aPythonDump;
1118 if ( !_mapGroups.empty() )
1120 aPythonDump << "[ ";
1122 aList->length( _mapGroups.size() );
1124 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1125 for ( ; it != _mapGroups.end(); it++ ) {
1126 if ( CORBA::is_nil( it->second )) continue;
1127 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1129 if (i > 1) aPythonDump << ", ";
1130 aPythonDump << it->second;
1134 catch(SALOME_Exception & S_ex) {
1135 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1137 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1139 return aList._retn();
1142 //=============================================================================
1144 * Get number of groups existing in the mesh
1146 //=============================================================================
1148 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1150 Unexpect aCatch(SALOME_SalomeException);
1151 return _mapGroups.size();
1154 //=============================================================================
1156 * New group including all mesh elements present in initial groups is created.
1158 //=============================================================================
1160 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1161 SMESH::SMESH_GroupBase_ptr theGroup2,
1162 const char* theName )
1163 throw (SALOME::SALOME_Exception)
1165 SMESH::SMESH_Group_var aResGrp;
1169 _preMeshInfo->FullLoadFromFile();
1171 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1172 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1174 if ( theGroup1->GetType() != theGroup2->GetType() )
1175 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1180 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1181 if ( aResGrp->_is_nil() )
1182 return SMESH::SMESH_Group::_nil();
1184 aResGrp->AddFrom( theGroup1 );
1185 aResGrp->AddFrom( theGroup2 );
1187 // Update Python script
1188 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1189 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1191 SMESH_CATCH( SMESH::throwCorbaException );
1193 return aResGrp._retn();
1196 //=============================================================================
1198 * \brief New group including all mesh elements present in initial groups is created.
1199 * \param theGroups list of groups
1200 * \param theName name of group to be created
1201 * \return pointer to the new group
1203 //=============================================================================
1205 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1206 const char* theName )
1207 throw (SALOME::SALOME_Exception)
1209 SMESH::SMESH_Group_var aResGrp;
1212 _preMeshInfo->FullLoadFromFile();
1215 return SMESH::SMESH_Group::_nil();
1220 SMESH::ElementType aType = SMESH::ALL;
1221 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1223 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1224 if ( CORBA::is_nil( aGrp ) )
1226 if ( aType == SMESH::ALL )
1227 aType = aGrp->GetType();
1228 else if ( aType != aGrp->GetType() )
1229 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1232 if ( aType == SMESH::ALL )
1233 return SMESH::SMESH_Group::_nil();
1238 aResGrp = CreateGroup( aType, theName );
1239 if ( aResGrp->_is_nil() )
1240 return SMESH::SMESH_Group::_nil();
1242 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1243 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1245 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1246 if ( !CORBA::is_nil( aGrp ) )
1248 aResGrp->AddFrom( aGrp );
1249 if ( g > 0 ) pyDump << ", ";
1253 pyDump << " ], '" << theName << "' )";
1255 SMESH_CATCH( SMESH::throwCorbaException );
1257 return aResGrp._retn();
1260 //=============================================================================
1262 * New group is created. All mesh elements that are
1263 * present in both initial groups are added to the new one.
1265 //=============================================================================
1267 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1268 SMESH::SMESH_GroupBase_ptr theGroup2,
1269 const char* theName )
1270 throw (SALOME::SALOME_Exception)
1272 SMESH::SMESH_Group_var aResGrp;
1277 _preMeshInfo->FullLoadFromFile();
1279 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1280 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1282 if ( theGroup1->GetType() != theGroup2->GetType() )
1283 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1287 // Create Intersection
1288 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1289 if ( aResGrp->_is_nil() )
1290 return aResGrp._retn();
1292 SMESHDS_GroupBase* groupDS1 = 0;
1293 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1294 groupDS1 = grp_i->GetGroupDS();
1296 SMESHDS_GroupBase* groupDS2 = 0;
1297 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1298 groupDS2 = grp_i->GetGroupDS();
1300 SMESHDS_Group* resGroupDS = 0;
1301 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1302 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1304 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1306 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1307 while ( elemIt1->more() )
1309 const SMDS_MeshElement* e = elemIt1->next();
1310 if ( groupDS2->Contains( e ))
1311 resGroupDS->SMDSGroup().Add( e );
1314 // Update Python script
1315 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1316 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1318 SMESH_CATCH( SMESH::throwCorbaException );
1320 return aResGrp._retn();
1323 //=============================================================================
1325 \brief Intersect list of groups. New group is created. All mesh elements that
1326 are present in all initial groups simultaneously are added to the new one.
1327 \param theGroups list of groups
1328 \param theName name of group to be created
1329 \return pointer on the group
1331 //=============================================================================
1332 SMESH::SMESH_Group_ptr
1333 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1334 const char* theName )
1335 throw (SALOME::SALOME_Exception)
1337 SMESH::SMESH_Group_var aResGrp;
1342 _preMeshInfo->FullLoadFromFile();
1345 return SMESH::SMESH_Group::_nil();
1347 // check types and get SMESHDS_GroupBase's
1348 SMESH::ElementType aType = SMESH::ALL;
1349 vector< SMESHDS_GroupBase* > groupVec;
1350 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1352 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1353 if ( CORBA::is_nil( aGrp ) )
1355 if ( aType == SMESH::ALL )
1356 aType = aGrp->GetType();
1357 else if ( aType != aGrp->GetType() )
1358 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1361 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1362 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1364 if ( grpDS->IsEmpty() )
1369 groupVec.push_back( grpDS );
1372 if ( aType == SMESH::ALL ) // all groups are nil
1373 return SMESH::SMESH_Group::_nil();
1378 aResGrp = CreateGroup( aType, theName );
1380 SMESHDS_Group* resGroupDS = 0;
1381 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1382 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1383 if ( !resGroupDS || groupVec.empty() )
1384 return aResGrp._retn();
1387 size_t i, nb = groupVec.size();
1388 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1389 while ( elemIt1->more() )
1391 const SMDS_MeshElement* e = elemIt1->next();
1393 for ( i = 1; ( i < nb && inAll ); ++i )
1394 inAll = groupVec[i]->Contains( e );
1397 resGroupDS->SMDSGroup().Add( e );
1400 // Update Python script
1401 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1402 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1404 SMESH_CATCH( SMESH::throwCorbaException );
1406 return aResGrp._retn();
1409 //=============================================================================
1411 * New group is created. All mesh elements that are present in
1412 * a main group but is not present in a tool group are added to the new one
1414 //=============================================================================
1416 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1417 SMESH::SMESH_GroupBase_ptr theGroup2,
1418 const char* theName )
1419 throw (SALOME::SALOME_Exception)
1421 SMESH::SMESH_Group_var aResGrp;
1426 _preMeshInfo->FullLoadFromFile();
1428 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1429 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1431 if ( theGroup1->GetType() != theGroup2->GetType() )
1432 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1436 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1437 if ( aResGrp->_is_nil() )
1438 return aResGrp._retn();
1440 SMESHDS_GroupBase* groupDS1 = 0;
1441 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1442 groupDS1 = grp_i->GetGroupDS();
1444 SMESHDS_GroupBase* groupDS2 = 0;
1445 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1446 groupDS2 = grp_i->GetGroupDS();
1448 SMESHDS_Group* resGroupDS = 0;
1449 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1450 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1452 if ( groupDS1 && groupDS2 && resGroupDS )
1454 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1455 while ( elemIt1->more() )
1457 const SMDS_MeshElement* e = elemIt1->next();
1458 if ( !groupDS2->Contains( e ))
1459 resGroupDS->SMDSGroup().Add( e );
1462 // Update Python script
1463 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1464 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1466 SMESH_CATCH( SMESH::throwCorbaException );
1468 return aResGrp._retn();
1471 //=============================================================================
1473 \brief Cut lists of groups. New group is created. All mesh elements that are
1474 present in main groups but do not present in tool groups are added to the new one
1475 \param theMainGroups list of main groups
1476 \param theToolGroups list of tool groups
1477 \param theName name of group to be created
1478 \return pointer on the group
1480 //=============================================================================
1481 SMESH::SMESH_Group_ptr
1482 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1483 const SMESH::ListOfGroups& theToolGroups,
1484 const char* theName )
1485 throw (SALOME::SALOME_Exception)
1487 SMESH::SMESH_Group_var aResGrp;
1492 _preMeshInfo->FullLoadFromFile();
1495 return SMESH::SMESH_Group::_nil();
1497 // check types and get SMESHDS_GroupBase's
1498 SMESH::ElementType aType = SMESH::ALL;
1499 vector< SMESHDS_GroupBase* > toolGroupVec;
1500 vector< SMDS_ElemIteratorPtr > mainIterVec;
1502 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1504 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1505 if ( CORBA::is_nil( aGrp ) )
1507 if ( aType == SMESH::ALL )
1508 aType = aGrp->GetType();
1509 else if ( aType != aGrp->GetType() )
1510 THROW_SALOME_CORBA_EXCEPTION("CreateDimGroup(): different group types",
1512 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1513 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1514 if ( !grpDS->IsEmpty() )
1515 mainIterVec.push_back( grpDS->GetElements() );
1517 if ( aType == SMESH::ALL ) // all main groups are nil
1518 return SMESH::SMESH_Group::_nil();
1519 if ( mainIterVec.empty() ) // all main groups are empty
1520 return aResGrp._retn();
1522 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1524 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1525 if ( CORBA::is_nil( aGrp ) )
1527 if ( aType != aGrp->GetType() )
1528 THROW_SALOME_CORBA_EXCEPTION("CreateDimGroup(): different group types",
1530 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1531 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1532 toolGroupVec.push_back( grpDS );
1538 aResGrp = CreateGroup( aType, theName );
1540 SMESHDS_Group* resGroupDS = 0;
1541 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1542 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1544 return aResGrp._retn();
1547 size_t i, nb = toolGroupVec.size();
1548 SMDS_ElemIteratorPtr mainElemIt
1549 ( new SMDS_IteratorOnIterators
1550 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1551 while ( mainElemIt->more() )
1553 const SMDS_MeshElement* e = mainElemIt->next();
1555 for ( i = 0; ( i < nb && !isIn ); ++i )
1556 isIn = toolGroupVec[i]->Contains( e );
1559 resGroupDS->SMDSGroup().Add( e );
1562 // Update Python script
1563 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1564 << ".CutListOfGroups( " << theMainGroups
1565 << theToolGroups << ", '" << theName << "' )";
1567 SMESH_CATCH( SMESH::throwCorbaException );
1569 return aResGrp._retn();
1572 //=============================================================================
1574 \brief Create groups of entities from existing groups of superior dimensions
1576 1) extract all nodes from each group,
1577 2) combine all elements of specified dimension laying on these nodes.
1578 \param theGroups list of source groups
1579 \param theElemType dimension of elements
1580 \param theName name of new group
1581 \return pointer on new group
1585 //=============================================================================
1587 SMESH::SMESH_Group_ptr
1588 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1589 SMESH::ElementType theElemType,
1590 const char* theName )
1591 throw (SALOME::SALOME_Exception)
1593 SMESH::SMESH_Group_var aResGrp;
1597 _preMeshInfo->FullLoadFromFile();
1599 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1601 if ( !theName || !aMeshDS )
1602 return SMESH::SMESH_Group::_nil();
1604 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1610 aResGrp = CreateGroup( theElemType, theName );
1611 if ( aResGrp->_is_nil() )
1612 return SMESH::SMESH_Group::_nil();
1614 SMESHDS_GroupBase* groupBaseDS =
1615 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1616 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1618 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1620 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1621 if ( CORBA::is_nil( aGrp ) )
1624 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1625 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1627 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1629 while ( elIt->more() ) {
1630 const SMDS_MeshElement* el = elIt->next();
1631 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1632 while ( nIt->more() )
1633 resGroupCore.Add( nIt->next() );
1636 else // get elements of theElemType based on nodes of every element of group
1638 while ( elIt->more() )
1640 const SMDS_MeshElement* el = elIt->next(); // an element of group
1641 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1642 TIDSortedElemSet checkedElems;
1643 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1644 while ( nIt->more() )
1646 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1647 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1648 // check nodes of elements of theElemType around el
1649 while ( elOfTypeIt->more() )
1651 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1652 if ( !checkedElems.insert( elOfType ).second ) continue;
1654 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1655 bool allNodesOK = true;
1656 while ( nIt2->more() && allNodesOK )
1657 allNodesOK = elNodes.count( nIt2->next() );
1659 resGroupCore.Add( elOfType );
1666 // Update Python script
1667 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1668 << ".CreateDimGroup( "
1669 << theGroups << ", " << theElemType << ", '" << theName << "' )";
1671 SMESH_CATCH( SMESH::throwCorbaException );
1673 return aResGrp._retn();
1676 //================================================================================
1678 * \brief Remember GEOM group data
1680 //================================================================================
1682 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1683 CORBA::Object_ptr theSmeshObj)
1685 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1688 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1689 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1690 if ( groupSO->_is_nil() )
1693 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1694 GEOM::GEOM_IGroupOperations_wrap groupOp =
1695 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1696 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1699 _geomGroupData.push_back( TGeomGroupData() );
1700 TGeomGroupData & groupData = _geomGroupData.back();
1702 CORBA::String_var entry = groupSO->GetID();
1703 groupData._groupEntry = entry.in();
1705 for ( int i = 0; i < ids->length(); ++i )
1706 groupData._indices.insert( ids[i] );
1708 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1711 //================================================================================
1713 * Remove GEOM group data relating to removed smesh object
1715 //================================================================================
1717 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1719 list<TGeomGroupData>::iterator
1720 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1721 for ( ; data != dataEnd; ++data ) {
1722 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1723 _geomGroupData.erase( data );
1729 //================================================================================
1731 * \brief Return new group contents if it has been changed and update group data
1733 //================================================================================
1735 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1737 TopoDS_Shape newShape;
1740 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1741 if ( study->_is_nil() ) return newShape; // means "not changed"
1742 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1743 if ( !groupSO->_is_nil() )
1745 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1746 if ( CORBA::is_nil( groupObj )) return newShape;
1747 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1749 // get indices of group items
1750 set<int> curIndices;
1751 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1752 GEOM::GEOM_IGroupOperations_wrap groupOp =
1753 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1754 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1755 for ( int i = 0; i < ids->length(); ++i )
1756 curIndices.insert( ids[i] );
1758 if ( groupData._indices == curIndices )
1759 return newShape; // group not changed
1762 groupData._indices = curIndices;
1764 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1765 if ( !geomClient ) return newShape;
1766 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1767 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1768 newShape = _gen_i->GeomObjectToShape( geomGroup );
1771 if ( newShape.IsNull() ) {
1772 // geom group becomes empty - return empty compound
1773 TopoDS_Compound compound;
1774 BRep_Builder().MakeCompound(compound);
1775 newShape = compound;
1782 //=============================================================================
1784 * \brief Storage of shape and index used in CheckGeomGroupModif()
1786 //=============================================================================
1787 struct TIndexedShape
1790 TopoDS_Shape _shape;
1791 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1794 //=============================================================================
1796 * \brief Update objects depending on changed geom groups
1798 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1799 * issue 0020210: Update of a smesh group after modification of the associated geom group
1801 //=============================================================================
1803 void SMESH_Mesh_i::CheckGeomGroupModif()
1805 if ( !_impl->HasShapeToMesh() ) return;
1807 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1808 if ( study->_is_nil() ) return;
1810 CORBA::Long nbEntities = NbNodes() + NbElements();
1812 // Check if group contents changed
1814 typedef map< string, TopoDS_Shape > TEntry2Geom;
1815 TEntry2Geom newGroupContents;
1817 list<TGeomGroupData>::iterator
1818 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1819 for ( ; data != dataEnd; ++data )
1821 pair< TEntry2Geom::iterator, bool > it_new =
1822 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1823 bool processedGroup = !it_new.second;
1824 TopoDS_Shape& newShape = it_new.first->second;
1825 if ( !processedGroup )
1826 newShape = newGroupShape( *data );
1827 if ( newShape.IsNull() )
1828 continue; // no changes
1831 _preMeshInfo->ForgetOrLoad();
1833 if ( processedGroup ) { // update group indices
1834 list<TGeomGroupData>::iterator data2 = data;
1835 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1836 data->_indices = data2->_indices;
1839 // Update SMESH objects according to new GEOM group contents
1841 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1842 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1844 int oldID = submesh->GetId();
1845 if ( !_mapSubMeshIor.count( oldID ))
1847 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1849 // update hypotheses
1850 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1851 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1852 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1854 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1855 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1857 // care of submeshes
1858 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1859 int newID = newSubmesh->GetId();
1860 if ( newID != oldID ) {
1861 _mapSubMesh [ newID ] = newSubmesh;
1862 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1863 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1864 _mapSubMesh. erase(oldID);
1865 _mapSubMesh_i. erase(oldID);
1866 _mapSubMeshIor.erase(oldID);
1867 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1872 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1873 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1874 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1876 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1878 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1879 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1880 ds->SetShape( newShape );
1885 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1886 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1888 // Remove groups and submeshes basing on removed sub-shapes
1890 TopTools_MapOfShape newShapeMap;
1891 TopoDS_Iterator shapeIt( newShape );
1892 for ( ; shapeIt.More(); shapeIt.Next() )
1893 newShapeMap.Add( shapeIt.Value() );
1895 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1896 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1898 if ( newShapeMap.Contains( shapeIt.Value() ))
1900 TopTools_IndexedMapOfShape oldShapeMap;
1901 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1902 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1904 const TopoDS_Shape& oldShape = oldShapeMap(i);
1905 int oldInd = meshDS->ShapeToIndex( oldShape );
1907 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1908 if ( i_smIor != _mapSubMeshIor.end() ) {
1909 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1912 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1913 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1915 // check if a group bases on oldInd shape
1916 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1917 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1918 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1919 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1921 RemoveGroup( i_grp->second ); // several groups can base on same shape
1922 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1927 // Reassign hypotheses and update groups after setting the new shape to mesh
1929 // collect anassigned hypotheses
1930 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1931 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1932 TShapeHypList assignedHyps;
1933 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1935 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1936 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1937 if ( !hyps.empty() ) {
1938 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1939 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1940 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1943 // collect shapes supporting groups
1944 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1945 TShapeTypeList groupData;
1946 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1947 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1948 for ( ; grIt != groups.end(); ++grIt )
1950 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1952 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1954 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1955 _impl->ShapeToMesh( newShape );
1957 // reassign hypotheses
1958 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1959 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1961 TIndexedShape& geom = indS_hyps->first;
1962 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1963 int oldID = geom._index;
1964 int newID = meshDS->ShapeToIndex( geom._shape );
1965 if ( oldID == 1 ) { // main shape
1967 geom._shape = newShape;
1971 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1972 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1973 // care of submeshes
1974 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1975 if ( newID != oldID ) {
1976 _mapSubMesh [ newID ] = newSubmesh;
1977 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1978 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1979 _mapSubMesh. erase(oldID);
1980 _mapSubMesh_i. erase(oldID);
1981 _mapSubMeshIor.erase(oldID);
1982 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1986 TShapeTypeList::iterator geomType = groupData.begin();
1987 for ( ; geomType != groupData.end(); ++geomType )
1989 const TIndexedShape& geom = geomType->first;
1990 int oldID = geom._index;
1991 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1994 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1995 CORBA::String_var name = groupSO->GetName();
1997 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1999 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2000 group_i->changeLocalId( newID );
2003 break; // everything has been updated
2006 } // loop on group data
2010 CORBA::Long newNbEntities = NbNodes() + NbElements();
2011 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2012 if ( newNbEntities != nbEntities )
2014 // Add all SObjects with icons to soToUpdateIcons
2015 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2017 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2018 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2019 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2021 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2022 i_gr != _mapGroups.end(); ++i_gr ) // groups
2023 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2026 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2027 for ( ; so != soToUpdateIcons.end(); ++so )
2028 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2031 //=============================================================================
2033 * \brief Create standalone group from a group on geometry or filter
2035 //=============================================================================
2037 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2038 throw (SALOME::SALOME_Exception)
2040 SMESH::SMESH_Group_var aGroup;
2045 _preMeshInfo->FullLoadFromFile();
2047 if ( theGroup->_is_nil() )
2048 return aGroup._retn();
2050 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2052 return aGroup._retn();
2054 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2056 const int anId = aGroupToRem->GetLocalID();
2057 if ( !_impl->ConvertToStandalone( anId ) )
2058 return aGroup._retn();
2059 removeGeomGroupData( theGroup );
2061 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2063 // remove old instance of group from own map
2064 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2065 _mapGroups.erase( anId );
2067 SALOMEDS::StudyBuilder_var builder;
2068 SALOMEDS::SObject_wrap aGroupSO;
2069 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2070 if ( !aStudy->_is_nil() ) {
2071 builder = aStudy->NewBuilder();
2072 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2073 if ( !aGroupSO->_is_nil() )
2075 // remove reference to geometry
2076 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2077 for ( ; chItr->More(); chItr->Next() )
2078 // Remove group's child SObject
2079 builder->RemoveObject( chItr->Value() );
2081 // Update Python script
2082 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2083 << ".ConvertToStandalone( " << aGroupSO << " )";
2085 // change icon of Group on Filter
2088 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2089 const int isEmpty = ( elemTypes->length() == 0 );
2092 SALOMEDS::GenericAttribute_wrap anAttr =
2093 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2094 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2095 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2101 // remember new group in own map
2102 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2103 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2105 // register CORBA object for persistence
2106 _gen_i->RegisterObject( aGroup );
2108 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2109 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2110 //aGroup->Register();
2111 aGroupToRem->UnRegister();
2113 SMESH_CATCH( SMESH::throwCorbaException );
2115 return aGroup._retn();
2118 //=============================================================================
2122 //=============================================================================
2124 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2126 if(MYDEBUG) MESSAGE( "createSubMesh" );
2127 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2128 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2129 const int subMeshId = mySubMesh->GetId();
2131 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2132 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2134 _mapSubMesh [subMeshId] = mySubMesh;
2135 _mapSubMesh_i [subMeshId] = subMeshServant;
2136 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2138 subMeshServant->Register();
2140 // register CORBA object for persistence
2141 int nextId = _gen_i->RegisterObject( subMesh );
2142 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2143 else { nextId = 0; } // avoid "unused variable" warning
2145 // to track changes of GEOM groups
2146 addGeomGroupData( theSubShapeObject, subMesh );
2148 return subMesh._retn();
2151 //=======================================================================
2152 //function : getSubMesh
2154 //=======================================================================
2156 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2158 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2159 if ( it == _mapSubMeshIor.end() )
2160 return SMESH::SMESH_subMesh::_nil();
2162 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2165 //=============================================================================
2169 //=============================================================================
2171 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2172 GEOM::GEOM_Object_ptr theSubShapeObject )
2174 bool isHypChanged = false;
2175 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2176 return isHypChanged;
2178 const int subMeshId = theSubMesh->GetId();
2180 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2182 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2184 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2187 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2188 isHypChanged = !hyps.empty();
2189 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2190 for ( ; hyp != hyps.end(); ++hyp )
2191 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2198 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2199 isHypChanged = ( aHypList->length() > 0 );
2200 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2201 removeHypothesis( theSubShapeObject, aHypList[i] );
2204 catch( const SALOME::SALOME_Exception& ) {
2205 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2207 removeGeomGroupData( theSubShapeObject );
2211 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2212 if ( id_smi != _mapSubMesh_i.end() )
2213 id_smi->second->UnRegister();
2215 // remove a CORBA object
2216 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2217 if ( id_smptr != _mapSubMeshIor.end() )
2218 SMESH::SMESH_subMesh_var( id_smptr->second );
2220 _mapSubMesh.erase(subMeshId);
2221 _mapSubMesh_i.erase(subMeshId);
2222 _mapSubMeshIor.erase(subMeshId);
2224 return isHypChanged;
2227 //=============================================================================
2231 //=============================================================================
2233 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2234 const char* theName,
2235 const TopoDS_Shape& theShape,
2236 const SMESH_PredicatePtr& thePredicate )
2238 std::string newName;
2239 if ( !theName || strlen( theName ) == 0 )
2241 std::set< std::string > presentNames;
2242 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2243 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2245 CORBA::String_var name = i_gr->second->GetName();
2246 presentNames.insert( name.in() );
2249 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2250 } while ( !presentNames.insert( newName ).second );
2251 theName = newName.c_str();
2254 SMESH::SMESH_GroupBase_var aGroup;
2255 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2257 SMESH_GroupBase_i* aGroupImpl;
2258 if ( !theShape.IsNull() )
2259 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2260 else if ( thePredicate )
2261 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2263 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2265 aGroup = aGroupImpl->_this();
2266 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2267 aGroupImpl->Register();
2269 // register CORBA object for persistence
2270 int nextId = _gen_i->RegisterObject( aGroup );
2271 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2272 else { nextId = 0; } // avoid "unused variable" warning in release mode
2274 // to track changes of GEOM groups
2275 if ( !theShape.IsNull() ) {
2276 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2277 addGeomGroupData( geom, aGroup );
2280 return aGroup._retn();
2283 //=============================================================================
2285 * SMESH_Mesh_i::removeGroup
2287 * Should be called by ~SMESH_Group_i()
2289 //=============================================================================
2291 void SMESH_Mesh_i::removeGroup( const int theId )
2293 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2294 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2295 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2296 _mapGroups.erase( theId );
2297 removeGeomGroupData( group );
2298 if ( !_impl->RemoveGroup( theId ))
2300 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2301 RemoveGroup( group );
2303 group->UnRegister();
2307 //=============================================================================
2311 //=============================================================================
2313 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2314 throw(SALOME::SALOME_Exception)
2316 SMESH::log_array_var aLog;
2320 _preMeshInfo->FullLoadFromFile();
2322 list < SMESHDS_Command * >logDS = _impl->GetLog();
2323 aLog = new SMESH::log_array;
2325 int lg = logDS.size();
2328 list < SMESHDS_Command * >::iterator its = logDS.begin();
2329 while(its != logDS.end()){
2330 SMESHDS_Command *com = *its;
2331 int comType = com->GetType();
2333 int lgcom = com->GetNumber();
2335 const list < int >&intList = com->GetIndexes();
2336 int inum = intList.size();
2338 list < int >::const_iterator ii = intList.begin();
2339 const list < double >&coordList = com->GetCoords();
2340 int rnum = coordList.size();
2342 list < double >::const_iterator ir = coordList.begin();
2343 aLog[indexLog].commandType = comType;
2344 aLog[indexLog].number = lgcom;
2345 aLog[indexLog].coords.length(rnum);
2346 aLog[indexLog].indexes.length(inum);
2347 for(int i = 0; i < rnum; i++){
2348 aLog[indexLog].coords[i] = *ir;
2349 //MESSAGE(" "<<i<<" "<<ir.Value());
2352 for(int i = 0; i < inum; i++){
2353 aLog[indexLog].indexes[i] = *ii;
2354 //MESSAGE(" "<<i<<" "<<ii.Value());
2363 SMESH_CATCH( SMESH::throwCorbaException );
2365 return aLog._retn();
2369 //=============================================================================
2373 //=============================================================================
2375 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2379 SMESH_CATCH( SMESH::throwCorbaException );
2382 //=============================================================================
2386 //=============================================================================
2388 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2393 //=============================================================================
2397 //=============================================================================
2399 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2404 //=============================================================================
2407 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2408 // issue 0020918: groups removal is caused by hyp modification
2409 // issue 0021208: to forget not loaded mesh data at hyp modification
2410 struct TCallUp_i : public SMESH_Mesh::TCallUp
2412 SMESH_Mesh_i* _mesh;
2413 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2414 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2415 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2416 virtual void Load () { _mesh->Load(); }
2420 //================================================================================
2422 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2424 //================================================================================
2426 void SMESH_Mesh_i::onHypothesisModified()
2429 _preMeshInfo->ForgetOrLoad();
2432 //=============================================================================
2436 //=============================================================================
2438 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2440 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2443 _impl->SetCallUp( new TCallUp_i(this));
2446 //=============================================================================
2450 //=============================================================================
2452 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2454 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2458 //=============================================================================
2460 * Return mesh editor
2462 //=============================================================================
2464 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2465 throw (SALOME::SALOME_Exception)
2467 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2471 _preMeshInfo->FullLoadFromFile();
2473 // Create MeshEditor
2475 _editor = new SMESH_MeshEditor_i( this, false );
2476 aMeshEdVar = _editor->_this();
2478 // Update Python script
2479 TPythonDump() << _editor << " = "
2480 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2482 SMESH_CATCH( SMESH::throwCorbaException );
2484 return aMeshEdVar._retn();
2487 //=============================================================================
2489 * Return mesh edition previewer
2491 //=============================================================================
2493 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2494 throw (SALOME::SALOME_Exception)
2496 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2500 _preMeshInfo->FullLoadFromFile();
2502 if ( !_previewEditor )
2503 _previewEditor = new SMESH_MeshEditor_i( this, true );
2504 aMeshEdVar = _previewEditor->_this();
2506 SMESH_CATCH( SMESH::throwCorbaException );
2508 return aMeshEdVar._retn();
2511 //================================================================================
2513 * \brief Return true if the mesh has been edited since a last total re-compute
2514 * and those modifications may prevent successful partial re-compute
2516 //================================================================================
2518 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2520 Unexpect aCatch(SALOME_SalomeException);
2521 return _impl->HasModificationsToDiscard();
2524 //================================================================================
2526 * \brief Returns a random unique color
2528 //================================================================================
2530 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2532 const int MAX_ATTEMPTS = 100;
2534 double tolerance = 0.5;
2535 SALOMEDS::Color col;
2539 // generate random color
2540 double red = (double)rand() / RAND_MAX;
2541 double green = (double)rand() / RAND_MAX;
2542 double blue = (double)rand() / RAND_MAX;
2543 // check existence in the list of the existing colors
2544 bool matched = false;
2545 std::list<SALOMEDS::Color>::const_iterator it;
2546 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2547 SALOMEDS::Color color = *it;
2548 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2549 matched = tol < tolerance;
2551 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2552 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2560 //=============================================================================
2562 * Sets auto-color mode. If it is on, groups get unique random colors
2564 //=============================================================================
2566 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2568 Unexpect aCatch(SALOME_SalomeException);
2569 _impl->SetAutoColor(theAutoColor);
2571 TPythonDump pyDump; // not to dump group->SetColor() from below code
2572 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2574 std::list<SALOMEDS::Color> aReservedColors;
2575 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2576 for ( ; it != _mapGroups.end(); it++ ) {
2577 if ( CORBA::is_nil( it->second )) continue;
2578 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2579 it->second->SetColor( aColor );
2580 aReservedColors.push_back( aColor );
2584 //=============================================================================
2586 * Returns true if auto-color mode is on
2588 //=============================================================================
2590 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2592 Unexpect aCatch(SALOME_SalomeException);
2593 return _impl->GetAutoColor();
2596 //=============================================================================
2598 * Checks if there are groups with equal names
2600 //=============================================================================
2602 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2604 return _impl->HasDuplicatedGroupNamesMED();
2607 //================================================================================
2609 * \brief Care of a file before exporting mesh into it
2611 //================================================================================
2613 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2615 TCollection_AsciiString aFullName ((char*)file);
2616 OSD_Path aPath (aFullName);
2617 OSD_File aFile (aPath);
2618 if (aFile.Exists()) {
2619 // existing filesystem node
2620 if (aFile.KindOfFile() == OSD_FILE) {
2621 if (aFile.IsWriteable()) {
2626 if (aFile.Failed()) {
2627 TCollection_AsciiString msg ("File ");
2628 msg += aFullName + " cannot be replaced.";
2629 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2632 TCollection_AsciiString msg ("File ");
2633 msg += aFullName + " cannot be overwritten.";
2634 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2637 TCollection_AsciiString msg ("Location ");
2638 msg += aFullName + " is not a file.";
2639 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2642 // nonexisting file; check if it can be created
2644 aFile.Build(OSD_WriteOnly, OSD_Protection());
2645 if (aFile.Failed()) {
2646 TCollection_AsciiString msg ("You cannot create the file ");
2647 msg += aFullName + ". Check the directory existance and access rights.";
2648 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2656 //================================================================================
2658 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2659 * \param file - file name
2660 * \param overwrite - to erase the file or not
2661 * \retval string - mesh name
2663 //================================================================================
2665 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2666 CORBA::Boolean overwrite)
2669 PrepareForWriting(file, overwrite);
2670 string aMeshName = "Mesh";
2671 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2672 if ( !aStudy->_is_nil() ) {
2673 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2674 if ( !aMeshSO->_is_nil() ) {
2675 CORBA::String_var name = aMeshSO->GetName();
2677 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2678 if ( !aStudy->GetProperties()->IsLocked() )
2680 SALOMEDS::GenericAttribute_wrap anAttr;
2681 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2682 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2683 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2684 ASSERT(!aFileName->_is_nil());
2685 aFileName->SetValue(file);
2686 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2687 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2688 ASSERT(!aFileType->_is_nil());
2689 aFileType->SetValue("FICHIERMED");
2693 // Update Python script
2694 // set name of mesh before export
2695 TPythonDump() << _gen_i << ".SetName("
2696 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2698 // check names of groups
2704 //================================================================================
2706 * \brief Export to med file
2708 //================================================================================
2710 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2711 CORBA::Boolean auto_groups,
2712 SMESH::MED_VERSION theVersion,
2713 CORBA::Boolean overwrite,
2714 CORBA::Boolean autoDimension)
2715 throw(SALOME::SALOME_Exception)
2719 _preMeshInfo->FullLoadFromFile();
2721 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2722 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2723 << file << "', " << auto_groups << ", "
2724 << theVersion << ", " << overwrite << ", "
2725 << autoDimension << " )";
2727 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2729 SMESH_CATCH( SMESH::throwCorbaException );
2732 //================================================================================
2734 * \brief Export a mesh to a med file
2736 //================================================================================
2738 void SMESH_Mesh_i::ExportToMED (const char* file,
2739 CORBA::Boolean auto_groups,
2740 SMESH::MED_VERSION theVersion)
2741 throw(SALOME::SALOME_Exception)
2743 ExportToMEDX(file,auto_groups,theVersion,true);
2746 //================================================================================
2748 * \brief Export a mesh to a med file
2750 //================================================================================
2752 void SMESH_Mesh_i::ExportMED (const char* file,
2753 CORBA::Boolean auto_groups)
2754 throw(SALOME::SALOME_Exception)
2756 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2759 //================================================================================
2761 * \brief Export a mesh to a SAUV file
2763 //================================================================================
2765 void SMESH_Mesh_i::ExportSAUV (const char* file,
2766 CORBA::Boolean auto_groups)
2767 throw(SALOME::SALOME_Exception)
2769 Unexpect aCatch(SALOME_SalomeException);
2771 _preMeshInfo->FullLoadFromFile();
2773 string aMeshName = prepareMeshNameAndGroups(file, true);
2774 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2775 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2776 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2780 //================================================================================
2782 * \brief Export a mesh to a DAT file
2784 //================================================================================
2786 void SMESH_Mesh_i::ExportDAT (const char *file)
2787 throw(SALOME::SALOME_Exception)
2789 Unexpect aCatch(SALOME_SalomeException);
2791 _preMeshInfo->FullLoadFromFile();
2793 // Update Python script
2794 // check names of groups
2796 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2799 PrepareForWriting(file);
2800 _impl->ExportDAT(file);
2803 //================================================================================
2805 * \brief Export a mesh to an UNV file
2807 //================================================================================
2809 void SMESH_Mesh_i::ExportUNV (const char *file)
2810 throw(SALOME::SALOME_Exception)
2812 Unexpect aCatch(SALOME_SalomeException);
2814 _preMeshInfo->FullLoadFromFile();
2816 // Update Python script
2817 // check names of groups
2819 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2822 PrepareForWriting(file);
2823 _impl->ExportUNV(file);
2826 //================================================================================
2828 * \brief Export a mesh to an STL file
2830 //================================================================================
2832 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2833 throw(SALOME::SALOME_Exception)
2835 Unexpect aCatch(SALOME_SalomeException);
2837 _preMeshInfo->FullLoadFromFile();
2839 // Update Python script
2840 // check names of groups
2842 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2843 << ".ExportSTL( r'" << file << "', " << isascii << " )";
2846 PrepareForWriting(file);
2847 _impl->ExportSTL(file, isascii);
2850 //================================================================================
2852 * \brief Export a part of mesh to a med file
2854 //================================================================================
2856 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2858 CORBA::Boolean auto_groups,
2859 ::SMESH::MED_VERSION version,
2860 ::CORBA::Boolean overwrite,
2861 ::CORBA::Boolean autoDimension)
2862 throw (SALOME::SALOME_Exception)
2864 Unexpect aCatch(SALOME_SalomeException);
2867 if ( SMESH_Mesh_i * mesh = SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
2869 mesh->ExportToMEDX( file, auto_groups, version, autoDimension );
2874 _preMeshInfo->FullLoadFromFile();
2876 PrepareForWriting(file, overwrite);
2878 string aMeshName = "Mesh";
2879 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2880 if ( !aStudy->_is_nil() ) {
2881 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2882 if ( !SO->_is_nil() ) {
2883 CORBA::String_var name = SO->GetName();
2887 SMESH_MeshPartDS partDS( meshPart );
2888 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS, autoDimension );
2890 pyDump << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToMED( "
2891 << meshPart << ", r'" << file << "', "
2892 << auto_groups << ", " << version << ", " << overwrite << ", "
2893 << autoDimension << " )";
2896 //================================================================================
2898 * \brief Export a part of mesh to a DAT file
2900 //================================================================================
2902 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2904 throw (SALOME::SALOME_Exception)
2906 Unexpect aCatch(SALOME_SalomeException);
2908 _preMeshInfo->FullLoadFromFile();
2910 PrepareForWriting(file);
2912 SMESH_MeshPartDS partDS( meshPart );
2913 _impl->ExportDAT(file,&partDS);
2915 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2916 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2918 //================================================================================
2920 * \brief Export a part of mesh to an UNV file
2922 //================================================================================
2924 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2926 throw (SALOME::SALOME_Exception)
2928 Unexpect aCatch(SALOME_SalomeException);
2930 _preMeshInfo->FullLoadFromFile();
2932 PrepareForWriting(file);
2934 SMESH_MeshPartDS partDS( meshPart );
2935 _impl->ExportUNV(file, &partDS);
2937 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2938 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2940 //================================================================================
2942 * \brief Export a part of mesh to an STL file
2944 //================================================================================
2946 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2948 ::CORBA::Boolean isascii)
2949 throw (SALOME::SALOME_Exception)
2951 Unexpect aCatch(SALOME_SalomeException);
2953 _preMeshInfo->FullLoadFromFile();
2955 PrepareForWriting(file);
2957 SMESH_MeshPartDS partDS( meshPart );
2958 _impl->ExportSTL(file, isascii, &partDS);
2960 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
2961 << meshPart<< ", r'" << file << "', " << isascii << ")";
2964 //================================================================================
2966 * \brief Export a part of mesh to an STL file
2968 //================================================================================
2970 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2972 CORBA::Boolean overwrite)
2973 throw (SALOME::SALOME_Exception)
2976 Unexpect aCatch(SALOME_SalomeException);
2978 _preMeshInfo->FullLoadFromFile();
2980 PrepareForWriting(file,overwrite);
2982 SMESH_MeshPartDS partDS( meshPart );
2983 _impl->ExportCGNS(file, &partDS);
2985 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
2986 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2988 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2992 //================================================================================
2994 * \brief Export a part of mesh to a GMF file
2996 //================================================================================
2998 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3000 bool withRequiredGroups)
3001 throw (SALOME::SALOME_Exception)
3003 Unexpect aCatch(SALOME_SalomeException);
3005 _preMeshInfo->FullLoadFromFile();
3007 PrepareForWriting(file,/*overwrite=*/true);
3009 SMESH_MeshPartDS partDS( meshPart );
3010 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3012 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3013 << meshPart<< ", r'"
3015 << withRequiredGroups << ")";
3018 //=============================================================================
3020 * Return computation progress [0.,1]
3022 //=============================================================================
3024 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3028 return _impl->GetComputeProgress();
3030 SMESH_CATCH( SMESH::doNothing );
3034 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3036 Unexpect aCatch(SALOME_SalomeException);
3038 return _preMeshInfo->NbNodes();
3040 return _impl->NbNodes();
3043 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3045 Unexpect aCatch(SALOME_SalomeException);
3047 return _preMeshInfo->NbElements();
3049 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3052 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3054 Unexpect aCatch(SALOME_SalomeException);
3056 return _preMeshInfo->Nb0DElements();
3058 return _impl->Nb0DElements();
3061 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3063 Unexpect aCatch(SALOME_SalomeException);
3065 return _preMeshInfo->NbBalls();
3067 return _impl->NbBalls();
3070 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3072 Unexpect aCatch(SALOME_SalomeException);
3074 return _preMeshInfo->NbEdges();
3076 return _impl->NbEdges();
3079 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3080 throw(SALOME::SALOME_Exception)
3082 Unexpect aCatch(SALOME_SalomeException);
3084 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3086 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3089 //=============================================================================
3091 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3093 Unexpect aCatch(SALOME_SalomeException);
3095 return _preMeshInfo->NbFaces();
3097 return _impl->NbFaces();
3100 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3102 Unexpect aCatch(SALOME_SalomeException);
3104 return _preMeshInfo->NbTriangles();
3106 return _impl->NbTriangles();
3109 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3111 Unexpect aCatch(SALOME_SalomeException);
3113 return _preMeshInfo->NbBiQuadTriangles();
3115 return _impl->NbBiQuadTriangles();
3118 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3120 Unexpect aCatch(SALOME_SalomeException);
3122 return _preMeshInfo->NbQuadrangles();
3124 return _impl->NbQuadrangles();
3127 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3129 Unexpect aCatch(SALOME_SalomeException);
3131 return _preMeshInfo->NbBiQuadQuadrangles();
3133 return _impl->NbBiQuadQuadrangles();
3136 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3138 Unexpect aCatch(SALOME_SalomeException);
3140 return _preMeshInfo->NbPolygons();
3142 return _impl->NbPolygons();
3145 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3146 throw(SALOME::SALOME_Exception)
3148 Unexpect aCatch(SALOME_SalomeException);
3150 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3152 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3155 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3156 throw(SALOME::SALOME_Exception)
3158 Unexpect aCatch(SALOME_SalomeException);
3160 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3162 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3165 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3166 throw(SALOME::SALOME_Exception)
3168 Unexpect aCatch(SALOME_SalomeException);
3170 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3172 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3175 //=============================================================================
3177 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3179 Unexpect aCatch(SALOME_SalomeException);
3181 return _preMeshInfo->NbVolumes();
3183 return _impl->NbVolumes();
3186 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3188 Unexpect aCatch(SALOME_SalomeException);
3190 return _preMeshInfo->NbTetras();
3192 return _impl->NbTetras();
3195 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3197 Unexpect aCatch(SALOME_SalomeException);
3199 return _preMeshInfo->NbHexas();
3201 return _impl->NbHexas();
3204 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3206 Unexpect aCatch(SALOME_SalomeException);
3208 return _preMeshInfo->NbTriQuadHexas();
3210 return _impl->NbTriQuadraticHexas();
3213 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3215 Unexpect aCatch(SALOME_SalomeException);
3217 return _preMeshInfo->NbPyramids();
3219 return _impl->NbPyramids();
3222 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3224 Unexpect aCatch(SALOME_SalomeException);
3226 return _preMeshInfo->NbPrisms();
3228 return _impl->NbPrisms();
3231 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3233 Unexpect aCatch(SALOME_SalomeException);
3235 return _preMeshInfo->NbHexPrisms();
3237 return _impl->NbHexagonalPrisms();
3240 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3242 Unexpect aCatch(SALOME_SalomeException);
3244 return _preMeshInfo->NbPolyhedrons();
3246 return _impl->NbPolyhedrons();
3249 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3250 throw(SALOME::SALOME_Exception)
3252 Unexpect aCatch(SALOME_SalomeException);
3254 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3256 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3259 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3260 throw(SALOME::SALOME_Exception)
3262 Unexpect aCatch(SALOME_SalomeException);
3264 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3266 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3269 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3270 throw(SALOME::SALOME_Exception)
3272 Unexpect aCatch(SALOME_SalomeException);
3274 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3276 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3279 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3280 throw(SALOME::SALOME_Exception)
3282 Unexpect aCatch(SALOME_SalomeException);
3284 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3286 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3289 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3290 throw(SALOME::SALOME_Exception)
3292 Unexpect aCatch(SALOME_SalomeException);
3294 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3296 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3299 //=============================================================================
3301 * Returns nb of published sub-meshes
3303 //=============================================================================
3305 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3307 Unexpect aCatch(SALOME_SalomeException);
3308 return _mapSubMesh_i.size();
3311 //=============================================================================
3313 * Dumps mesh into a string
3315 //=============================================================================
3317 char* SMESH_Mesh_i::Dump()
3321 return CORBA::string_dup( os.str().c_str() );
3324 //=============================================================================
3326 * Method of SMESH_IDSource interface
3328 //=============================================================================
3330 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3332 return GetElementsId();
3335 //=============================================================================
3337 * Returns ids of all elements
3339 //=============================================================================
3341 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3342 throw (SALOME::SALOME_Exception)
3344 Unexpect aCatch(SALOME_SalomeException);
3346 _preMeshInfo->FullLoadFromFile();
3348 SMESH::long_array_var aResult = new SMESH::long_array();
3349 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3351 if ( aSMESHDS_Mesh == NULL )
3352 return aResult._retn();
3354 long nbElements = NbElements();
3355 aResult->length( nbElements );
3356 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3357 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3358 aResult[i] = anIt->next()->GetID();
3360 return aResult._retn();
3364 //=============================================================================
3366 * Returns ids of all elements of given type
3368 //=============================================================================
3370 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3371 throw (SALOME::SALOME_Exception)
3373 Unexpect aCatch(SALOME_SalomeException);
3375 _preMeshInfo->FullLoadFromFile();
3377 SMESH::long_array_var aResult = new SMESH::long_array();
3378 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3380 if ( aSMESHDS_Mesh == NULL )
3381 return aResult._retn();
3383 long nbElements = NbElements();
3385 // No sense in returning ids of elements along with ids of nodes:
3386 // when theElemType == SMESH::ALL, return node ids only if
3387 // there are no elements
3388 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3389 return GetNodesId();
3391 aResult->length( nbElements );
3395 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3396 while ( i < nbElements && anIt->more() )
3397 aResult[i++] = anIt->next()->GetID();
3399 aResult->length( i );
3401 return aResult._retn();
3404 //=============================================================================
3406 * Returns ids of all nodes
3408 //=============================================================================
3410 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3411 throw (SALOME::SALOME_Exception)
3413 Unexpect aCatch(SALOME_SalomeException);
3415 _preMeshInfo->FullLoadFromFile();
3417 SMESH::long_array_var aResult = new SMESH::long_array();
3418 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3420 if ( aSMESHDS_Mesh == NULL )
3421 return aResult._retn();
3423 long nbNodes = NbNodes();
3424 aResult->length( nbNodes );
3425 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3426 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3427 aResult[i] = anIt->next()->GetID();
3429 return aResult._retn();
3432 //=============================================================================
3436 //=============================================================================
3438 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3439 throw (SALOME::SALOME_Exception)
3441 SMESH::ElementType type;
3445 _preMeshInfo->FullLoadFromFile();
3447 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3449 SMESH_CATCH( SMESH::throwCorbaException );
3454 //=============================================================================
3458 //=============================================================================
3460 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3461 throw (SALOME::SALOME_Exception)
3464 _preMeshInfo->FullLoadFromFile();
3466 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3468 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3470 return ( SMESH::EntityType ) e->GetEntityType();
3473 //=============================================================================
3477 //=============================================================================
3479 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3480 throw (SALOME::SALOME_Exception)
3483 _preMeshInfo->FullLoadFromFile();
3485 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3487 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3489 return ( SMESH::GeometryType ) e->GetGeomType();
3492 //=============================================================================
3494 * Returns ID of elements for given submesh
3496 //=============================================================================
3497 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3498 throw (SALOME::SALOME_Exception)
3500 SMESH::long_array_var aResult = new SMESH::long_array();
3504 _preMeshInfo->FullLoadFromFile();
3506 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3507 if(!SM) return aResult._retn();
3509 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3510 if(!SDSM) return aResult._retn();
3512 aResult->length(SDSM->NbElements());
3514 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3516 while ( eIt->more() ) {
3517 aResult[i++] = eIt->next()->GetID();
3520 SMESH_CATCH( SMESH::throwCorbaException );
3522 return aResult._retn();
3525 //=============================================================================
3527 * Returns ID of nodes for given submesh
3528 * If param all==true - returns all nodes, else -
3529 * returns only nodes on shapes.
3531 //=============================================================================
3533 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3535 throw (SALOME::SALOME_Exception)
3537 SMESH::long_array_var aResult = new SMESH::long_array();
3541 _preMeshInfo->FullLoadFromFile();
3543 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3544 if(!SM) return aResult._retn();
3546 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3547 if(!SDSM) return aResult._retn();
3550 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3551 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3552 while ( nIt->more() ) {
3553 const SMDS_MeshNode* elem = nIt->next();
3554 theElems.insert( elem->GetID() );
3557 else { // all nodes of submesh elements
3558 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3559 while ( eIt->more() ) {
3560 const SMDS_MeshElement* anElem = eIt->next();
3561 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3562 while ( nIt->more() ) {
3563 const SMDS_MeshElement* elem = nIt->next();
3564 theElems.insert( elem->GetID() );
3569 aResult->length(theElems.size());
3570 set<int>::iterator itElem;
3572 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3573 aResult[i++] = *itElem;
3575 SMESH_CATCH( SMESH::throwCorbaException );
3577 return aResult._retn();
3580 //=============================================================================
3582 * Returns type of elements for given submesh
3584 //=============================================================================
3586 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3587 throw (SALOME::SALOME_Exception)
3589 SMESH::ElementType type;
3593 _preMeshInfo->FullLoadFromFile();
3595 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3596 if(!SM) return SMESH::ALL;
3598 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3599 if(!SDSM) return SMESH::ALL;
3601 if(SDSM->NbElements()==0)
3602 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3604 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3605 const SMDS_MeshElement* anElem = eIt->next();
3607 type = ( SMESH::ElementType ) anElem->GetType();
3609 SMESH_CATCH( SMESH::throwCorbaException );
3615 //=============================================================================
3617 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3619 //=============================================================================
3621 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3624 _preMeshInfo->FullLoadFromFile();
3626 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3628 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3633 //=============================================================================
3635 * Get XYZ coordinates of node as list of double
3636 * If there is not node for given ID - returns empty list
3638 //=============================================================================
3640 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3643 _preMeshInfo->FullLoadFromFile();
3645 SMESH::double_array_var aResult = new SMESH::double_array();
3646 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3647 if ( aSMESHDS_Mesh == NULL )
3648 return aResult._retn();
3651 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3653 return aResult._retn();
3657 aResult[0] = aNode->X();
3658 aResult[1] = aNode->Y();
3659 aResult[2] = aNode->Z();
3660 return aResult._retn();
3664 //=============================================================================
3666 * For given node returns list of IDs of inverse elements
3667 * If there is not node for given ID - returns empty list
3669 //=============================================================================
3671 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3674 _preMeshInfo->FullLoadFromFile();
3676 SMESH::long_array_var aResult = new SMESH::long_array();
3677 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3678 if ( aSMESHDS_Mesh == NULL )
3679 return aResult._retn();
3682 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3684 return aResult._retn();
3686 // find inverse elements
3687 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3688 TColStd_SequenceOfInteger IDs;
3689 while(eIt->more()) {
3690 const SMDS_MeshElement* elem = eIt->next();
3691 IDs.Append(elem->GetID());
3693 if(IDs.Length()>0) {
3694 aResult->length(IDs.Length());
3696 for(; i<=IDs.Length(); i++) {
3697 aResult[i-1] = IDs.Value(i);
3700 return aResult._retn();
3703 //=============================================================================
3705 * \brief Return position of a node on shape
3707 //=============================================================================
3709 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3712 _preMeshInfo->FullLoadFromFile();
3714 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3715 aNodePosition->shapeID = 0;
3716 aNodePosition->shapeType = GEOM::SHAPE;
3718 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3719 if ( !mesh ) return aNodePosition;
3721 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3723 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3725 aNodePosition->shapeID = aNode->getshapeId();
3726 switch ( pos->GetTypeOfPosition() ) {
3728 aNodePosition->shapeType = GEOM::EDGE;
3729 aNodePosition->params.length(1);
3730 aNodePosition->params[0] =
3731 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3734 aNodePosition->shapeType = GEOM::FACE;
3735 aNodePosition->params.length(2);
3736 aNodePosition->params[0] =
3737 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3738 aNodePosition->params[1] =
3739 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3741 case SMDS_TOP_VERTEX:
3742 aNodePosition->shapeType = GEOM::VERTEX;
3744 case SMDS_TOP_3DSPACE:
3745 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3746 aNodePosition->shapeType = GEOM::SOLID;
3747 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3748 aNodePosition->shapeType = GEOM::SHELL;
3754 return aNodePosition;
3757 //=============================================================================
3759 * \brief Return position of an element on shape
3761 //=============================================================================
3763 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
3766 _preMeshInfo->FullLoadFromFile();
3768 SMESH::ElementPosition anElementPosition;
3769 anElementPosition.shapeID = 0;
3770 anElementPosition.shapeType = GEOM::SHAPE;
3772 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3773 if ( !mesh ) return anElementPosition;
3775 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
3777 anElementPosition.shapeID = anElem->getshapeId();
3778 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
3779 if ( !aSp.IsNull() ) {
3780 switch ( aSp.ShapeType() ) {
3782 anElementPosition.shapeType = GEOM::EDGE;
3785 anElementPosition.shapeType = GEOM::FACE;
3788 anElementPosition.shapeType = GEOM::VERTEX;
3791 anElementPosition.shapeType = GEOM::SOLID;
3794 anElementPosition.shapeType = GEOM::SHELL;
3800 return anElementPosition;
3803 //=============================================================================
3805 * If given element is node returns IDs of shape from position
3806 * If there is not node for given ID - returns -1
3808 //=============================================================================
3810 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3813 _preMeshInfo->FullLoadFromFile();
3815 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3816 if ( aSMESHDS_Mesh == NULL )
3820 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3822 return aNode->getshapeId();
3829 //=============================================================================
3831 * For given element returns ID of result shape after
3832 * ::FindShape() from SMESH_MeshEditor
3833 * If there is not element for given ID - returns -1
3835 //=============================================================================
3837 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3840 _preMeshInfo->FullLoadFromFile();
3842 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3843 if ( aSMESHDS_Mesh == NULL )
3846 // try to find element
3847 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3851 ::SMESH_MeshEditor aMeshEditor(_impl);
3852 int index = aMeshEditor.FindShape( elem );
3860 //=============================================================================
3862 * Returns number of nodes for given element
3863 * If there is not element for given ID - returns -1
3865 //=============================================================================
3867 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3870 _preMeshInfo->FullLoadFromFile();
3872 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3873 if ( aSMESHDS_Mesh == NULL ) return -1;
3874 // try to find element
3875 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3876 if(!elem) return -1;
3877 return elem->NbNodes();
3881 //=============================================================================
3883 * Returns ID of node by given index for given element
3884 * If there is not element for given ID - returns -1
3885 * If there is not node for given index - returns -2
3887 //=============================================================================
3889 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3892 _preMeshInfo->FullLoadFromFile();
3894 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3895 if ( aSMESHDS_Mesh == NULL ) return -1;
3896 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3897 if(!elem) return -1;
3898 if( index>=elem->NbNodes() || index<0 ) return -1;
3899 return elem->GetNode(index)->GetID();
3902 //=============================================================================
3904 * Returns IDs of nodes of given element
3906 //=============================================================================
3908 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3911 _preMeshInfo->FullLoadFromFile();
3913 SMESH::long_array_var aResult = new SMESH::long_array();
3914 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3916 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3918 aResult->length( elem->NbNodes() );
3919 for ( int i = 0; i < elem->NbNodes(); ++i )
3920 aResult[ i ] = elem->GetNode( i )->GetID();
3923 return aResult._retn();
3926 //=============================================================================
3928 * Returns true if given node is medium node
3929 * in given quadratic element
3931 //=============================================================================
3933 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3936 _preMeshInfo->FullLoadFromFile();
3938 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3939 if ( aSMESHDS_Mesh == NULL ) return false;
3941 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3942 if(!aNode) return false;
3943 // try to find element
3944 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3945 if(!elem) return false;
3947 return elem->IsMediumNode(aNode);
3951 //=============================================================================
3953 * Returns true if given node is medium node
3954 * in one of quadratic elements
3956 //=============================================================================
3958 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3959 SMESH::ElementType theElemType)
3962 _preMeshInfo->FullLoadFromFile();
3964 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3965 if ( aSMESHDS_Mesh == NULL ) return false;
3968 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3969 if(!aNode) return false;
3971 SMESH_MesherHelper aHelper( *(_impl) );
3973 SMDSAbs_ElementType aType;
3974 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3975 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3976 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3977 else aType = SMDSAbs_All;
3979 return aHelper.IsMedium(aNode,aType);
3983 //=============================================================================
3985 * Returns number of edges for given element
3987 //=============================================================================
3989 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3992 _preMeshInfo->FullLoadFromFile();
3994 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3995 if ( aSMESHDS_Mesh == NULL ) return -1;
3996 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3997 if(!elem) return -1;
3998 return elem->NbEdges();
4002 //=============================================================================
4004 * Returns number of faces for given element
4006 //=============================================================================
4008 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4011 _preMeshInfo->FullLoadFromFile();
4013 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4014 if ( aSMESHDS_Mesh == NULL ) return -1;
4015 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4016 if(!elem) return -1;
4017 return elem->NbFaces();
4020 //=======================================================================
4021 //function : GetElemFaceNodes
4022 //purpose : Returns nodes of given face (counted from zero) for given element.
4023 //=======================================================================
4025 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4026 CORBA::Short faceIndex)
4029 _preMeshInfo->FullLoadFromFile();
4031 SMESH::long_array_var aResult = new SMESH::long_array();
4032 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4034 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4036 SMDS_VolumeTool vtool( elem );
4037 if ( faceIndex < vtool.NbFaces() )
4039 aResult->length( vtool.NbFaceNodes( faceIndex ));
4040 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4041 for ( int i = 0; i < aResult->length(); ++i )
4042 aResult[ i ] = nn[ i ]->GetID();
4046 return aResult._retn();
4049 //=======================================================================
4050 //function : GetElemFaceNodes
4051 //purpose : Returns three components of normal of given mesh face.
4052 //=======================================================================
4054 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4055 CORBA::Boolean normalized)
4058 _preMeshInfo->FullLoadFromFile();
4060 SMESH::double_array_var aResult = new SMESH::double_array();
4062 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4065 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4067 aResult->length( 3 );
4068 aResult[ 0 ] = normal.X();
4069 aResult[ 1 ] = normal.Y();
4070 aResult[ 2 ] = normal.Z();
4073 return aResult._retn();
4076 //=======================================================================
4077 //function : FindElementByNodes
4078 //purpose : Returns an element based on all given nodes.
4079 //=======================================================================
4081 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4084 _preMeshInfo->FullLoadFromFile();
4086 CORBA::Long elemID(0);
4087 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4089 vector< const SMDS_MeshNode * > nn( nodes.length() );
4090 for ( int i = 0; i < nodes.length(); ++i )
4091 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4094 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4095 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4096 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4097 _impl->NbVolumes( ORDER_QUADRATIC )))
4098 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4100 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4105 //=============================================================================
4107 * Returns true if given element is polygon
4109 //=============================================================================
4111 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4114 _preMeshInfo->FullLoadFromFile();
4116 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4117 if ( aSMESHDS_Mesh == NULL ) return false;
4118 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4119 if(!elem) return false;
4120 return elem->IsPoly();
4124 //=============================================================================
4126 * Returns true if given element is quadratic
4128 //=============================================================================
4130 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4133 _preMeshInfo->FullLoadFromFile();
4135 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4136 if ( aSMESHDS_Mesh == NULL ) return false;
4137 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4138 if(!elem) return false;
4139 return elem->IsQuadratic();
4142 //=============================================================================
4144 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4146 //=============================================================================
4148 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4151 _preMeshInfo->FullLoadFromFile();
4153 if ( const SMDS_BallElement* ball =
4154 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4155 return ball->GetDiameter();
4160 //=============================================================================
4162 * Returns bary center for given element
4164 //=============================================================================
4166 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4169 _preMeshInfo->FullLoadFromFile();
4171 SMESH::double_array_var aResult = new SMESH::double_array();
4172 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4173 if ( aSMESHDS_Mesh == NULL )
4174 return aResult._retn();
4176 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4178 return aResult._retn();
4180 if(elem->GetType()==SMDSAbs_Volume) {
4181 SMDS_VolumeTool aTool;
4182 if(aTool.Set(elem)) {
4184 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4189 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4191 double x=0., y=0., z=0.;
4192 for(; anIt->more(); ) {
4194 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4208 return aResult._retn();
4211 //================================================================================
4213 * \brief Create a group of elements preventing computation of a sub-shape
4215 //================================================================================
4217 SMESH::ListOfGroups*
4218 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4219 const char* theGroupName )
4220 throw ( SALOME::SALOME_Exception )
4222 Unexpect aCatch(SALOME_SalomeException);
4224 if ( !theGroupName || strlen( theGroupName) == 0 )
4225 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4227 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4229 // submesh by subshape id
4230 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4231 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4234 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4235 if ( error && !error->myBadElements.empty())
4237 // sort bad elements by type
4238 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4239 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4240 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4241 for ( ; elemIt != elemEnd; ++elemIt )
4243 const SMDS_MeshElement* elem = *elemIt;
4244 if ( !elem ) continue;
4246 if ( elem->GetID() < 1 )
4248 // elem is a temporary element, make a real element
4249 vector< const SMDS_MeshNode* > nodes;
4250 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4251 while ( nIt->more() && elem )
4253 nodes.push_back( nIt->next() );
4254 if ( nodes.back()->GetID() < 1 )
4255 elem = 0; // a temporary element on temporary nodes
4259 ::SMESH_MeshEditor editor( _impl );
4260 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4264 elemsByType[ elem->GetType() ].push_back( elem );
4267 // how many groups to create?
4269 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4270 nbTypes += int( !elemsByType[ i ].empty() );
4271 groups->length( nbTypes );
4274 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4276 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4277 if ( elems.empty() ) continue;
4279 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4280 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4282 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4283 SMESH::SMESH_Mesh_var mesh = _this();
4284 SALOMEDS::SObject_wrap aSO =
4285 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4286 GEOM::GEOM_Object::_nil(), theGroupName);
4287 aSO->_is_nil(); // avoid "unused variable" warning
4289 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4290 if ( !grp_i ) continue;
4292 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4293 for ( size_t iE = 0; iE < elems.size(); ++iE )
4294 grpDS->SMDSGroup().Add( elems[ iE ]);
4299 return groups._retn();
4302 //=============================================================================
4304 * Create and publish group servants if any groups were imported or created anyhow
4306 //=============================================================================
4308 void SMESH_Mesh_i::CreateGroupServants()
4310 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4311 SMESH::SMESH_Mesh_var aMesh = _this();
4314 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4315 while ( groupIt->more() )
4317 ::SMESH_Group* group = groupIt->next();
4318 int anId = group->GetGroupDS()->GetID();
4320 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4321 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4323 addedIDs.insert( anId );
4325 SMESH_GroupBase_i* aGroupImpl;
4327 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4328 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4330 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4331 shape = groupOnGeom->GetShape();
4334 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4337 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4338 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4339 aGroupImpl->Register();
4341 // register CORBA object for persistence
4342 int nextId = _gen_i->RegisterObject( groupVar );
4343 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4344 else { nextId = 0; } // avoid "unused variable" warning in release mode
4346 // publishing the groups in the study
4347 if ( !aStudy->_is_nil() ) {
4348 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4349 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4352 if ( !addedIDs.empty() )
4355 set<int>::iterator id = addedIDs.begin();
4356 for ( ; id != addedIDs.end(); ++id )
4358 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4359 int i = std::distance( _mapGroups.begin(), it );
4360 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4365 //=============================================================================
4367 * \brief Return groups cantained in _mapGroups by their IDs
4369 //=============================================================================
4371 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4373 int nbGroups = groupIDs.size();
4374 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4375 aList->length( nbGroups );
4377 list<int>::const_iterator ids = groupIDs.begin();
4378 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4380 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4381 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4382 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4384 aList->length( nbGroups );
4385 return aList._retn();
4388 //=============================================================================
4390 * \brief Return information about imported file
4392 //=============================================================================
4394 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4396 SMESH::MedFileInfo_var res( _medFileInfo );
4397 if ( !res.operator->() ) {
4398 res = new SMESH::MedFileInfo;
4400 res->fileSize = res->major = res->minor = res->release = -1;
4405 //=============================================================================
4407 * \brief Pass names of mesh groups from study to mesh DS
4409 //=============================================================================
4411 void SMESH_Mesh_i::checkGroupNames()
4413 int nbGrp = NbGroups();
4417 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4418 if ( aStudy->_is_nil() )
4419 return; // nothing to do
4421 SMESH::ListOfGroups* grpList = 0;
4422 // avoid dump of "GetGroups"
4424 // store python dump into a local variable inside local scope
4425 SMESH::TPythonDump pDump; // do not delete this line of code
4426 grpList = GetGroups();
4429 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4430 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4433 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4434 if ( aGrpSO->_is_nil() )
4436 // correct name of the mesh group if necessary
4437 const char* guiName = aGrpSO->GetName();
4438 if ( strcmp(guiName, aGrp->GetName()) )
4439 aGrp->SetName( guiName );
4443 //=============================================================================
4445 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4447 //=============================================================================
4448 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4450 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4454 //=============================================================================
4456 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4458 //=============================================================================
4460 char* SMESH_Mesh_i::GetParameters()
4462 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4465 //=============================================================================
4467 * \brief Returns list of notebook variables used for last Mesh operation
4469 //=============================================================================
4470 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4472 SMESH::string_array_var aResult = new SMESH::string_array();
4473 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4475 CORBA::String_var aParameters = GetParameters();
4476 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4477 if ( !aStudy->_is_nil()) {
4478 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4479 if(aSections->length() > 0) {
4480 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4481 aResult->length(aVars.length());
4482 for(int i = 0;i < aVars.length();i++)
4483 aResult[i] = CORBA::string_dup( aVars[i]);
4487 return aResult._retn();
4490 //=======================================================================
4491 //function : GetTypes
4492 //purpose : Returns types of elements it contains
4493 //=======================================================================
4495 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4498 return _preMeshInfo->GetTypes();
4500 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4504 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4505 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4506 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4507 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4508 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4509 types->length( nbTypes );
4511 return types._retn();
4514 //=======================================================================
4515 //function : GetMesh
4516 //purpose : Returns self
4517 //=======================================================================
4519 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4521 return SMESH::SMESH_Mesh::_duplicate( _this() );
4524 //=======================================================================
4525 //function : IsMeshInfoCorrect
4526 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4527 // * happen if mesh data is not yet fully loaded from the file of study.
4528 //=======================================================================
4530 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4532 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4535 //=============================================================================
4537 * \brief Returns number of mesh elements per each \a EntityType
4539 //=============================================================================
4541 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4544 return _preMeshInfo->GetMeshInfo();
4546 SMESH::long_array_var aRes = new SMESH::long_array();
4547 aRes->length(SMESH::Entity_Last);
4548 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4550 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4552 return aRes._retn();
4553 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4554 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4555 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4556 return aRes._retn();
4559 //=============================================================================
4561 * \brief Returns number of mesh elements per each \a ElementType
4563 //=============================================================================
4565 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
4567 SMESH::long_array_var aRes = new SMESH::long_array();
4568 aRes->length(SMESH::NB_ELEMENT_TYPES);
4569 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4572 const SMDS_MeshInfo* meshInfo = 0;
4574 meshInfo = _preMeshInfo;
4575 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
4576 meshInfo = & meshDS->GetMeshInfo();
4579 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4580 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
4582 return aRes._retn();
4585 //=============================================================================
4587 * Collect statistic of mesh elements given by iterator
4589 //=============================================================================
4591 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4592 SMESH::long_array& theInfo)
4594 if (!theItr) return;
4595 while (theItr->more())
4596 theInfo[ theItr->next()->GetEntityType() ]++;
4599 //=============================================================================
4600 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
4601 * SMESH::ElementType type) */
4603 using namespace SMESH::Controls;
4604 //-----------------------------------------------------------------------------
4605 struct PredicateIterator : public SMDS_ElemIterator
4607 SMDS_ElemIteratorPtr _elemIter;
4608 PredicatePtr _predicate;
4609 const SMDS_MeshElement* _elem;
4611 PredicateIterator( SMDS_ElemIteratorPtr iterator,
4612 PredicatePtr predicate):
4613 _elemIter(iterator), _predicate(predicate)
4621 virtual const SMDS_MeshElement* next()
4623 const SMDS_MeshElement* res = _elem;
4625 while ( _elemIter->more() && !_elem )
4627 _elem = _elemIter->next();
4628 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
4635 //-----------------------------------------------------------------------------
4636 struct IDSourceIterator : public SMDS_ElemIterator
4638 const CORBA::Long* _idPtr;
4639 const CORBA::Long* _idEndPtr;
4640 SMESH::long_array_var _idArray;
4641 const SMDS_Mesh* _mesh;
4642 const SMDSAbs_ElementType _type;
4643 const SMDS_MeshElement* _elem;
4645 IDSourceIterator( const SMDS_Mesh* mesh,
4646 const CORBA::Long* ids,
4648 SMDSAbs_ElementType type):
4649 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
4651 if ( _idPtr && nbIds && _mesh )
4654 IDSourceIterator( const SMDS_Mesh* mesh,
4655 SMESH::long_array* idArray,
4656 SMDSAbs_ElementType type):
4657 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
4659 if ( idArray && _mesh )
4661 _idPtr = &_idArray[0];
4662 _idEndPtr = _idPtr + _idArray->length();
4670 virtual const SMDS_MeshElement* next()
4672 const SMDS_MeshElement* res = _elem;
4674 while ( _idPtr < _idEndPtr && !_elem )
4676 if ( _type == SMDSAbs_Node )
4678 _elem = _mesh->FindNode( *_idPtr++ );
4680 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
4681 _elem->GetType() != _type )
4689 //-----------------------------------------------------------------------------
4691 struct NodeOfElemIterator : public SMDS_ElemIterator
4693 TColStd_MapOfInteger _checkedNodeIDs;
4694 SMDS_ElemIteratorPtr _elemIter;
4695 SMDS_ElemIteratorPtr _nodeIter;
4696 const SMDS_MeshElement* _node;
4698 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
4700 if ( _elemIter && _elemIter->more() )
4702 _nodeIter = _elemIter->next()->nodesIterator();
4710 virtual const SMDS_MeshElement* next()
4712 const SMDS_MeshElement* res = _node;
4714 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
4716 if ( _nodeIter->more() )
4718 _node = _nodeIter->next();
4719 if ( !_checkedNodeIDs.Add( _node->GetID() ))
4724 _nodeIter = _elemIter->next()->nodesIterator();
4732 //=============================================================================
4734 * Return iterator on elements of given type in given object
4736 //=============================================================================
4738 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
4739 SMESH::ElementType theType)
4741 SMDS_ElemIteratorPtr elemIt;
4742 bool typeOK = false;
4743 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
4745 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
4746 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
4747 if ( !mesh_i ) return elemIt;
4748 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
4750 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
4752 elemIt = meshDS->elementsIterator( elemType );
4755 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
4757 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
4760 elemIt = sm->GetElements();
4761 if ( elemType != SMDSAbs_Node )
4763 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
4764 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
4768 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
4770 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
4771 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
4773 elemIt = groupDS->GetElements();
4774 typeOK = ( groupDS->GetType() == elemType );
4777 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
4779 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
4781 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
4782 if ( pred_i && pred_i->GetPredicate() )
4784 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
4785 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
4786 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
4787 typeOK = ( filterType == elemType );
4793 SMESH::array_of_ElementType_var types = theObject->GetTypes();
4794 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
4795 if ( isNodes && elemType != SMDSAbs_Node )
4797 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
4800 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
4801 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
4805 SMESH::long_array_var ids = theObject->GetIDs();
4806 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
4808 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
4811 if ( elemIt && elemIt->more() && !typeOK )
4813 if ( elemType == SMDSAbs_Node )
4815 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
4819 elemIt = SMDS_ElemIteratorPtr();
4825 //=============================================================================
4826 namespace // Finding concurrent hypotheses
4827 //=============================================================================
4831 * \brief mapping of mesh dimension into shape type
4833 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4835 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4837 case 0: aType = TopAbs_VERTEX; break;
4838 case 1: aType = TopAbs_EDGE; break;
4839 case 2: aType = TopAbs_FACE; break;
4841 default:aType = TopAbs_SOLID; break;
4846 //-----------------------------------------------------------------------------
4848 * \brief Internal structure used to find concurent submeshes
4850 * It represents a pair < submesh, concurent dimension >, where
4851 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4852 * with another submesh. In other words, it is dimension of a hypothesis assigned
4859 int _dim; //!< a dimension the algo can build (concurrent dimension)
4860 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4861 TopTools_MapOfShape _shapeMap;
4862 SMESH_subMesh* _subMesh;
4863 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4865 //-----------------------------------------------------------------------------
4866 // Return the algorithm
4867 const SMESH_Algo* GetAlgo() const
4868 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4870 //-----------------------------------------------------------------------------
4872 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4874 const TopoDS_Shape& theShape)
4876 _subMesh = (SMESH_subMesh*)theSubMesh;
4877 SetShape( theDim, theShape );
4880 //-----------------------------------------------------------------------------
4882 void SetShape(const int theDim,
4883 const TopoDS_Shape& theShape)
4886 _ownDim = SMESH_Gen::GetShapeDim(theShape);
4887 if (_dim >= _ownDim)
4888 _shapeMap.Add( theShape );
4890 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4891 for( ; anExp.More(); anExp.Next() )
4892 _shapeMap.Add( anExp.Current() );
4896 //-----------------------------------------------------------------------------
4897 //! Check sharing of sub-shapes
4898 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4899 const TopTools_MapOfShape& theToFind,
4900 const TopAbs_ShapeEnum theType)
4902 bool isShared = false;
4903 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4904 for (; !isShared && anItr.More(); anItr.Next() )
4906 const TopoDS_Shape aSubSh = anItr.Key();
4907 // check for case when concurrent dimensions are same
4908 isShared = theToFind.Contains( aSubSh );
4909 // check for sub-shape with concurrent dimension
4910 TopExp_Explorer anExp( aSubSh, theType );
4911 for ( ; !isShared && anExp.More(); anExp.Next() )
4912 isShared = theToFind.Contains( anExp.Current() );
4917 //-----------------------------------------------------------------------------
4918 //! check algorithms
4919 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4920 const SMESHDS_Hypothesis* theA2)
4922 if ( !theA1 || !theA2 ||
4923 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4924 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4925 return false; // one of the hypothesis is not algorithm
4926 // check algorithm names (should be equal)
4927 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4931 //-----------------------------------------------------------------------------
4932 //! Check if sub-shape hypotheses are concurrent
4933 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4935 if ( _subMesh == theOther->_subMesh )
4936 return false; // same sub-shape - should not be
4938 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4939 // any of the two submeshes is not on COMPOUND shape )
4940 // -> no concurrency
4941 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4942 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4943 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4944 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4945 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4948 // bool checkSubShape = ( _dim >= theOther->_dim )
4949 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4950 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4951 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4952 if ( !checkSubShape )
4955 // check algorithms to be same
4956 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4957 return true; // different algorithms -> concurrency !
4959 // check hypothesises for concurrence (skip first as algorithm)
4961 // pointers should be same, because it is referened from mesh hypothesis partition
4962 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4963 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4964 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4965 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4967 // the submeshes are concurrent if their algorithms has different parameters
4968 return nbSame != theOther->_hypotheses.size() - 1;
4971 // Return true if algorithm of this SMESH_DimHyp is used if no
4972 // sub-mesh order is imposed by the user
4973 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4975 // NeedDiscreteBoundary() algo has a higher priority
4976 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4977 theOther->GetAlgo()->NeedDiscreteBoundary() )
4978 return !this->GetAlgo()->NeedDiscreteBoundary();
4980 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4983 }; // end of SMESH_DimHyp
4984 //-----------------------------------------------------------------------------
4986 typedef list<const SMESH_DimHyp*> TDimHypList;
4988 //-----------------------------------------------------------------------------
4990 void addDimHypInstance(const int theDim,
4991 const TopoDS_Shape& theShape,
4992 const SMESH_Algo* theAlgo,
4993 const SMESH_subMesh* theSubMesh,
4994 const list <const SMESHDS_Hypothesis*>& theHypList,
4995 TDimHypList* theDimHypListArr )
4997 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4998 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4999 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5000 dimHyp->_hypotheses.push_front(theAlgo);
5001 listOfdimHyp.push_back( dimHyp );
5004 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5005 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5006 theHypList.begin(), theHypList.end() );
5009 //-----------------------------------------------------------------------------
5010 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5011 TDimHypList& theListOfConcurr)
5013 if ( theListOfConcurr.empty() )
5015 theListOfConcurr.push_back( theDimHyp );
5019 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5020 while ( hypIt != theListOfConcurr.end() &&
5021 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5023 theListOfConcurr.insert( hypIt, theDimHyp );
5027 //-----------------------------------------------------------------------------
5028 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5029 const TDimHypList& theListOfDimHyp,
5030 TDimHypList& theListOfConcurrHyp,
5031 set<int>& theSetOfConcurrId )
5033 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5034 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5036 const SMESH_DimHyp* curDimHyp = *rIt;
5037 if ( curDimHyp == theDimHyp )
5038 break; // meet own dimHyp pointer in same dimension
5040 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5041 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5043 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5048 //-----------------------------------------------------------------------------
5049 void unionLists(TListOfInt& theListOfId,
5050 TListOfListOfInt& theListOfListOfId,
5053 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5054 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5056 continue; //skip already treated lists
5057 // check if other list has any same submesh object
5058 TListOfInt& otherListOfId = *it;
5059 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5060 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5063 // union two lists (from source into target)
5064 TListOfInt::iterator it2 = otherListOfId.begin();
5065 for ( ; it2 != otherListOfId.end(); it2++ ) {
5066 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5067 theListOfId.push_back(*it2);
5069 // clear source list
5070 otherListOfId.clear();
5073 //-----------------------------------------------------------------------------
5075 //! free memory allocated for dimension-hypothesis objects
5076 void removeDimHyps( TDimHypList* theArrOfList )
5078 for (int i = 0; i < 4; i++ ) {
5079 TDimHypList& listOfdimHyp = theArrOfList[i];
5080 TDimHypList::const_iterator it = listOfdimHyp.begin();
5081 for ( ; it != listOfdimHyp.end(); it++ )
5086 //-----------------------------------------------------------------------------
5088 * \brief find common submeshes with given submesh
5089 * \param theSubMeshList list of already collected submesh to check
5090 * \param theSubMesh given submesh to intersect with other
5091 * \param theCommonSubMeshes collected common submeshes
5093 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5094 const SMESH_subMesh* theSubMesh,
5095 set<const SMESH_subMesh*>& theCommon )
5099 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5100 for ( ; it != theSubMeshList.end(); it++ )
5101 theSubMesh->FindIntersection( *it, theCommon );
5102 theSubMeshList.push_back( theSubMesh );
5103 //theCommon.insert( theSubMesh );
5106 //-----------------------------------------------------------------------------
5107 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5109 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5110 for ( ; listsIt != smLists.end(); ++listsIt )
5112 const TListOfInt& smIDs = *listsIt;
5113 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5121 //=============================================================================
5123 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5125 //=============================================================================
5127 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5129 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5130 if ( isSubMeshInList( submeshID, anOrder ))
5133 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5134 return isSubMeshInList( submeshID, allConurrent );
5137 //=============================================================================
5139 * \brief Return submesh objects list in meshing order
5141 //=============================================================================
5143 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5145 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5147 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5149 return aResult._retn();
5151 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5152 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5153 anOrder.splice( anOrder.end(), allConurrent );
5156 TListOfListOfInt::iterator listIt = anOrder.begin();
5157 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5158 unionLists( *listIt, anOrder, listIndx + 1 );
5160 // convert submesh ids into interface instances
5161 // and dump command into python
5162 convertMeshOrder( anOrder, aResult, false );
5164 return aResult._retn();
5167 //=============================================================================
5169 * \brief Finds concurrent sub-meshes
5171 //=============================================================================
5173 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5175 TListOfListOfInt anOrder;
5176 ::SMESH_Mesh& mesh = GetImpl();
5178 // collect submeshes and detect concurrent algorithms and hypothesises
5179 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5181 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5182 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5183 ::SMESH_subMesh* sm = (*i_sm).second;
5185 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5187 // list of assigned hypothesises
5188 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5189 // Find out dimensions where the submesh can be concurrent.
5190 // We define the dimensions by algo of each of hypotheses in hypList
5191 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5192 for( ; hypIt != hypList.end(); hypIt++ ) {
5193 SMESH_Algo* anAlgo = 0;
5194 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5195 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5196 // hyp it-self is algo
5197 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5199 // try to find algorithm with help of sub-shapes
5200 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5201 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5202 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5205 continue; // no algorithm assigned to a current submesh
5207 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5208 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5210 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5211 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5212 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5214 } // end iterations on submesh
5216 // iterate on created dimension-hypotheses and check for concurrents
5217 for ( int i = 0; i < 4; i++ ) {
5218 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5219 // check for concurrents in own and other dimensions (step-by-step)
5220 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5221 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5222 const SMESH_DimHyp* dimHyp = *dhIt;
5223 TDimHypList listOfConcurr;
5224 set<int> setOfConcurrIds;
5225 // looking for concurrents and collect into own list
5226 for ( int j = i; j < 4; j++ )
5227 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5228 // check if any concurrents found
5229 if ( listOfConcurr.size() > 0 ) {
5230 // add own submesh to list of concurrent
5231 addInOrderOfPriority( dimHyp, listOfConcurr );
5232 list<int> listOfConcurrIds;
5233 TDimHypList::iterator hypIt = listOfConcurr.begin();
5234 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5235 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5236 anOrder.push_back( listOfConcurrIds );
5241 removeDimHyps(dimHypListArr);
5243 // now, minimise the number of concurrent groups
5244 // Here we assume that lists of submeshes can have same submesh
5245 // in case of multi-dimension algorithms, as result
5246 // list with common submesh has to be united into one list
5248 TListOfListOfInt::iterator listIt = anOrder.begin();
5249 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5250 unionLists( *listIt, anOrder, listIndx + 1 );
5256 //=============================================================================
5258 * \brief Set submesh object order
5259 * \param theSubMeshArray submesh array order
5261 //=============================================================================
5263 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5266 _preMeshInfo->ForgetOrLoad();
5269 ::SMESH_Mesh& mesh = GetImpl();
5271 TPythonDump aPythonDump; // prevent dump of called methods
5272 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5274 TListOfListOfInt subMeshOrder;
5275 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5277 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5278 TListOfInt subMeshIds;
5279 aPythonDump << "[ ";
5280 // Collect subMeshes which should be clear
5281 // do it list-by-list, because modification of submesh order
5282 // take effect between concurrent submeshes only
5283 set<const SMESH_subMesh*> subMeshToClear;
5284 list<const SMESH_subMesh*> subMeshList;
5285 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5287 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5289 aPythonDump << ", ";
5290 aPythonDump << subMesh;
5291 subMeshIds.push_back( subMesh->GetId() );
5292 // detect common parts of submeshes
5293 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5294 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5296 aPythonDump << " ]";
5297 subMeshOrder.push_back( subMeshIds );
5299 // clear collected submeshes
5300 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5301 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5302 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5303 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5305 aPythonDump << " ])";
5307 mesh.SetMeshOrder( subMeshOrder );
5313 //=============================================================================
5315 * \brief Convert submesh ids into submesh interfaces
5317 //=============================================================================
5319 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5320 SMESH::submesh_array_array& theResOrder,
5321 const bool theIsDump)
5323 int nbSet = theIdsOrder.size();
5324 TPythonDump aPythonDump; // prevent dump of called methods
5326 aPythonDump << "[ ";
5327 theResOrder.length(nbSet);
5328 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5330 for( ; it != theIdsOrder.end(); it++ ) {
5331 // translate submesh identificators into submesh objects
5332 // takeing into account real number of concurrent lists
5333 const TListOfInt& aSubOrder = (*it);
5334 if (!aSubOrder.size())
5337 aPythonDump << "[ ";
5338 // convert shape indeces into interfaces
5339 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5340 aResSubSet->length(aSubOrder.size());
5341 TListOfInt::const_iterator subIt = aSubOrder.begin();
5343 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5344 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5346 SMESH::SMESH_subMesh_var subMesh =
5347 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5350 aPythonDump << ", ";
5351 aPythonDump << subMesh;
5353 aResSubSet[ j++ ] = subMesh;
5356 aPythonDump << " ]";
5358 theResOrder[ listIndx++ ] = aResSubSet;
5360 // correct number of lists
5361 theResOrder.length( listIndx );
5364 // finilise python dump
5365 aPythonDump << " ]";
5366 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5370 //================================================================================
5372 // Implementation of SMESH_MeshPartDS
5374 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5375 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5377 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5378 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5380 _meshDS = mesh_i->GetImpl().GetMeshDS();
5382 SetPersistentId( _meshDS->GetPersistentId() );
5384 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5386 // <meshPart> is the whole mesh
5387 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5389 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5390 myGroupSet = _meshDS->GetGroups();
5395 SMESH::long_array_var anIDs = meshPart->GetIDs();
5396 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5397 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5399 for (int i=0; i < anIDs->length(); i++)
5400 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5401 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5406 for (int i=0; i < anIDs->length(); i++)
5407 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5408 if ( _elements[ e->GetType() ].insert( e ).second )
5411 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5412 while ( nIt->more() )
5414 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5415 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5422 _meshDS = 0; // to enforce iteration on _elements and _nodes
5425 // -------------------------------------------------------------------------------------
5426 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5427 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5430 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5431 for ( ; partIt != meshPart.end(); ++partIt )
5432 if ( const SMDS_MeshElement * e = *partIt )
5433 if ( _elements[ e->GetType() ].insert( e ).second )
5436 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5437 while ( nIt->more() )
5439 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5440 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5446 // -------------------------------------------------------------------------------------
5447 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5449 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5451 typedef SMDS_SetIterator
5452 <const SMDS_MeshElement*,
5453 TIDSortedElemSet::const_iterator,
5454 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5455 SMDS_MeshElement::GeomFilter
5458 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5460 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5461 _elements[type].end(),
5462 SMDS_MeshElement::GeomFilter( geomType )));
5464 // -------------------------------------------------------------------------------------
5465 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5467 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5469 typedef SMDS_SetIterator
5470 <const SMDS_MeshElement*,
5471 TIDSortedElemSet::const_iterator,
5472 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5473 SMDS_MeshElement::EntityFilter
5476 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5478 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5479 _elements[type].end(),
5480 SMDS_MeshElement::EntityFilter( entity )));
5482 // -------------------------------------------------------------------------------------
5483 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5485 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5486 if ( type == SMDSAbs_All && !_meshDS )
5488 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5490 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5491 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5493 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5495 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5496 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5498 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5499 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5501 // -------------------------------------------------------------------------------------
5502 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5503 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5505 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5506 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5507 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5509 // -------------------------------------------------------------------------------------
5510 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5511 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5512 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5513 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5514 #undef _GET_ITER_DEFINE
5516 // END Implementation of SMESH_MeshPartDS
5518 //================================================================================