1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_SMESHDS_Mesh.h"
30 #include "MED_Factory.hxx"
31 #include "SMDS_EdgePosition.hxx"
32 #include "SMDS_ElemIterator.hxx"
33 #include "SMDS_FacePosition.hxx"
34 #include "SMDS_IteratorOnIterators.hxx"
35 #include "SMDS_MeshGroup.hxx"
36 #include "SMDS_SetIterator.hxx"
37 #include "SMDS_VolumeTool.hxx"
38 #include "SMESHDS_Command.hxx"
39 #include "SMESHDS_CommandType.hxx"
40 #include "SMESHDS_Group.hxx"
41 #include "SMESHDS_GroupOnGeom.hxx"
42 #include "SMESH_Controls.hxx"
43 #include "SMESH_Filter_i.hxx"
44 #include "SMESH_Gen_i.hxx"
45 #include "SMESH_Group.hxx"
46 #include "SMESH_Group_i.hxx"
47 #include "SMESH_MeshEditor.hxx"
48 #include "SMESH_MeshEditor_i.hxx"
49 #include "SMESH_MeshPartDS.hxx"
50 #include "SMESH_MesherHelper.hxx"
51 #include "SMESH_PreMeshInfo.hxx"
52 #include "SMESH_PythonDump.hxx"
53 #include "SMESH_subMesh_i.hxx"
56 #include <SALOMEDS_Attributes_wrap.hxx>
57 #include <SALOMEDS_wrap.hxx>
58 #include <SALOME_NamingService.hxx>
59 #include <Utils_ExceptHandlers.hxx>
60 #include <Utils_SINGLETON.hxx>
61 #include <utilities.h>
63 #include <GEOMImpl_Types.hxx>
64 #include <GEOM_wrap.hxx>
67 #include <BRep_Builder.hxx>
68 #include <OSD_Directory.hxx>
69 #include <OSD_File.hxx>
70 #include <OSD_Path.hxx>
71 #include <OSD_Protection.hxx>
72 #include <Standard_OutOfMemory.hxx>
73 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
74 #include <TColStd_MapOfInteger.hxx>
75 #include <TColStd_SequenceOfInteger.hxx>
76 #include <TCollection_AsciiString.hxx>
78 #include <TopExp_Explorer.hxx>
79 #include <TopTools_MapIteratorOfMapOfShape.hxx>
80 #include <TopTools_MapOfShape.hxx>
81 #include <TopoDS_Compound.hxx>
83 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
94 static int MYDEBUG = 0;
96 static int MYDEBUG = 0;
100 using SMESH::TPythonDump;
102 int SMESH_Mesh_i::_idGenerator = 0;
104 //=============================================================================
108 //=============================================================================
110 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
112 CORBA::Long studyId )
113 : SALOME::GenericObj_i( thePOA )
115 MESSAGE("SMESH_Mesh_i");
118 _id = _idGenerator++;
121 _previewEditor = NULL;
125 //=============================================================================
129 //=============================================================================
131 SMESH_Mesh_i::~SMESH_Mesh_i()
133 MESSAGE("~SMESH_Mesh_i");
136 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
137 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
138 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
140 aGroup->UnRegister();
141 SMESH::SMESH_GroupBase_var( itGr->second );
146 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
147 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
148 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
150 aSubMesh->UnRegister();
151 SMESH::SMESH_subMesh_var( itSM->second );
153 _mapSubMeshIor.clear();
155 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
156 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
157 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
158 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
159 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
160 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
163 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
167 delete _editor; _editor = NULL;
168 delete _previewEditor; _previewEditor = NULL;
169 delete _impl; _impl = NULL;
170 delete _preMeshInfo; _preMeshInfo = NULL;
173 //=============================================================================
177 * Associates <this> mesh with <theShape> and puts a reference
178 * to <theShape> into the current study;
179 * the previous shape is substituted by the new one.
181 //=============================================================================
183 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
184 throw (SALOME::SALOME_Exception)
186 Unexpect aCatch(SALOME_SalomeException);
188 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
190 catch(SALOME_Exception & S_ex) {
191 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
193 // to track changes of GEOM groups
194 SMESH::SMESH_Mesh_var mesh = _this();
195 addGeomGroupData( theShapeObject, mesh );
198 //================================================================================
200 * \brief return true if mesh has a shape to build a shape on
202 //================================================================================
204 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
205 throw (SALOME::SALOME_Exception)
207 Unexpect aCatch(SALOME_SalomeException);
210 res = _impl->HasShapeToMesh();
212 catch(SALOME_Exception & S_ex) {
213 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
218 //=======================================================================
219 //function : GetShapeToMesh
221 //=======================================================================
223 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
224 throw (SALOME::SALOME_Exception)
226 Unexpect aCatch(SALOME_SalomeException);
227 GEOM::GEOM_Object_var aShapeObj;
229 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
231 aShapeObj = _gen_i->ShapeToGeomObject( S );
233 catch(SALOME_Exception & S_ex) {
234 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
236 return aShapeObj._retn();
239 //================================================================================
241 * \brief Return false if the mesh is not yet fully loaded from the study file
243 //================================================================================
245 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
247 Unexpect aCatch(SALOME_SalomeException);
248 return !_preMeshInfo;
251 //================================================================================
253 * \brief Load full mesh data from the study file
255 //================================================================================
257 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
259 Unexpect aCatch(SALOME_SalomeException);
261 _preMeshInfo->FullLoadFromFile();
264 //================================================================================
266 * \brief Remove all nodes and elements
268 //================================================================================
270 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
272 Unexpect aCatch(SALOME_SalomeException);
274 _preMeshInfo->ForgetAllData();
278 CheckGeomGroupModif(); // issue 20145
280 catch(SALOME_Exception & S_ex) {
281 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
283 _impl->GetMeshDS()->Modified();
285 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
288 //================================================================================
290 * \brief Remove all nodes and elements for indicated shape
292 //================================================================================
294 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
295 throw (SALOME::SALOME_Exception)
297 Unexpect aCatch(SALOME_SalomeException);
299 _preMeshInfo->FullLoadFromFile();
302 _impl->ClearSubMesh( ShapeID );
304 catch(SALOME_Exception & S_ex) {
305 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
307 _impl->GetMeshDS()->Modified();
309 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
312 //=============================================================================
314 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
316 //=============================================================================
318 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
320 SMESH::DriverMED_ReadStatus res;
323 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
324 res = SMESH::DRS_OK; break;
325 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
326 res = SMESH::DRS_EMPTY; break;
327 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
328 res = SMESH::DRS_WARN_RENUMBER; break;
329 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
330 res = SMESH::DRS_WARN_SKIP_ELEM; break;
331 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
332 res = SMESH::DRS_WARN_DESCENDING; break;
333 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
335 res = SMESH::DRS_FAIL; break;
340 //=============================================================================
342 * Convert ::SMESH_ComputeError to SMESH::ComputeError
344 //=============================================================================
346 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
348 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
349 errVar->subShapeID = -1;
350 errVar->hasBadMesh = false;
352 if ( !errorPtr || errorPtr->IsOK() )
354 errVar->code = SMESH::COMPERR_OK;
358 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
359 errVar->comment = errorPtr->myComment.c_str();
361 return errVar._retn();
364 //=============================================================================
368 * Imports mesh data from MED file
370 //=============================================================================
372 SMESH::DriverMED_ReadStatus
373 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
374 throw ( SALOME::SALOME_Exception )
376 Unexpect aCatch(SALOME_SalomeException);
379 status = _impl->MEDToMesh( theFileName, theMeshName );
381 catch( SALOME_Exception& S_ex ) {
382 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
385 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
388 CreateGroupServants();
390 int major, minor, release;
391 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
392 major = minor = release = -1;
393 _medFileInfo = new SMESH::MedFileInfo();
394 _medFileInfo->fileName = theFileName;
395 _medFileInfo->fileSize = 0;
396 _medFileInfo->major = major;
397 _medFileInfo->minor = minor;
398 _medFileInfo->release = release;
401 if ( ::_stati64( theFileName, &d ) != -1 )
404 if ( ::stat64( theFileName, &d ) != -1 )
406 _medFileInfo->fileSize = d.st_size;
408 return ConvertDriverMEDReadStatus(status);
411 //================================================================================
413 * \brief Imports mesh data from the CGNS file
415 //================================================================================
417 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
418 const int theMeshIndex,
419 std::string& theMeshName )
420 throw ( SALOME::SALOME_Exception )
422 Unexpect aCatch(SALOME_SalomeException);
425 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
427 catch( SALOME_Exception& S_ex ) {
428 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
431 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
434 CreateGroupServants();
436 return ConvertDriverMEDReadStatus(status);
439 //================================================================================
441 * \brief Return string representation of a MED file version comprising nbDigits
443 //================================================================================
445 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
447 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
449 return CORBA::string_dup( ver.c_str() );
452 //=============================================================================
456 * Imports mesh data from MED file
458 //=============================================================================
460 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
461 throw ( SALOME::SALOME_Exception )
465 // Read mesh with name = <theMeshName> into SMESH_Mesh
466 _impl->UNVToMesh( theFileName );
468 CreateGroupServants();
470 SMESH_CATCH( SMESH::throwCorbaException );
475 //=============================================================================
479 * Imports mesh data from STL file
481 //=============================================================================
482 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
483 throw ( SALOME::SALOME_Exception )
487 // Read mesh with name = <theMeshName> into SMESH_Mesh
488 _impl->STLToMesh( theFileName );
490 SMESH_CATCH( SMESH::throwCorbaException );
495 //================================================================================
497 * \brief Function used in SMESH_CATCH by ImportGMFFile()
499 //================================================================================
503 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
505 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
509 //================================================================================
511 * \brief Imports data from a GMF file and returns an error description
513 //================================================================================
515 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
516 bool theMakeRequiredGroups )
517 throw (SALOME::SALOME_Exception)
519 SMESH_ComputeErrorPtr error;
522 #define SMESH_CAUGHT error =
525 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
527 SMESH_CATCH( exceptionToComputeError );
531 CreateGroupServants();
533 return ConvertComputeError( error );
536 //=============================================================================
540 //=============================================================================
542 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
544 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
545 (SMESH_Hypothesis::Hypothesis_Status theStatus)
548 RETURNCASE( HYP_OK );
549 RETURNCASE( HYP_MISSING );
550 RETURNCASE( HYP_CONCURENT );
551 RETURNCASE( HYP_BAD_PARAMETER );
552 RETURNCASE( HYP_HIDDEN_ALGO );
553 RETURNCASE( HYP_HIDING_ALGO );
554 RETURNCASE( HYP_UNKNOWN_FATAL );
555 RETURNCASE( HYP_INCOMPATIBLE );
556 RETURNCASE( HYP_NOTCONFORM );
557 RETURNCASE( HYP_ALREADY_EXIST );
558 RETURNCASE( HYP_BAD_DIM );
559 RETURNCASE( HYP_BAD_SUBSHAPE );
560 RETURNCASE( HYP_BAD_GEOMETRY );
561 RETURNCASE( HYP_NEED_SHAPE );
564 return SMESH::HYP_UNKNOWN_FATAL;
567 //=============================================================================
571 * calls internal addHypothesis() and then adds a reference to <anHyp> under
572 * the SObject actually having a reference to <aSubShape>.
573 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
575 //=============================================================================
577 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
578 SMESH::SMESH_Hypothesis_ptr anHyp)
579 throw(SALOME::SALOME_Exception)
581 Unexpect aCatch(SALOME_SalomeException);
583 _preMeshInfo->ForgetOrLoad();
585 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
587 SMESH::SMESH_Mesh_var mesh( _this() );
588 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
590 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
591 _gen_i->AddHypothesisToShape( study, mesh, aSubShapeObject, anHyp );
593 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
595 // Update Python script
596 //if(_impl->HasShapeToMesh())
598 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
599 << aSubShapeObject << ", " << anHyp << " )";
602 // TPythonDump() << "status = " << mesh << ".AddHypothesis( "<< anHyp << " )";
605 return ConvertHypothesisStatus(status);
608 //=============================================================================
612 //=============================================================================
614 SMESH_Hypothesis::Hypothesis_Status
615 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
616 SMESH::SMESH_Hypothesis_ptr anHyp)
618 if(MYDEBUG) MESSAGE("addHypothesis");
620 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
621 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
623 if (CORBA::is_nil( anHyp ))
624 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
626 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
629 TopoDS_Shape myLocSubShape;
630 //use PseudoShape in case if mesh has no shape
632 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
634 myLocSubShape = _impl->GetShapeToMesh();
636 const int hypId = anHyp->GetId();
637 status = _impl->AddHypothesis(myLocSubShape, hypId);
638 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
639 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
641 // assure there is a corresponding submesh
642 if ( !_impl->IsMainShape( myLocSubShape )) {
643 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
644 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
645 SMESH::SMESH_subMesh_var( createSubMesh( aSubShapeObject ));
649 catch(SALOME_Exception & S_ex)
651 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
656 //=============================================================================
660 //=============================================================================
662 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
663 SMESH::SMESH_Hypothesis_ptr anHyp)
664 throw(SALOME::SALOME_Exception)
666 Unexpect aCatch(SALOME_SalomeException);
668 _preMeshInfo->ForgetOrLoad();
670 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
671 SMESH::SMESH_Mesh_var mesh = _this();
673 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
675 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
676 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShapeObject, anHyp );
678 // Update Python script
679 if(_impl->HasShapeToMesh())
680 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
681 << aSubShapeObject << ", " << anHyp << " )";
683 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
686 return ConvertHypothesisStatus(status);
689 //=============================================================================
693 //=============================================================================
695 SMESH_Hypothesis::Hypothesis_Status
696 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
697 SMESH::SMESH_Hypothesis_ptr anHyp)
699 if(MYDEBUG) MESSAGE("removeHypothesis()");
701 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
702 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
704 if (CORBA::is_nil( anHyp ))
705 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
707 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
710 TopoDS_Shape myLocSubShape;
711 //use PseudoShape in case if mesh has no shape
712 if( _impl->HasShapeToMesh() )
713 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject );
715 myLocSubShape = _impl->GetShapeToMesh();
717 const int hypId = anHyp->GetId();
718 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
719 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
721 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
725 catch(SALOME_Exception & S_ex)
727 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
732 //=============================================================================
736 //=============================================================================
738 SMESH::ListOfHypothesis *
739 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
740 throw(SALOME::SALOME_Exception)
742 Unexpect aCatch(SALOME_SalomeException);
743 if (MYDEBUG) MESSAGE("GetHypothesisList");
744 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
745 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
747 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
750 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
751 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
752 myLocSubShape = _impl->GetShapeToMesh();
753 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
754 int i = 0, n = aLocalList.size();
757 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
758 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
759 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
761 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
762 if ( id_hypptr != _mapHypo.end() )
763 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
767 catch(SALOME_Exception & S_ex) {
768 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
771 return aList._retn();
774 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
776 Unexpect aCatch(SALOME_SalomeException);
777 if (MYDEBUG) MESSAGE("GetSubMeshes");
779 SMESH::submesh_array_var aList = new SMESH::submesh_array();
782 TPythonDump aPythonDump;
783 if ( !_mapSubMeshIor.empty() )
787 aList->length( _mapSubMeshIor.size() );
789 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
790 for ( ; it != _mapSubMeshIor.end(); it++ ) {
791 if ( CORBA::is_nil( it->second )) continue;
792 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
794 if (i > 1) aPythonDump << ", ";
795 aPythonDump << it->second;
799 catch(SALOME_Exception & S_ex) {
800 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
803 // Update Python script
804 if ( !_mapSubMeshIor.empty() )
805 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
807 return aList._retn();
810 //=============================================================================
814 //=============================================================================
816 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
817 const char* theName )
818 throw(SALOME::SALOME_Exception)
820 Unexpect aCatch(SALOME_SalomeException);
821 if (CORBA::is_nil(aSubShapeObject))
822 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
824 SMESH::SMESH_subMesh_var subMesh;
825 SMESH::SMESH_Mesh_var aMesh = _this();
827 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
829 //Get or Create the SMESH_subMesh object implementation
831 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
833 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
835 TopoDS_Iterator it( myLocSubShape );
837 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
839 subMesh = getSubMesh( subMeshId );
841 // create a new subMesh object servant if there is none for the shape
842 if ( subMesh->_is_nil() )
843 subMesh = createSubMesh( aSubShapeObject );
844 if ( _gen_i->CanPublishInStudy( subMesh ))
846 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
847 SALOMEDS::SObject_wrap aSO =
848 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShapeObject, theName );
849 if ( !aSO->_is_nil()) {
850 // Update Python script
851 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
852 << aSubShapeObject << ", '" << theName << "' )";
856 catch(SALOME_Exception & S_ex) {
857 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
859 return subMesh._retn();
862 //=============================================================================
866 //=============================================================================
868 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
869 throw (SALOME::SALOME_Exception)
873 if ( theSubMesh->_is_nil() )
876 GEOM::GEOM_Object_var aSubShapeObject;
877 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
878 if ( !aStudy->_is_nil() ) {
879 // Remove submesh's SObject
880 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
881 if ( !anSO->_is_nil() ) {
882 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
883 SALOMEDS::SObject_wrap anObj, aRef;
884 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
885 anObj->ReferencedObject( aRef.inout() ))
887 CORBA::Object_var obj = aRef->GetObject();
888 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
890 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
891 // aSubShapeObject = theSubMesh->GetSubShape();
893 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
894 builder->RemoveObjectWithChildren( anSO );
896 // Update Python script
897 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
901 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
903 _preMeshInfo->ForgetOrLoad();
905 SMESH_CATCH( SMESH::throwCorbaException );
908 //=============================================================================
912 //=============================================================================
914 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
915 const char* theName )
916 throw(SALOME::SALOME_Exception)
918 Unexpect aCatch(SALOME_SalomeException);
920 _preMeshInfo->FullLoadFromFile();
922 SMESH::SMESH_Group_var aNewGroup =
923 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
925 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
927 SMESH::SMESH_Mesh_var mesh = _this();
928 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
929 SALOMEDS::SObject_wrap aSO =
930 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
931 if ( !aSO->_is_nil())
932 // Update Python script
933 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
934 << theElemType << ", '" << theName << "' )";
936 return aNewGroup._retn();
939 //=============================================================================
943 //=============================================================================
944 SMESH::SMESH_GroupOnGeom_ptr
945 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
947 GEOM::GEOM_Object_ptr theGeomObj)
948 throw(SALOME::SALOME_Exception)
950 Unexpect aCatch(SALOME_SalomeException);
952 _preMeshInfo->FullLoadFromFile();
954 SMESH::SMESH_GroupOnGeom_var aNewGroup;
956 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
957 if ( !aShape.IsNull() )
960 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
962 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
964 SMESH::SMESH_Mesh_var mesh = _this();
965 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
966 SALOMEDS::SObject_wrap aSO =
967 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
968 if ( !aSO->_is_nil())
969 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
970 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
974 return aNewGroup._retn();
977 //================================================================================
979 * \brief Creates a group whose contents is defined by filter
980 * \param theElemType - group type
981 * \param theName - group name
982 * \param theFilter - the filter
983 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
985 //================================================================================
987 SMESH::SMESH_GroupOnFilter_ptr
988 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
990 SMESH::Filter_ptr theFilter )
991 throw (SALOME::SALOME_Exception)
993 Unexpect aCatch(SALOME_SalomeException);
995 _preMeshInfo->FullLoadFromFile();
997 if ( CORBA::is_nil( theFilter ))
998 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1000 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1002 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1004 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1005 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1008 if ( !aNewGroup->_is_nil() )
1009 aNewGroup->SetFilter( theFilter );
1011 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1013 SMESH::SMESH_Mesh_var mesh = _this();
1014 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1015 SALOMEDS::SObject_wrap aSO =
1016 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1018 if ( !aSO->_is_nil())
1019 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1020 << theElemType << ", '" << theName << "', " << theFilter << " )";
1022 return aNewGroup._retn();
1025 //=============================================================================
1029 //=============================================================================
1031 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1032 throw (SALOME::SALOME_Exception)
1034 if ( theGroup->_is_nil() )
1039 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1043 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1044 if ( !aStudy->_is_nil() )
1046 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1047 if ( !aGroupSO->_is_nil() )
1049 // Update Python script
1050 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1052 // Remove group's SObject
1053 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1054 builder->RemoveObjectWithChildren( aGroupSO );
1058 // Remove the group from SMESH data structures
1059 removeGroup( aGroup->GetLocalID() );
1061 SMESH_CATCH( SMESH::throwCorbaException );
1064 //=============================================================================
1066 * Remove group with its contents
1068 //=============================================================================
1070 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1071 throw (SALOME::SALOME_Exception)
1075 _preMeshInfo->FullLoadFromFile();
1077 if ( theGroup->_is_nil() )
1081 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1082 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1083 while ( elemIt->more() )
1084 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1086 TPythonDump pyDump; // Supress dump from RemoveGroup()
1088 // Update Python script (theGroup must be alive for this)
1089 pyDump << SMESH::SMESH_Mesh_var(_this())
1090 << ".RemoveGroupWithContents( " << theGroup << " )";
1093 RemoveGroup( theGroup );
1095 SMESH_CATCH( SMESH::throwCorbaException );
1098 //================================================================================
1100 * \brief Get the list of groups existing in the mesh
1101 * \retval SMESH::ListOfGroups * - list of groups
1103 //================================================================================
1105 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1107 Unexpect aCatch(SALOME_SalomeException);
1108 if (MYDEBUG) MESSAGE("GetGroups");
1110 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1113 TPythonDump aPythonDump;
1114 if ( !_mapGroups.empty() )
1116 aPythonDump << "[ ";
1118 aList->length( _mapGroups.size() );
1120 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1121 for ( ; it != _mapGroups.end(); it++ ) {
1122 if ( CORBA::is_nil( it->second )) continue;
1123 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1125 if (i > 1) aPythonDump << ", ";
1126 aPythonDump << it->second;
1130 catch(SALOME_Exception & S_ex) {
1131 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1133 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1135 return aList._retn();
1138 //=============================================================================
1140 * Get number of groups existing in the mesh
1142 //=============================================================================
1144 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1146 Unexpect aCatch(SALOME_SalomeException);
1147 return _mapGroups.size();
1150 //=============================================================================
1152 * New group including all mesh elements present in initial groups is created.
1154 //=============================================================================
1156 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1157 SMESH::SMESH_GroupBase_ptr theGroup2,
1158 const char* theName )
1159 throw (SALOME::SALOME_Exception)
1161 SMESH::SMESH_Group_var aResGrp;
1165 _preMeshInfo->FullLoadFromFile();
1167 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1168 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1170 if ( theGroup1->GetType() != theGroup2->GetType() )
1171 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1176 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1177 if ( aResGrp->_is_nil() )
1178 return SMESH::SMESH_Group::_nil();
1180 aResGrp->AddFrom( theGroup1 );
1181 aResGrp->AddFrom( theGroup2 );
1183 // Update Python script
1184 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1185 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1187 SMESH_CATCH( SMESH::throwCorbaException );
1189 return aResGrp._retn();
1192 //=============================================================================
1194 * \brief New group including all mesh elements present in initial groups is created.
1195 * \param theGroups list of groups
1196 * \param theName name of group to be created
1197 * \return pointer to the new group
1199 //=============================================================================
1201 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1202 const char* theName )
1203 throw (SALOME::SALOME_Exception)
1205 SMESH::SMESH_Group_var aResGrp;
1208 _preMeshInfo->FullLoadFromFile();
1211 return SMESH::SMESH_Group::_nil();
1216 SMESH::ElementType aType = SMESH::ALL;
1217 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1219 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1220 if ( CORBA::is_nil( aGrp ) )
1222 if ( aType == SMESH::ALL )
1223 aType = aGrp->GetType();
1224 else if ( aType != aGrp->GetType() )
1225 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1228 if ( aType == SMESH::ALL )
1229 return SMESH::SMESH_Group::_nil();
1234 aResGrp = CreateGroup( aType, theName );
1235 if ( aResGrp->_is_nil() )
1236 return SMESH::SMESH_Group::_nil();
1238 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1239 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1241 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1242 if ( !CORBA::is_nil( aGrp ) )
1244 aResGrp->AddFrom( aGrp );
1245 if ( g > 0 ) pyDump << ", ";
1249 pyDump << " ], '" << theName << "' )";
1251 SMESH_CATCH( SMESH::throwCorbaException );
1253 return aResGrp._retn();
1256 //=============================================================================
1258 * New group is created. All mesh elements that are
1259 * present in both initial groups are added to the new one.
1261 //=============================================================================
1263 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1264 SMESH::SMESH_GroupBase_ptr theGroup2,
1265 const char* theName )
1266 throw (SALOME::SALOME_Exception)
1268 SMESH::SMESH_Group_var aResGrp;
1273 _preMeshInfo->FullLoadFromFile();
1275 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1276 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1278 if ( theGroup1->GetType() != theGroup2->GetType() )
1279 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1283 // Create Intersection
1284 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1285 if ( aResGrp->_is_nil() )
1286 return aResGrp._retn();
1288 SMESHDS_GroupBase* groupDS1 = 0;
1289 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1290 groupDS1 = grp_i->GetGroupDS();
1292 SMESHDS_GroupBase* groupDS2 = 0;
1293 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1294 groupDS2 = grp_i->GetGroupDS();
1296 SMESHDS_Group* resGroupDS = 0;
1297 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1298 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1300 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1302 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1303 while ( elemIt1->more() )
1305 const SMDS_MeshElement* e = elemIt1->next();
1306 if ( groupDS2->Contains( e ))
1307 resGroupDS->SMDSGroup().Add( e );
1310 // Update Python script
1311 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1312 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1314 SMESH_CATCH( SMESH::throwCorbaException );
1316 return aResGrp._retn();
1319 //=============================================================================
1321 \brief Intersect list of groups. New group is created. All mesh elements that
1322 are present in all initial groups simultaneously are added to the new one.
1323 \param theGroups list of groups
1324 \param theName name of group to be created
1325 \return pointer on the group
1327 //=============================================================================
1328 SMESH::SMESH_Group_ptr
1329 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1330 const char* theName )
1331 throw (SALOME::SALOME_Exception)
1333 SMESH::SMESH_Group_var aResGrp;
1338 _preMeshInfo->FullLoadFromFile();
1341 return SMESH::SMESH_Group::_nil();
1343 // check types and get SMESHDS_GroupBase's
1344 SMESH::ElementType aType = SMESH::ALL;
1345 vector< SMESHDS_GroupBase* > groupVec;
1346 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1348 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1349 if ( CORBA::is_nil( aGrp ) )
1351 if ( aType == SMESH::ALL )
1352 aType = aGrp->GetType();
1353 else if ( aType != aGrp->GetType() )
1354 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1357 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1358 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1360 if ( grpDS->IsEmpty() )
1365 groupVec.push_back( grpDS );
1368 if ( aType == SMESH::ALL ) // all groups are nil
1369 return SMESH::SMESH_Group::_nil();
1374 aResGrp = CreateGroup( aType, theName );
1376 SMESHDS_Group* resGroupDS = 0;
1377 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1378 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1379 if ( !resGroupDS || groupVec.empty() )
1380 return aResGrp._retn();
1383 size_t i, nb = groupVec.size();
1384 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1385 while ( elemIt1->more() )
1387 const SMDS_MeshElement* e = elemIt1->next();
1389 for ( i = 1; ( i < nb && inAll ); ++i )
1390 inAll = groupVec[i]->Contains( e );
1393 resGroupDS->SMDSGroup().Add( e );
1396 // Update Python script
1397 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1398 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1400 SMESH_CATCH( SMESH::throwCorbaException );
1402 return aResGrp._retn();
1405 //=============================================================================
1407 * New group is created. All mesh elements that are present in
1408 * a main group but is not present in a tool group are added to the new one
1410 //=============================================================================
1412 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1413 SMESH::SMESH_GroupBase_ptr theGroup2,
1414 const char* theName )
1415 throw (SALOME::SALOME_Exception)
1417 SMESH::SMESH_Group_var aResGrp;
1422 _preMeshInfo->FullLoadFromFile();
1424 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1425 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1427 if ( theGroup1->GetType() != theGroup2->GetType() )
1428 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1432 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1433 if ( aResGrp->_is_nil() )
1434 return aResGrp._retn();
1436 SMESHDS_GroupBase* groupDS1 = 0;
1437 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1438 groupDS1 = grp_i->GetGroupDS();
1440 SMESHDS_GroupBase* groupDS2 = 0;
1441 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1442 groupDS2 = grp_i->GetGroupDS();
1444 SMESHDS_Group* resGroupDS = 0;
1445 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1446 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1448 if ( groupDS1 && groupDS2 && resGroupDS )
1450 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1451 while ( elemIt1->more() )
1453 const SMDS_MeshElement* e = elemIt1->next();
1454 if ( !groupDS2->Contains( e ))
1455 resGroupDS->SMDSGroup().Add( e );
1458 // Update Python script
1459 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1460 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1462 SMESH_CATCH( SMESH::throwCorbaException );
1464 return aResGrp._retn();
1467 //=============================================================================
1469 \brief Cut lists of groups. New group is created. All mesh elements that are
1470 present in main groups but do not present in tool groups are added to the new one
1471 \param theMainGroups list of main groups
1472 \param theToolGroups list of tool groups
1473 \param theName name of group to be created
1474 \return pointer on the group
1476 //=============================================================================
1477 SMESH::SMESH_Group_ptr
1478 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1479 const SMESH::ListOfGroups& theToolGroups,
1480 const char* theName )
1481 throw (SALOME::SALOME_Exception)
1483 SMESH::SMESH_Group_var aResGrp;
1488 _preMeshInfo->FullLoadFromFile();
1491 return SMESH::SMESH_Group::_nil();
1493 // check types and get SMESHDS_GroupBase's
1494 SMESH::ElementType aType = SMESH::ALL;
1495 vector< SMESHDS_GroupBase* > toolGroupVec;
1496 vector< SMDS_ElemIteratorPtr > mainIterVec;
1498 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1500 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1501 if ( CORBA::is_nil( aGrp ) )
1503 if ( aType == SMESH::ALL )
1504 aType = aGrp->GetType();
1505 else if ( aType != aGrp->GetType() )
1506 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1508 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1509 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1510 if ( !grpDS->IsEmpty() )
1511 mainIterVec.push_back( grpDS->GetElements() );
1513 if ( aType == SMESH::ALL ) // all main groups are nil
1514 return SMESH::SMESH_Group::_nil();
1515 if ( mainIterVec.empty() ) // all main groups are empty
1516 return aResGrp._retn();
1518 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1520 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1521 if ( CORBA::is_nil( aGrp ) )
1523 if ( aType != aGrp->GetType() )
1524 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1526 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1527 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1528 toolGroupVec.push_back( grpDS );
1534 aResGrp = CreateGroup( aType, theName );
1536 SMESHDS_Group* resGroupDS = 0;
1537 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1538 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1540 return aResGrp._retn();
1543 size_t i, nb = toolGroupVec.size();
1544 SMDS_ElemIteratorPtr mainElemIt
1545 ( new SMDS_IteratorOnIterators
1546 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1547 while ( mainElemIt->more() )
1549 const SMDS_MeshElement* e = mainElemIt->next();
1551 for ( i = 0; ( i < nb && !isIn ); ++i )
1552 isIn = toolGroupVec[i]->Contains( e );
1555 resGroupDS->SMDSGroup().Add( e );
1558 // Update Python script
1559 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1560 << ".CutListOfGroups( " << theMainGroups
1561 << theToolGroups << ", '" << theName << "' )";
1563 SMESH_CATCH( SMESH::throwCorbaException );
1565 return aResGrp._retn();
1568 //=============================================================================
1570 \brief Create groups of entities from existing groups of superior dimensions
1572 1) extract all nodes from each group,
1573 2) combine all elements of specified dimension laying on these nodes.
1574 \param theGroups list of source groups
1575 \param theElemType dimension of elements
1576 \param theName name of new group
1577 \return pointer on new group
1581 //=============================================================================
1583 SMESH::SMESH_Group_ptr
1584 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1585 SMESH::ElementType theElemType,
1586 const char* theName )
1587 throw (SALOME::SALOME_Exception)
1589 SMESH::SMESH_Group_var aResGrp;
1593 _preMeshInfo->FullLoadFromFile();
1595 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1597 if ( !theName || !aMeshDS )
1598 return SMESH::SMESH_Group::_nil();
1600 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1606 aResGrp = CreateGroup( theElemType, theName );
1607 if ( aResGrp->_is_nil() )
1608 return SMESH::SMESH_Group::_nil();
1610 SMESHDS_GroupBase* groupBaseDS =
1611 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1612 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1614 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1616 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1617 if ( CORBA::is_nil( aGrp ) )
1620 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1621 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1623 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1625 while ( elIt->more() ) {
1626 const SMDS_MeshElement* el = elIt->next();
1627 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1628 while ( nIt->more() )
1629 resGroupCore.Add( nIt->next() );
1632 else // get elements of theElemType based on nodes of every element of group
1634 while ( elIt->more() )
1636 const SMDS_MeshElement* el = elIt->next(); // an element of group
1637 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1638 TIDSortedElemSet checkedElems;
1639 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1640 while ( nIt->more() )
1642 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1643 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1644 // check nodes of elements of theElemType around el
1645 while ( elOfTypeIt->more() )
1647 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1648 if ( !checkedElems.insert( elOfType ).second ) continue;
1650 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1651 bool allNodesOK = true;
1652 while ( nIt2->more() && allNodesOK )
1653 allNodesOK = elNodes.count( nIt2->next() );
1655 resGroupCore.Add( elOfType );
1662 // Update Python script
1663 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1664 << ".CreateDimGroup( "
1665 << theGroups << ", " << theElemType << ", '" << theName << "' )";
1667 SMESH_CATCH( SMESH::throwCorbaException );
1669 return aResGrp._retn();
1672 //================================================================================
1674 * \brief Remember GEOM group data
1676 //================================================================================
1678 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1679 CORBA::Object_ptr theSmeshObj)
1681 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1684 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1685 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1686 if ( groupSO->_is_nil() )
1689 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1690 GEOM::GEOM_IGroupOperations_wrap groupOp =
1691 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1692 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1695 _geomGroupData.push_back( TGeomGroupData() );
1696 TGeomGroupData & groupData = _geomGroupData.back();
1698 CORBA::String_var entry = groupSO->GetID();
1699 groupData._groupEntry = entry.in();
1701 for ( int i = 0; i < ids->length(); ++i )
1702 groupData._indices.insert( ids[i] );
1704 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1707 //================================================================================
1709 * Remove GEOM group data relating to removed smesh object
1711 //================================================================================
1713 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1715 list<TGeomGroupData>::iterator
1716 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1717 for ( ; data != dataEnd; ++data ) {
1718 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1719 _geomGroupData.erase( data );
1725 //================================================================================
1727 * \brief Return new group contents if it has been changed and update group data
1729 //================================================================================
1731 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1733 TopoDS_Shape newShape;
1736 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1737 if ( study->_is_nil() ) return newShape; // means "not changed"
1738 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1739 if ( !groupSO->_is_nil() )
1741 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1742 if ( CORBA::is_nil( groupObj )) return newShape;
1743 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1745 // get indices of group items
1746 set<int> curIndices;
1747 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1748 GEOM::GEOM_IGroupOperations_wrap groupOp =
1749 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1750 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1751 for ( int i = 0; i < ids->length(); ++i )
1752 curIndices.insert( ids[i] );
1754 if ( groupData._indices == curIndices )
1755 return newShape; // group not changed
1758 groupData._indices = curIndices;
1760 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1761 if ( !geomClient ) return newShape;
1762 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1763 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1764 newShape = _gen_i->GeomObjectToShape( geomGroup );
1767 if ( newShape.IsNull() ) {
1768 // geom group becomes empty - return empty compound
1769 TopoDS_Compound compound;
1770 BRep_Builder().MakeCompound(compound);
1771 newShape = compound;
1778 //=============================================================================
1780 * \brief Storage of shape and index used in CheckGeomGroupModif()
1782 //=============================================================================
1783 struct TIndexedShape
1786 TopoDS_Shape _shape;
1787 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1790 //=============================================================================
1792 * \brief Update objects depending on changed geom groups
1794 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1795 * issue 0020210: Update of a smesh group after modification of the associated geom group
1797 //=============================================================================
1799 void SMESH_Mesh_i::CheckGeomGroupModif()
1801 if ( !_impl->HasShapeToMesh() ) return;
1803 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1804 if ( study->_is_nil() ) return;
1806 CORBA::Long nbEntities = NbNodes() + NbElements();
1808 // Check if group contents changed
1810 typedef map< string, TopoDS_Shape > TEntry2Geom;
1811 TEntry2Geom newGroupContents;
1813 list<TGeomGroupData>::iterator
1814 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1815 for ( ; data != dataEnd; ++data )
1817 pair< TEntry2Geom::iterator, bool > it_new =
1818 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1819 bool processedGroup = !it_new.second;
1820 TopoDS_Shape& newShape = it_new.first->second;
1821 if ( !processedGroup )
1822 newShape = newGroupShape( *data );
1823 if ( newShape.IsNull() )
1824 continue; // no changes
1827 _preMeshInfo->ForgetOrLoad();
1829 if ( processedGroup ) { // update group indices
1830 list<TGeomGroupData>::iterator data2 = data;
1831 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1832 data->_indices = data2->_indices;
1835 // Update SMESH objects according to new GEOM group contents
1837 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1838 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1840 int oldID = submesh->GetId();
1841 if ( !_mapSubMeshIor.count( oldID ))
1843 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1845 // update hypotheses
1846 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1847 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1848 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1850 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1851 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1853 // care of submeshes
1854 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1855 int newID = newSubmesh->GetId();
1856 if ( newID != oldID ) {
1857 _mapSubMesh [ newID ] = newSubmesh;
1858 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1859 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1860 _mapSubMesh. erase(oldID);
1861 _mapSubMesh_i. erase(oldID);
1862 _mapSubMeshIor.erase(oldID);
1863 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1868 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1869 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1870 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1872 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1874 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1875 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1876 ds->SetShape( newShape );
1881 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1882 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1884 // Remove groups and submeshes basing on removed sub-shapes
1886 TopTools_MapOfShape newShapeMap;
1887 TopoDS_Iterator shapeIt( newShape );
1888 for ( ; shapeIt.More(); shapeIt.Next() )
1889 newShapeMap.Add( shapeIt.Value() );
1891 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1892 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1894 if ( newShapeMap.Contains( shapeIt.Value() ))
1896 TopTools_IndexedMapOfShape oldShapeMap;
1897 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1898 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1900 const TopoDS_Shape& oldShape = oldShapeMap(i);
1901 int oldInd = meshDS->ShapeToIndex( oldShape );
1903 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1904 if ( i_smIor != _mapSubMeshIor.end() ) {
1905 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1908 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1909 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1911 // check if a group bases on oldInd shape
1912 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1913 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1914 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1915 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1917 RemoveGroup( i_grp->second ); // several groups can base on same shape
1918 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1923 // Reassign hypotheses and update groups after setting the new shape to mesh
1925 // collect anassigned hypotheses
1926 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1927 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1928 TShapeHypList assignedHyps;
1929 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1931 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1932 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1933 if ( !hyps.empty() ) {
1934 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1935 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1936 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1939 // collect shapes supporting groups
1940 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1941 TShapeTypeList groupData;
1942 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1943 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1944 for ( ; grIt != groups.end(); ++grIt )
1946 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1948 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1950 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1951 _impl->ShapeToMesh( newShape );
1953 // reassign hypotheses
1954 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1955 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1957 TIndexedShape& geom = indS_hyps->first;
1958 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1959 int oldID = geom._index;
1960 int newID = meshDS->ShapeToIndex( geom._shape );
1961 if ( oldID == 1 ) { // main shape
1963 geom._shape = newShape;
1967 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1968 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1969 // care of submeshes
1970 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1971 if ( newID != oldID ) {
1972 _mapSubMesh [ newID ] = newSubmesh;
1973 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1974 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1975 _mapSubMesh. erase(oldID);
1976 _mapSubMesh_i. erase(oldID);
1977 _mapSubMeshIor.erase(oldID);
1978 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1982 TShapeTypeList::iterator geomType = groupData.begin();
1983 for ( ; geomType != groupData.end(); ++geomType )
1985 const TIndexedShape& geom = geomType->first;
1986 int oldID = geom._index;
1987 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1990 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1991 CORBA::String_var name = groupSO->GetName();
1993 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1995 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1996 group_i->changeLocalId( newID );
1999 break; // everything has been updated
2002 } // loop on group data
2006 CORBA::Long newNbEntities = NbNodes() + NbElements();
2007 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2008 if ( newNbEntities != nbEntities )
2010 // Add all SObjects with icons to soToUpdateIcons
2011 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2013 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2014 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2015 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2017 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2018 i_gr != _mapGroups.end(); ++i_gr ) // groups
2019 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2022 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2023 for ( ; so != soToUpdateIcons.end(); ++so )
2024 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2027 //=============================================================================
2029 * \brief Create standalone group from a group on geometry or filter
2031 //=============================================================================
2033 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2034 throw (SALOME::SALOME_Exception)
2036 SMESH::SMESH_Group_var aGroup;
2041 _preMeshInfo->FullLoadFromFile();
2043 if ( theGroup->_is_nil() )
2044 return aGroup._retn();
2046 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2048 return aGroup._retn();
2050 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2052 const int anId = aGroupToRem->GetLocalID();
2053 if ( !_impl->ConvertToStandalone( anId ) )
2054 return aGroup._retn();
2055 removeGeomGroupData( theGroup );
2057 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2059 // remove old instance of group from own map
2060 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2061 _mapGroups.erase( anId );
2063 SALOMEDS::StudyBuilder_var builder;
2064 SALOMEDS::SObject_wrap aGroupSO;
2065 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2066 if ( !aStudy->_is_nil() ) {
2067 builder = aStudy->NewBuilder();
2068 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2069 if ( !aGroupSO->_is_nil() )
2071 // remove reference to geometry
2072 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2073 for ( ; chItr->More(); chItr->Next() )
2074 // Remove group's child SObject
2075 builder->RemoveObject( chItr->Value() );
2077 // Update Python script
2078 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2079 << ".ConvertToStandalone( " << aGroupSO << " )";
2081 // change icon of Group on Filter
2084 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2085 const int isEmpty = ( elemTypes->length() == 0 );
2088 SALOMEDS::GenericAttribute_wrap anAttr =
2089 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2090 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2091 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2097 // remember new group in own map
2098 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2099 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2101 // register CORBA object for persistence
2102 _gen_i->RegisterObject( aGroup );
2104 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2105 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2106 //aGroup->Register();
2107 aGroupToRem->UnRegister();
2109 SMESH_CATCH( SMESH::throwCorbaException );
2111 return aGroup._retn();
2114 //=============================================================================
2118 //=============================================================================
2120 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2122 if(MYDEBUG) MESSAGE( "createSubMesh" );
2123 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2124 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2125 const int subMeshId = mySubMesh->GetId();
2127 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2128 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2130 _mapSubMesh [subMeshId] = mySubMesh;
2131 _mapSubMesh_i [subMeshId] = subMeshServant;
2132 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2134 subMeshServant->Register();
2136 // register CORBA object for persistence
2137 int nextId = _gen_i->RegisterObject( subMesh );
2138 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2139 else { nextId = 0; } // avoid "unused variable" warning
2141 // to track changes of GEOM groups
2142 addGeomGroupData( theSubShapeObject, subMesh );
2144 return subMesh._retn();
2147 //=======================================================================
2148 //function : getSubMesh
2150 //=======================================================================
2152 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2154 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2155 if ( it == _mapSubMeshIor.end() )
2156 return SMESH::SMESH_subMesh::_nil();
2158 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2161 //=============================================================================
2165 //=============================================================================
2167 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2168 GEOM::GEOM_Object_ptr theSubShapeObject )
2170 bool isHypChanged = false;
2171 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2172 return isHypChanged;
2174 const int subMeshId = theSubMesh->GetId();
2176 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2178 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2180 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2183 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2184 isHypChanged = !hyps.empty();
2185 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2186 for ( ; hyp != hyps.end(); ++hyp )
2187 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2194 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2195 isHypChanged = ( aHypList->length() > 0 );
2196 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2197 removeHypothesis( theSubShapeObject, aHypList[i] );
2200 catch( const SALOME::SALOME_Exception& ) {
2201 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2203 removeGeomGroupData( theSubShapeObject );
2207 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2208 if ( id_smi != _mapSubMesh_i.end() )
2209 id_smi->second->UnRegister();
2211 // remove a CORBA object
2212 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2213 if ( id_smptr != _mapSubMeshIor.end() )
2214 SMESH::SMESH_subMesh_var( id_smptr->second );
2216 _mapSubMesh.erase(subMeshId);
2217 _mapSubMesh_i.erase(subMeshId);
2218 _mapSubMeshIor.erase(subMeshId);
2220 return isHypChanged;
2223 //=============================================================================
2227 //=============================================================================
2229 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2230 const char* theName,
2231 const TopoDS_Shape& theShape,
2232 const SMESH_PredicatePtr& thePredicate )
2234 std::string newName;
2235 if ( !theName || strlen( theName ) == 0 )
2237 std::set< std::string > presentNames;
2238 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2239 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2241 CORBA::String_var name = i_gr->second->GetName();
2242 presentNames.insert( name.in() );
2245 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2246 } while ( !presentNames.insert( newName ).second );
2247 theName = newName.c_str();
2250 SMESH::SMESH_GroupBase_var aGroup;
2251 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2253 SMESH_GroupBase_i* aGroupImpl;
2254 if ( !theShape.IsNull() )
2255 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2256 else if ( thePredicate )
2257 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2259 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2261 aGroup = aGroupImpl->_this();
2262 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2263 aGroupImpl->Register();
2265 // register CORBA object for persistence
2266 int nextId = _gen_i->RegisterObject( aGroup );
2267 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2268 else { nextId = 0; } // avoid "unused variable" warning in release mode
2270 // to track changes of GEOM groups
2271 if ( !theShape.IsNull() ) {
2272 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2273 addGeomGroupData( geom, aGroup );
2276 return aGroup._retn();
2279 //=============================================================================
2281 * SMESH_Mesh_i::removeGroup
2283 * Should be called by ~SMESH_Group_i()
2285 //=============================================================================
2287 void SMESH_Mesh_i::removeGroup( const int theId )
2289 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2290 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2291 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2292 _mapGroups.erase( theId );
2293 removeGeomGroupData( group );
2294 if ( !_impl->RemoveGroup( theId ))
2296 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2297 RemoveGroup( group );
2299 group->UnRegister();
2303 //=============================================================================
2307 //=============================================================================
2309 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2310 throw(SALOME::SALOME_Exception)
2312 SMESH::log_array_var aLog;
2316 _preMeshInfo->FullLoadFromFile();
2318 list < SMESHDS_Command * >logDS = _impl->GetLog();
2319 aLog = new SMESH::log_array;
2321 int lg = logDS.size();
2324 list < SMESHDS_Command * >::iterator its = logDS.begin();
2325 while(its != logDS.end()){
2326 SMESHDS_Command *com = *its;
2327 int comType = com->GetType();
2329 int lgcom = com->GetNumber();
2331 const list < int >&intList = com->GetIndexes();
2332 int inum = intList.size();
2334 list < int >::const_iterator ii = intList.begin();
2335 const list < double >&coordList = com->GetCoords();
2336 int rnum = coordList.size();
2338 list < double >::const_iterator ir = coordList.begin();
2339 aLog[indexLog].commandType = comType;
2340 aLog[indexLog].number = lgcom;
2341 aLog[indexLog].coords.length(rnum);
2342 aLog[indexLog].indexes.length(inum);
2343 for(int i = 0; i < rnum; i++){
2344 aLog[indexLog].coords[i] = *ir;
2345 //MESSAGE(" "<<i<<" "<<ir.Value());
2348 for(int i = 0; i < inum; i++){
2349 aLog[indexLog].indexes[i] = *ii;
2350 //MESSAGE(" "<<i<<" "<<ii.Value());
2359 SMESH_CATCH( SMESH::throwCorbaException );
2361 return aLog._retn();
2365 //=============================================================================
2369 //=============================================================================
2371 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2375 SMESH_CATCH( SMESH::throwCorbaException );
2378 //=============================================================================
2382 //=============================================================================
2384 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2389 //=============================================================================
2393 //=============================================================================
2395 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2400 //=============================================================================
2403 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2404 // issue 0020918: groups removal is caused by hyp modification
2405 // issue 0021208: to forget not loaded mesh data at hyp modification
2406 struct TCallUp_i : public SMESH_Mesh::TCallUp
2408 SMESH_Mesh_i* _mesh;
2409 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2410 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2411 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2412 virtual void Load () { _mesh->Load(); }
2416 //================================================================================
2418 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2420 //================================================================================
2422 void SMESH_Mesh_i::onHypothesisModified()
2425 _preMeshInfo->ForgetOrLoad();
2428 //=============================================================================
2432 //=============================================================================
2434 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2436 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2439 _impl->SetCallUp( new TCallUp_i(this));
2442 //=============================================================================
2446 //=============================================================================
2448 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2450 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2454 //=============================================================================
2456 * Return mesh editor
2458 //=============================================================================
2460 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2461 throw (SALOME::SALOME_Exception)
2463 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2467 _preMeshInfo->FullLoadFromFile();
2469 // Create MeshEditor
2471 _editor = new SMESH_MeshEditor_i( this, false );
2472 aMeshEdVar = _editor->_this();
2474 // Update Python script
2475 TPythonDump() << _editor << " = "
2476 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2478 SMESH_CATCH( SMESH::throwCorbaException );
2480 return aMeshEdVar._retn();
2483 //=============================================================================
2485 * Return mesh edition previewer
2487 //=============================================================================
2489 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2490 throw (SALOME::SALOME_Exception)
2492 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2496 _preMeshInfo->FullLoadFromFile();
2498 if ( !_previewEditor )
2499 _previewEditor = new SMESH_MeshEditor_i( this, true );
2500 aMeshEdVar = _previewEditor->_this();
2502 SMESH_CATCH( SMESH::throwCorbaException );
2504 return aMeshEdVar._retn();
2507 //================================================================================
2509 * \brief Return true if the mesh has been edited since a last total re-compute
2510 * and those modifications may prevent successful partial re-compute
2512 //================================================================================
2514 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2516 Unexpect aCatch(SALOME_SalomeException);
2517 return _impl->HasModificationsToDiscard();
2520 //================================================================================
2522 * \brief Returns a random unique color
2524 //================================================================================
2526 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2528 const int MAX_ATTEMPTS = 100;
2530 double tolerance = 0.5;
2531 SALOMEDS::Color col;
2535 // generate random color
2536 double red = (double)rand() / RAND_MAX;
2537 double green = (double)rand() / RAND_MAX;
2538 double blue = (double)rand() / RAND_MAX;
2539 // check existence in the list of the existing colors
2540 bool matched = false;
2541 std::list<SALOMEDS::Color>::const_iterator it;
2542 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2543 SALOMEDS::Color color = *it;
2544 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2545 matched = tol < tolerance;
2547 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2548 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2556 //=============================================================================
2558 * Sets auto-color mode. If it is on, groups get unique random colors
2560 //=============================================================================
2562 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2564 Unexpect aCatch(SALOME_SalomeException);
2565 _impl->SetAutoColor(theAutoColor);
2567 TPythonDump pyDump; // not to dump group->SetColor() from below code
2568 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2570 std::list<SALOMEDS::Color> aReservedColors;
2571 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2572 for ( ; it != _mapGroups.end(); it++ ) {
2573 if ( CORBA::is_nil( it->second )) continue;
2574 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2575 it->second->SetColor( aColor );
2576 aReservedColors.push_back( aColor );
2580 //=============================================================================
2582 * Returns true if auto-color mode is on
2584 //=============================================================================
2586 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2588 Unexpect aCatch(SALOME_SalomeException);
2589 return _impl->GetAutoColor();
2592 //=============================================================================
2594 * Checks if there are groups with equal names
2596 //=============================================================================
2598 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2600 return _impl->HasDuplicatedGroupNamesMED();
2603 //================================================================================
2605 * \brief Care of a file before exporting mesh into it
2607 //================================================================================
2609 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2611 TCollection_AsciiString aFullName ((char*)file);
2612 OSD_Path aPath (aFullName);
2613 OSD_File aFile (aPath);
2614 if (aFile.Exists()) {
2615 // existing filesystem node
2616 if (aFile.KindOfFile() == OSD_FILE) {
2617 if (aFile.IsWriteable()) {
2622 if (aFile.Failed()) {
2623 TCollection_AsciiString msg ("File ");
2624 msg += aFullName + " cannot be replaced.";
2625 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2628 TCollection_AsciiString msg ("File ");
2629 msg += aFullName + " cannot be overwritten.";
2630 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2633 TCollection_AsciiString msg ("Location ");
2634 msg += aFullName + " is not a file.";
2635 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2638 // nonexisting file; check if it can be created
2640 aFile.Build(OSD_WriteOnly, OSD_Protection());
2641 if (aFile.Failed()) {
2642 TCollection_AsciiString msg ("You cannot create the file ");
2643 msg += aFullName + ". Check the directory existance and access rights.";
2644 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2652 //================================================================================
2654 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2655 * \param file - file name
2656 * \param overwrite - to erase the file or not
2657 * \retval string - mesh name
2659 //================================================================================
2661 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2662 CORBA::Boolean overwrite)
2665 PrepareForWriting(file, overwrite);
2666 string aMeshName = "Mesh";
2667 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2668 if ( !aStudy->_is_nil() ) {
2669 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2670 if ( !aMeshSO->_is_nil() ) {
2671 CORBA::String_var name = aMeshSO->GetName();
2673 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2674 if ( !aStudy->GetProperties()->IsLocked() )
2676 SALOMEDS::GenericAttribute_wrap anAttr;
2677 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2678 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2679 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2680 ASSERT(!aFileName->_is_nil());
2681 aFileName->SetValue(file);
2682 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2683 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2684 ASSERT(!aFileType->_is_nil());
2685 aFileType->SetValue("FICHIERMED");
2689 // Update Python script
2690 // set name of mesh before export
2691 TPythonDump() << _gen_i << ".SetName("
2692 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2694 // check names of groups
2700 //================================================================================
2702 * \brief Export to med file
2704 //================================================================================
2706 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2707 CORBA::Boolean auto_groups,
2708 SMESH::MED_VERSION theVersion,
2709 CORBA::Boolean overwrite,
2710 CORBA::Boolean autoDimension)
2711 throw(SALOME::SALOME_Exception)
2715 _preMeshInfo->FullLoadFromFile();
2717 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2718 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2719 << file << "', " << auto_groups << ", "
2720 << theVersion << ", " << overwrite << ", "
2721 << autoDimension << " )";
2723 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2725 SMESH_CATCH( SMESH::throwCorbaException );
2728 //================================================================================
2730 * \brief Export a mesh to a med file
2732 //================================================================================
2734 void SMESH_Mesh_i::ExportToMED (const char* file,
2735 CORBA::Boolean auto_groups,
2736 SMESH::MED_VERSION theVersion)
2737 throw(SALOME::SALOME_Exception)
2739 ExportToMEDX(file,auto_groups,theVersion,true);
2742 //================================================================================
2744 * \brief Export a mesh to a med file
2746 //================================================================================
2748 void SMESH_Mesh_i::ExportMED (const char* file,
2749 CORBA::Boolean auto_groups)
2750 throw(SALOME::SALOME_Exception)
2752 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2755 //================================================================================
2757 * \brief Export a mesh to a SAUV file
2759 //================================================================================
2761 void SMESH_Mesh_i::ExportSAUV (const char* file,
2762 CORBA::Boolean auto_groups)
2763 throw(SALOME::SALOME_Exception)
2765 Unexpect aCatch(SALOME_SalomeException);
2767 _preMeshInfo->FullLoadFromFile();
2769 string aMeshName = prepareMeshNameAndGroups(file, true);
2770 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2771 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2772 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2776 //================================================================================
2778 * \brief Export a mesh to a DAT file
2780 //================================================================================
2782 void SMESH_Mesh_i::ExportDAT (const char *file)
2783 throw(SALOME::SALOME_Exception)
2785 Unexpect aCatch(SALOME_SalomeException);
2787 _preMeshInfo->FullLoadFromFile();
2789 // Update Python script
2790 // check names of groups
2792 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2795 PrepareForWriting(file);
2796 _impl->ExportDAT(file);
2799 //================================================================================
2801 * \brief Export a mesh to an UNV file
2803 //================================================================================
2805 void SMESH_Mesh_i::ExportUNV (const char *file)
2806 throw(SALOME::SALOME_Exception)
2808 Unexpect aCatch(SALOME_SalomeException);
2810 _preMeshInfo->FullLoadFromFile();
2812 // Update Python script
2813 // check names of groups
2815 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2818 PrepareForWriting(file);
2819 _impl->ExportUNV(file);
2822 //================================================================================
2824 * \brief Export a mesh to an STL file
2826 //================================================================================
2828 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2829 throw(SALOME::SALOME_Exception)
2831 Unexpect aCatch(SALOME_SalomeException);
2833 _preMeshInfo->FullLoadFromFile();
2835 // Update Python script
2836 // check names of groups
2838 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2839 << ".ExportSTL( r'" << file << "', " << isascii << " )";
2842 PrepareForWriting(file);
2843 _impl->ExportSTL(file, isascii);
2846 //================================================================================
2848 * \brief Export a part of mesh to a med file
2850 //================================================================================
2852 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2854 CORBA::Boolean auto_groups,
2855 ::SMESH::MED_VERSION version,
2856 ::CORBA::Boolean overwrite,
2857 ::CORBA::Boolean autoDimension)
2858 throw (SALOME::SALOME_Exception)
2860 Unexpect aCatch(SALOME_SalomeException);
2863 if ( SMESH_Mesh_i * mesh = SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
2865 mesh->ExportToMEDX( file, auto_groups, version, autoDimension );
2870 _preMeshInfo->FullLoadFromFile();
2872 PrepareForWriting(file, overwrite);
2874 string aMeshName = "Mesh";
2875 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2876 if ( !aStudy->_is_nil() ) {
2877 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2878 if ( !SO->_is_nil() ) {
2879 CORBA::String_var name = SO->GetName();
2883 SMESH_MeshPartDS partDS( meshPart );
2884 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS, autoDimension );
2886 pyDump << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToMED( "
2887 << meshPart << ", r'" << file << "', "
2888 << auto_groups << ", " << version << ", " << overwrite << ", "
2889 << autoDimension << " )";
2892 //================================================================================
2894 * \brief Export a part of mesh to a DAT file
2896 //================================================================================
2898 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2900 throw (SALOME::SALOME_Exception)
2902 Unexpect aCatch(SALOME_SalomeException);
2904 _preMeshInfo->FullLoadFromFile();
2906 PrepareForWriting(file);
2908 SMESH_MeshPartDS partDS( meshPart );
2909 _impl->ExportDAT(file,&partDS);
2911 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2912 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2914 //================================================================================
2916 * \brief Export a part of mesh to an UNV file
2918 //================================================================================
2920 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2922 throw (SALOME::SALOME_Exception)
2924 Unexpect aCatch(SALOME_SalomeException);
2926 _preMeshInfo->FullLoadFromFile();
2928 PrepareForWriting(file);
2930 SMESH_MeshPartDS partDS( meshPart );
2931 _impl->ExportUNV(file, &partDS);
2933 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2934 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2936 //================================================================================
2938 * \brief Export a part of mesh to an STL file
2940 //================================================================================
2942 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2944 ::CORBA::Boolean isascii)
2945 throw (SALOME::SALOME_Exception)
2947 Unexpect aCatch(SALOME_SalomeException);
2949 _preMeshInfo->FullLoadFromFile();
2951 PrepareForWriting(file);
2953 SMESH_MeshPartDS partDS( meshPart );
2954 _impl->ExportSTL(file, isascii, &partDS);
2956 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
2957 << meshPart<< ", r'" << file << "', " << isascii << ")";
2960 //================================================================================
2962 * \brief Export a part of mesh to an STL file
2964 //================================================================================
2966 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2968 CORBA::Boolean overwrite)
2969 throw (SALOME::SALOME_Exception)
2972 Unexpect aCatch(SALOME_SalomeException);
2974 _preMeshInfo->FullLoadFromFile();
2976 PrepareForWriting(file,overwrite);
2978 SMESH_MeshPartDS partDS( meshPart );
2979 _impl->ExportCGNS(file, &partDS);
2981 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
2982 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2984 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2988 //================================================================================
2990 * \brief Export a part of mesh to a GMF file
2992 //================================================================================
2994 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
2996 bool withRequiredGroups)
2997 throw (SALOME::SALOME_Exception)
2999 Unexpect aCatch(SALOME_SalomeException);
3001 _preMeshInfo->FullLoadFromFile();
3003 PrepareForWriting(file,/*overwrite=*/true);
3005 SMESH_MeshPartDS partDS( meshPart );
3006 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3008 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3009 << meshPart<< ", r'"
3011 << withRequiredGroups << ")";
3014 //=============================================================================
3016 * Return computation progress [0.,1]
3018 //=============================================================================
3020 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3024 return _impl->GetComputeProgress();
3026 SMESH_CATCH( SMESH::doNothing );
3030 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3032 Unexpect aCatch(SALOME_SalomeException);
3034 return _preMeshInfo->NbNodes();
3036 return _impl->NbNodes();
3039 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3041 Unexpect aCatch(SALOME_SalomeException);
3043 return _preMeshInfo->NbElements();
3045 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3048 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3050 Unexpect aCatch(SALOME_SalomeException);
3052 return _preMeshInfo->Nb0DElements();
3054 return _impl->Nb0DElements();
3057 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3059 Unexpect aCatch(SALOME_SalomeException);
3061 return _preMeshInfo->NbBalls();
3063 return _impl->NbBalls();
3066 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3068 Unexpect aCatch(SALOME_SalomeException);
3070 return _preMeshInfo->NbEdges();
3072 return _impl->NbEdges();
3075 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3076 throw(SALOME::SALOME_Exception)
3078 Unexpect aCatch(SALOME_SalomeException);
3080 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3082 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3085 //=============================================================================
3087 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3089 Unexpect aCatch(SALOME_SalomeException);
3091 return _preMeshInfo->NbFaces();
3093 return _impl->NbFaces();
3096 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3098 Unexpect aCatch(SALOME_SalomeException);
3100 return _preMeshInfo->NbTriangles();
3102 return _impl->NbTriangles();
3105 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3107 Unexpect aCatch(SALOME_SalomeException);
3109 return _preMeshInfo->NbBiQuadTriangles();
3111 return _impl->NbBiQuadTriangles();
3114 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3116 Unexpect aCatch(SALOME_SalomeException);
3118 return _preMeshInfo->NbQuadrangles();
3120 return _impl->NbQuadrangles();
3123 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3125 Unexpect aCatch(SALOME_SalomeException);
3127 return _preMeshInfo->NbBiQuadQuadrangles();
3129 return _impl->NbBiQuadQuadrangles();
3132 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3134 Unexpect aCatch(SALOME_SalomeException);
3136 return _preMeshInfo->NbPolygons();
3138 return _impl->NbPolygons();
3141 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3142 throw(SALOME::SALOME_Exception)
3144 Unexpect aCatch(SALOME_SalomeException);
3146 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3148 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3151 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3152 throw(SALOME::SALOME_Exception)
3154 Unexpect aCatch(SALOME_SalomeException);
3156 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3158 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3161 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3162 throw(SALOME::SALOME_Exception)
3164 Unexpect aCatch(SALOME_SalomeException);
3166 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3168 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3171 //=============================================================================
3173 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3175 Unexpect aCatch(SALOME_SalomeException);
3177 return _preMeshInfo->NbVolumes();
3179 return _impl->NbVolumes();
3182 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3184 Unexpect aCatch(SALOME_SalomeException);
3186 return _preMeshInfo->NbTetras();
3188 return _impl->NbTetras();
3191 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3193 Unexpect aCatch(SALOME_SalomeException);
3195 return _preMeshInfo->NbHexas();
3197 return _impl->NbHexas();
3200 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3202 Unexpect aCatch(SALOME_SalomeException);
3204 return _preMeshInfo->NbTriQuadHexas();
3206 return _impl->NbTriQuadraticHexas();
3209 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3211 Unexpect aCatch(SALOME_SalomeException);
3213 return _preMeshInfo->NbPyramids();
3215 return _impl->NbPyramids();
3218 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3220 Unexpect aCatch(SALOME_SalomeException);
3222 return _preMeshInfo->NbPrisms();
3224 return _impl->NbPrisms();
3227 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3229 Unexpect aCatch(SALOME_SalomeException);
3231 return _preMeshInfo->NbHexPrisms();
3233 return _impl->NbHexagonalPrisms();
3236 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3238 Unexpect aCatch(SALOME_SalomeException);
3240 return _preMeshInfo->NbPolyhedrons();
3242 return _impl->NbPolyhedrons();
3245 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3246 throw(SALOME::SALOME_Exception)
3248 Unexpect aCatch(SALOME_SalomeException);
3250 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3252 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3255 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3256 throw(SALOME::SALOME_Exception)
3258 Unexpect aCatch(SALOME_SalomeException);
3260 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3262 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3265 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3266 throw(SALOME::SALOME_Exception)
3268 Unexpect aCatch(SALOME_SalomeException);
3270 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3272 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3275 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3276 throw(SALOME::SALOME_Exception)
3278 Unexpect aCatch(SALOME_SalomeException);
3280 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3282 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3285 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3286 throw(SALOME::SALOME_Exception)
3288 Unexpect aCatch(SALOME_SalomeException);
3290 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3292 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3295 //=============================================================================
3297 * Returns nb of published sub-meshes
3299 //=============================================================================
3301 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3303 Unexpect aCatch(SALOME_SalomeException);
3304 return _mapSubMesh_i.size();
3307 //=============================================================================
3309 * Dumps mesh into a string
3311 //=============================================================================
3313 char* SMESH_Mesh_i::Dump()
3317 return CORBA::string_dup( os.str().c_str() );
3320 //=============================================================================
3322 * Method of SMESH_IDSource interface
3324 //=============================================================================
3326 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3328 return GetElementsId();
3331 //=============================================================================
3333 * Returns ids of all elements
3335 //=============================================================================
3337 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3338 throw (SALOME::SALOME_Exception)
3340 Unexpect aCatch(SALOME_SalomeException);
3342 _preMeshInfo->FullLoadFromFile();
3344 SMESH::long_array_var aResult = new SMESH::long_array();
3345 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3347 if ( aSMESHDS_Mesh == NULL )
3348 return aResult._retn();
3350 long nbElements = NbElements();
3351 aResult->length( nbElements );
3352 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3353 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3354 aResult[i] = anIt->next()->GetID();
3356 return aResult._retn();
3360 //=============================================================================
3362 * Returns ids of all elements of given type
3364 //=============================================================================
3366 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3367 throw (SALOME::SALOME_Exception)
3369 Unexpect aCatch(SALOME_SalomeException);
3371 _preMeshInfo->FullLoadFromFile();
3373 SMESH::long_array_var aResult = new SMESH::long_array();
3374 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3376 if ( aSMESHDS_Mesh == NULL )
3377 return aResult._retn();
3379 long nbElements = NbElements();
3381 // No sense in returning ids of elements along with ids of nodes:
3382 // when theElemType == SMESH::ALL, return node ids only if
3383 // there are no elements
3384 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3385 return GetNodesId();
3387 aResult->length( nbElements );
3391 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3392 while ( i < nbElements && anIt->more() )
3393 aResult[i++] = anIt->next()->GetID();
3395 aResult->length( i );
3397 return aResult._retn();
3400 //=============================================================================
3402 * Returns ids of all nodes
3404 //=============================================================================
3406 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3407 throw (SALOME::SALOME_Exception)
3409 Unexpect aCatch(SALOME_SalomeException);
3411 _preMeshInfo->FullLoadFromFile();
3413 SMESH::long_array_var aResult = new SMESH::long_array();
3414 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3416 if ( aSMESHDS_Mesh == NULL )
3417 return aResult._retn();
3419 long nbNodes = NbNodes();
3420 aResult->length( nbNodes );
3421 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3422 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3423 aResult[i] = anIt->next()->GetID();
3425 return aResult._retn();
3428 //=============================================================================
3432 //=============================================================================
3434 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3435 throw (SALOME::SALOME_Exception)
3437 SMESH::ElementType type;
3441 _preMeshInfo->FullLoadFromFile();
3443 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3445 SMESH_CATCH( SMESH::throwCorbaException );
3450 //=============================================================================
3454 //=============================================================================
3456 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3457 throw (SALOME::SALOME_Exception)
3460 _preMeshInfo->FullLoadFromFile();
3462 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3464 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3466 return ( SMESH::EntityType ) e->GetEntityType();
3469 //=============================================================================
3471 * Returns ID of elements for given submesh
3473 //=============================================================================
3474 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3475 throw (SALOME::SALOME_Exception)
3477 SMESH::long_array_var aResult = new SMESH::long_array();
3481 _preMeshInfo->FullLoadFromFile();
3483 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3484 if(!SM) return aResult._retn();
3486 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3487 if(!SDSM) return aResult._retn();
3489 aResult->length(SDSM->NbElements());
3491 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3493 while ( eIt->more() ) {
3494 aResult[i++] = eIt->next()->GetID();
3497 SMESH_CATCH( SMESH::throwCorbaException );
3499 return aResult._retn();
3502 //=============================================================================
3504 * Returns ID of nodes for given submesh
3505 * If param all==true - returns all nodes, else -
3506 * returns only nodes on shapes.
3508 //=============================================================================
3510 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3512 throw (SALOME::SALOME_Exception)
3514 SMESH::long_array_var aResult = new SMESH::long_array();
3518 _preMeshInfo->FullLoadFromFile();
3520 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3521 if(!SM) return aResult._retn();
3523 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3524 if(!SDSM) return aResult._retn();
3527 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3528 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3529 while ( nIt->more() ) {
3530 const SMDS_MeshNode* elem = nIt->next();
3531 theElems.insert( elem->GetID() );
3534 else { // all nodes of submesh elements
3535 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3536 while ( eIt->more() ) {
3537 const SMDS_MeshElement* anElem = eIt->next();
3538 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3539 while ( nIt->more() ) {
3540 const SMDS_MeshElement* elem = nIt->next();
3541 theElems.insert( elem->GetID() );
3546 aResult->length(theElems.size());
3547 set<int>::iterator itElem;
3549 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3550 aResult[i++] = *itElem;
3552 SMESH_CATCH( SMESH::throwCorbaException );
3554 return aResult._retn();
3557 //=============================================================================
3559 * Returns type of elements for given submesh
3561 //=============================================================================
3563 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3564 throw (SALOME::SALOME_Exception)
3566 SMESH::ElementType type;
3570 _preMeshInfo->FullLoadFromFile();
3572 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3573 if(!SM) return SMESH::ALL;
3575 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3576 if(!SDSM) return SMESH::ALL;
3578 if(SDSM->NbElements()==0)
3579 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3581 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3582 const SMDS_MeshElement* anElem = eIt->next();
3584 type = ( SMESH::ElementType ) anElem->GetType();
3586 SMESH_CATCH( SMESH::throwCorbaException );
3592 //=============================================================================
3594 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3596 //=============================================================================
3598 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3601 _preMeshInfo->FullLoadFromFile();
3603 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3605 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3610 //=============================================================================
3612 * Get XYZ coordinates of node as list of double
3613 * If there is not node for given ID - returns empty list
3615 //=============================================================================
3617 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3620 _preMeshInfo->FullLoadFromFile();
3622 SMESH::double_array_var aResult = new SMESH::double_array();
3623 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3624 if ( aSMESHDS_Mesh == NULL )
3625 return aResult._retn();
3628 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3630 return aResult._retn();
3634 aResult[0] = aNode->X();
3635 aResult[1] = aNode->Y();
3636 aResult[2] = aNode->Z();
3637 return aResult._retn();
3641 //=============================================================================
3643 * For given node returns list of IDs of inverse elements
3644 * If there is not node for given ID - returns empty list
3646 //=============================================================================
3648 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3651 _preMeshInfo->FullLoadFromFile();
3653 SMESH::long_array_var aResult = new SMESH::long_array();
3654 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3655 if ( aSMESHDS_Mesh == NULL )
3656 return aResult._retn();
3659 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3661 return aResult._retn();
3663 // find inverse elements
3664 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3665 TColStd_SequenceOfInteger IDs;
3666 while(eIt->more()) {
3667 const SMDS_MeshElement* elem = eIt->next();
3668 IDs.Append(elem->GetID());
3670 if(IDs.Length()>0) {
3671 aResult->length(IDs.Length());
3673 for(; i<=IDs.Length(); i++) {
3674 aResult[i-1] = IDs.Value(i);
3677 return aResult._retn();
3680 //=============================================================================
3682 * \brief Return position of a node on shape
3684 //=============================================================================
3686 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3689 _preMeshInfo->FullLoadFromFile();
3691 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3692 aNodePosition->shapeID = 0;
3693 aNodePosition->shapeType = GEOM::SHAPE;
3695 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3696 if ( !mesh ) return aNodePosition;
3698 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3700 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3702 aNodePosition->shapeID = aNode->getshapeId();
3703 switch ( pos->GetTypeOfPosition() ) {
3705 aNodePosition->shapeType = GEOM::EDGE;
3706 aNodePosition->params.length(1);
3707 aNodePosition->params[0] =
3708 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3711 aNodePosition->shapeType = GEOM::FACE;
3712 aNodePosition->params.length(2);
3713 aNodePosition->params[0] =
3714 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3715 aNodePosition->params[1] =
3716 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3718 case SMDS_TOP_VERTEX:
3719 aNodePosition->shapeType = GEOM::VERTEX;
3721 case SMDS_TOP_3DSPACE:
3722 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3723 aNodePosition->shapeType = GEOM::SOLID;
3724 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3725 aNodePosition->shapeType = GEOM::SHELL;
3731 return aNodePosition;
3734 //=============================================================================
3736 * \brief Return position of an element on shape
3738 //=============================================================================
3740 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
3743 _preMeshInfo->FullLoadFromFile();
3745 SMESH::ElementPosition anElementPosition;
3746 anElementPosition.shapeID = 0;
3747 anElementPosition.shapeType = GEOM::SHAPE;
3749 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3750 if ( !mesh ) return anElementPosition;
3752 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
3754 anElementPosition.shapeID = anElem->getshapeId();
3755 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
3756 if ( !aSp.IsNull() ) {
3757 switch ( aSp.ShapeType() ) {
3759 anElementPosition.shapeType = GEOM::EDGE;
3762 anElementPosition.shapeType = GEOM::FACE;
3765 anElementPosition.shapeType = GEOM::VERTEX;
3768 anElementPosition.shapeType = GEOM::SOLID;
3771 anElementPosition.shapeType = GEOM::SHELL;
3777 return anElementPosition;
3780 //=============================================================================
3782 * If given element is node returns IDs of shape from position
3783 * If there is not node for given ID - returns -1
3785 //=============================================================================
3787 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3790 _preMeshInfo->FullLoadFromFile();
3792 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3793 if ( aSMESHDS_Mesh == NULL )
3797 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3799 return aNode->getshapeId();
3806 //=============================================================================
3808 * For given element returns ID of result shape after
3809 * ::FindShape() from SMESH_MeshEditor
3810 * If there is not element for given ID - returns -1
3812 //=============================================================================
3814 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3817 _preMeshInfo->FullLoadFromFile();
3819 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3820 if ( aSMESHDS_Mesh == NULL )
3823 // try to find element
3824 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3828 ::SMESH_MeshEditor aMeshEditor(_impl);
3829 int index = aMeshEditor.FindShape( elem );
3837 //=============================================================================
3839 * Returns number of nodes for given element
3840 * If there is not element for given ID - returns -1
3842 //=============================================================================
3844 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3847 _preMeshInfo->FullLoadFromFile();
3849 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3850 if ( aSMESHDS_Mesh == NULL ) return -1;
3851 // try to find element
3852 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3853 if(!elem) return -1;
3854 return elem->NbNodes();
3858 //=============================================================================
3860 * Returns ID of node by given index for given element
3861 * If there is not element for given ID - returns -1
3862 * If there is not node for given index - returns -2
3864 //=============================================================================
3866 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3869 _preMeshInfo->FullLoadFromFile();
3871 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3872 if ( aSMESHDS_Mesh == NULL ) return -1;
3873 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3874 if(!elem) return -1;
3875 if( index>=elem->NbNodes() || index<0 ) return -1;
3876 return elem->GetNode(index)->GetID();
3879 //=============================================================================
3881 * Returns IDs of nodes of given element
3883 //=============================================================================
3885 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3888 _preMeshInfo->FullLoadFromFile();
3890 SMESH::long_array_var aResult = new SMESH::long_array();
3891 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3893 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3895 aResult->length( elem->NbNodes() );
3896 for ( int i = 0; i < elem->NbNodes(); ++i )
3897 aResult[ i ] = elem->GetNode( i )->GetID();
3900 return aResult._retn();
3903 //=============================================================================
3905 * Returns true if given node is medium node
3906 * in given quadratic element
3908 //=============================================================================
3910 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3913 _preMeshInfo->FullLoadFromFile();
3915 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3916 if ( aSMESHDS_Mesh == NULL ) return false;
3918 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3919 if(!aNode) return false;
3920 // try to find element
3921 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3922 if(!elem) return false;
3924 return elem->IsMediumNode(aNode);
3928 //=============================================================================
3930 * Returns true if given node is medium node
3931 * in one of quadratic elements
3933 //=============================================================================
3935 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3936 SMESH::ElementType theElemType)
3939 _preMeshInfo->FullLoadFromFile();
3941 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3942 if ( aSMESHDS_Mesh == NULL ) return false;
3945 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3946 if(!aNode) return false;
3948 SMESH_MesherHelper aHelper( *(_impl) );
3950 SMDSAbs_ElementType aType;
3951 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3952 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3953 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3954 else aType = SMDSAbs_All;
3956 return aHelper.IsMedium(aNode,aType);
3960 //=============================================================================
3962 * Returns number of edges for given element
3964 //=============================================================================
3966 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3969 _preMeshInfo->FullLoadFromFile();
3971 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3972 if ( aSMESHDS_Mesh == NULL ) return -1;
3973 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3974 if(!elem) return -1;
3975 return elem->NbEdges();
3979 //=============================================================================
3981 * Returns number of faces for given element
3983 //=============================================================================
3985 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3988 _preMeshInfo->FullLoadFromFile();
3990 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3991 if ( aSMESHDS_Mesh == NULL ) return -1;
3992 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3993 if(!elem) return -1;
3994 return elem->NbFaces();
3997 //=======================================================================
3998 //function : GetElemFaceNodes
3999 //purpose : Returns nodes of given face (counted from zero) for given element.
4000 //=======================================================================
4002 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4003 CORBA::Short faceIndex)
4006 _preMeshInfo->FullLoadFromFile();
4008 SMESH::long_array_var aResult = new SMESH::long_array();
4009 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4011 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4013 SMDS_VolumeTool vtool( elem );
4014 if ( faceIndex < vtool.NbFaces() )
4016 aResult->length( vtool.NbFaceNodes( faceIndex ));
4017 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4018 for ( int i = 0; i < aResult->length(); ++i )
4019 aResult[ i ] = nn[ i ]->GetID();
4023 return aResult._retn();
4026 //=======================================================================
4027 //function : FindElementByNodes
4028 //purpose : Returns an element based on all given nodes.
4029 //=======================================================================
4031 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4034 _preMeshInfo->FullLoadFromFile();
4036 CORBA::Long elemID(0);
4037 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4039 vector< const SMDS_MeshNode * > nn( nodes.length() );
4040 for ( int i = 0; i < nodes.length(); ++i )
4041 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4044 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4045 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4046 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4047 _impl->NbVolumes( ORDER_QUADRATIC )))
4048 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4050 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4055 //=============================================================================
4057 * Returns true if given element is polygon
4059 //=============================================================================
4061 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4064 _preMeshInfo->FullLoadFromFile();
4066 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4067 if ( aSMESHDS_Mesh == NULL ) return false;
4068 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4069 if(!elem) return false;
4070 return elem->IsPoly();
4074 //=============================================================================
4076 * Returns true if given element is quadratic
4078 //=============================================================================
4080 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4083 _preMeshInfo->FullLoadFromFile();
4085 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4086 if ( aSMESHDS_Mesh == NULL ) return false;
4087 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4088 if(!elem) return false;
4089 return elem->IsQuadratic();
4092 //=============================================================================
4094 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4096 //=============================================================================
4098 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4101 _preMeshInfo->FullLoadFromFile();
4103 if ( const SMDS_BallElement* ball =
4104 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4105 return ball->GetDiameter();
4110 //=============================================================================
4112 * Returns bary center for given element
4114 //=============================================================================
4116 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4119 _preMeshInfo->FullLoadFromFile();
4121 SMESH::double_array_var aResult = new SMESH::double_array();
4122 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4123 if ( aSMESHDS_Mesh == NULL )
4124 return aResult._retn();
4126 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4128 return aResult._retn();
4130 if(elem->GetType()==SMDSAbs_Volume) {
4131 SMDS_VolumeTool aTool;
4132 if(aTool.Set(elem)) {
4134 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4139 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4141 double x=0., y=0., z=0.;
4142 for(; anIt->more(); ) {
4144 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4158 return aResult._retn();
4161 //================================================================================
4163 * \brief Create a group of elements preventing computation of a sub-shape
4165 //================================================================================
4167 SMESH::ListOfGroups*
4168 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4169 const char* theGroupName )
4170 throw ( SALOME::SALOME_Exception )
4172 Unexpect aCatch(SALOME_SalomeException);
4174 if ( !theGroupName || strlen( theGroupName) == 0 )
4175 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4177 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4179 // submesh by subshape id
4180 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4181 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4184 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4185 if ( error && !error->myBadElements.empty())
4187 // sort bad elements by type
4188 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4189 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4190 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4191 for ( ; elemIt != elemEnd; ++elemIt )
4193 const SMDS_MeshElement* elem = *elemIt;
4194 if ( !elem ) continue;
4196 if ( elem->GetID() < 1 )
4198 // elem is a temporary element, make a real element
4199 vector< const SMDS_MeshNode* > nodes;
4200 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4201 while ( nIt->more() && elem )
4203 nodes.push_back( nIt->next() );
4204 if ( nodes.back()->GetID() < 1 )
4205 elem = 0; // a temporary element on temporary nodes
4209 ::SMESH_MeshEditor editor( _impl );
4210 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4214 elemsByType[ elem->GetType() ].push_back( elem );
4217 // how many groups to create?
4219 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4220 nbTypes += int( !elemsByType[ i ].empty() );
4221 groups->length( nbTypes );
4224 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4226 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4227 if ( elems.empty() ) continue;
4229 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4230 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4232 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4233 SMESH::SMESH_Mesh_var mesh = _this();
4234 SALOMEDS::SObject_wrap aSO =
4235 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4236 GEOM::GEOM_Object::_nil(), theGroupName);
4237 aSO->_is_nil(); // avoid "unused variable" warning
4239 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4240 if ( !grp_i ) continue;
4242 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4243 for ( size_t iE = 0; iE < elems.size(); ++iE )
4244 grpDS->SMDSGroup().Add( elems[ iE ]);
4249 return groups._retn();
4252 //=============================================================================
4254 * Create and publish group servants if any groups were imported or created anyhow
4256 //=============================================================================
4258 void SMESH_Mesh_i::CreateGroupServants()
4260 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4261 SMESH::SMESH_Mesh_var aMesh = _this();
4264 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4265 while ( groupIt->more() )
4267 ::SMESH_Group* group = groupIt->next();
4268 int anId = group->GetGroupDS()->GetID();
4270 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4271 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4273 addedIDs.insert( anId );
4275 SMESH_GroupBase_i* aGroupImpl;
4277 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4278 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4280 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4281 shape = groupOnGeom->GetShape();
4284 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4287 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4288 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4289 aGroupImpl->Register();
4291 // register CORBA object for persistence
4292 int nextId = _gen_i->RegisterObject( groupVar );
4293 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4294 else { nextId = 0; } // avoid "unused variable" warning in release mode
4296 // publishing the groups in the study
4297 if ( !aStudy->_is_nil() ) {
4298 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4299 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4302 if ( !addedIDs.empty() )
4305 set<int>::iterator id = addedIDs.begin();
4306 for ( ; id != addedIDs.end(); ++id )
4308 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4309 int i = std::distance( _mapGroups.begin(), it );
4310 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4315 //=============================================================================
4317 * \brief Return groups cantained in _mapGroups by their IDs
4319 //=============================================================================
4321 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4323 int nbGroups = groupIDs.size();
4324 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4325 aList->length( nbGroups );
4327 list<int>::const_iterator ids = groupIDs.begin();
4328 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4330 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4331 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4332 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4334 aList->length( nbGroups );
4335 return aList._retn();
4338 //=============================================================================
4340 * \brief Return information about imported file
4342 //=============================================================================
4344 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4346 SMESH::MedFileInfo_var res( _medFileInfo );
4347 if ( !res.operator->() ) {
4348 res = new SMESH::MedFileInfo;
4350 res->fileSize = res->major = res->minor = res->release = -1;
4355 //=============================================================================
4357 * \brief Pass names of mesh groups from study to mesh DS
4359 //=============================================================================
4361 void SMESH_Mesh_i::checkGroupNames()
4363 int nbGrp = NbGroups();
4367 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4368 if ( aStudy->_is_nil() )
4369 return; // nothing to do
4371 SMESH::ListOfGroups* grpList = 0;
4372 // avoid dump of "GetGroups"
4374 // store python dump into a local variable inside local scope
4375 SMESH::TPythonDump pDump; // do not delete this line of code
4376 grpList = GetGroups();
4379 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4380 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4383 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4384 if ( aGrpSO->_is_nil() )
4386 // correct name of the mesh group if necessary
4387 const char* guiName = aGrpSO->GetName();
4388 if ( strcmp(guiName, aGrp->GetName()) )
4389 aGrp->SetName( guiName );
4393 //=============================================================================
4395 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4397 //=============================================================================
4398 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4400 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4404 //=============================================================================
4406 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4408 //=============================================================================
4410 char* SMESH_Mesh_i::GetParameters()
4412 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4415 //=============================================================================
4417 * \brief Returns list of notebook variables used for last Mesh operation
4419 //=============================================================================
4420 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4422 SMESH::string_array_var aResult = new SMESH::string_array();
4423 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4425 CORBA::String_var aParameters = GetParameters();
4426 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4427 if ( !aStudy->_is_nil()) {
4428 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4429 if(aSections->length() > 0) {
4430 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4431 aResult->length(aVars.length());
4432 for(int i = 0;i < aVars.length();i++)
4433 aResult[i] = CORBA::string_dup( aVars[i]);
4437 return aResult._retn();
4440 //=======================================================================
4441 //function : GetTypes
4442 //purpose : Returns types of elements it contains
4443 //=======================================================================
4445 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4448 return _preMeshInfo->GetTypes();
4450 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4454 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4455 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4456 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4457 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4458 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4459 types->length( nbTypes );
4461 return types._retn();
4464 //=======================================================================
4465 //function : GetMesh
4466 //purpose : Returns self
4467 //=======================================================================
4469 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4471 return SMESH::SMESH_Mesh::_duplicate( _this() );
4474 //=======================================================================
4475 //function : IsMeshInfoCorrect
4476 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4477 // * happen if mesh data is not yet fully loaded from the file of study.
4478 //=======================================================================
4480 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4482 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4485 //=============================================================================
4487 * \brief Returns number of mesh elements per each \a EntityType
4489 //=============================================================================
4491 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4494 return _preMeshInfo->GetMeshInfo();
4496 SMESH::long_array_var aRes = new SMESH::long_array();
4497 aRes->length(SMESH::Entity_Last);
4498 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4500 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4502 return aRes._retn();
4503 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4504 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4505 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4506 return aRes._retn();
4509 //=============================================================================
4511 * \brief Returns number of mesh elements per each \a ElementType
4513 //=============================================================================
4515 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
4517 SMESH::long_array_var aRes = new SMESH::long_array();
4518 aRes->length(SMESH::NB_ELEMENT_TYPES);
4519 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4522 const SMDS_MeshInfo* meshInfo = 0;
4524 meshInfo = _preMeshInfo;
4525 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
4526 meshInfo = & meshDS->GetMeshInfo();
4529 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4530 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
4532 return aRes._retn();
4535 //=============================================================================
4537 * Collect statistic of mesh elements given by iterator
4539 //=============================================================================
4541 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4542 SMESH::long_array& theInfo)
4544 if (!theItr) return;
4545 while (theItr->more())
4546 theInfo[ theItr->next()->GetEntityType() ]++;
4549 //=============================================================================
4550 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
4551 * SMESH::ElementType type) */
4553 using namespace SMESH::Controls;
4554 //-----------------------------------------------------------------------------
4555 struct PredicateIterator : public SMDS_ElemIterator
4557 SMDS_ElemIteratorPtr _elemIter;
4558 PredicatePtr _predicate;
4559 const SMDS_MeshElement* _elem;
4561 PredicateIterator( SMDS_ElemIteratorPtr iterator,
4562 PredicatePtr predicate):
4563 _elemIter(iterator), _predicate(predicate)
4571 virtual const SMDS_MeshElement* next()
4573 const SMDS_MeshElement* res = _elem;
4575 while ( _elemIter->more() && !_elem )
4577 _elem = _elemIter->next();
4578 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
4585 //-----------------------------------------------------------------------------
4586 struct IDSourceIterator : public SMDS_ElemIterator
4588 const CORBA::Long* _idPtr;
4589 const CORBA::Long* _idEndPtr;
4590 SMESH::long_array_var _idArray;
4591 const SMDS_Mesh* _mesh;
4592 const SMDSAbs_ElementType _type;
4593 const SMDS_MeshElement* _elem;
4595 IDSourceIterator( const SMDS_Mesh* mesh,
4596 const CORBA::Long* ids,
4598 SMDSAbs_ElementType type):
4599 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
4601 if ( _idPtr && nbIds && _mesh )
4604 IDSourceIterator( const SMDS_Mesh* mesh,
4605 SMESH::long_array* idArray,
4606 SMDSAbs_ElementType type):
4607 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
4609 if ( idArray && _mesh )
4611 _idPtr = &_idArray[0];
4612 _idEndPtr = _idPtr + _idArray->length();
4620 virtual const SMDS_MeshElement* next()
4622 const SMDS_MeshElement* res = _elem;
4624 while ( _idPtr < _idEndPtr && !_elem )
4626 if ( _type == SMDSAbs_Node )
4628 _elem = _mesh->FindNode( *_idPtr++ );
4630 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
4631 _elem->GetType() != _type )
4639 //-----------------------------------------------------------------------------
4641 struct NodeOfElemIterator : public SMDS_ElemIterator
4643 TColStd_MapOfInteger _checkedNodeIDs;
4644 SMDS_ElemIteratorPtr _elemIter;
4645 SMDS_ElemIteratorPtr _nodeIter;
4646 const SMDS_MeshElement* _node;
4648 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
4650 if ( _elemIter && _elemIter->more() )
4652 _nodeIter = _elemIter->next()->nodesIterator();
4660 virtual const SMDS_MeshElement* next()
4662 const SMDS_MeshElement* res = _node;
4664 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
4666 if ( _nodeIter->more() )
4668 _node = _nodeIter->next();
4669 if ( !_checkedNodeIDs.Add( _node->GetID() ))
4674 _nodeIter = _elemIter->next()->nodesIterator();
4682 //=============================================================================
4684 * Return iterator on elements of given type in given object
4686 //=============================================================================
4688 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
4689 SMESH::ElementType theType)
4691 SMDS_ElemIteratorPtr elemIt;
4692 bool typeOK = false;
4693 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
4695 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
4696 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
4697 if ( !mesh_i ) return elemIt;
4698 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
4700 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
4702 elemIt = meshDS->elementsIterator( elemType );
4705 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
4707 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
4710 elemIt = sm->GetElements();
4711 if ( elemType != SMDSAbs_Node )
4713 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
4714 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
4718 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
4720 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
4721 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
4723 elemIt = groupDS->GetElements();
4724 typeOK = ( groupDS->GetType() == elemType );
4727 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
4729 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
4731 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
4732 if ( pred_i && pred_i->GetPredicate() )
4734 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
4735 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
4736 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
4737 typeOK = ( filterType == elemType );
4743 SMESH::array_of_ElementType_var types = theObject->GetTypes();
4744 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
4745 if ( isNodes && elemType != SMDSAbs_Node )
4747 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
4750 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
4751 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
4755 SMESH::long_array_var ids = theObject->GetIDs();
4756 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
4758 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
4761 if ( elemIt && elemIt->more() && !typeOK )
4763 if ( elemType == SMDSAbs_Node )
4765 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
4769 elemIt = SMDS_ElemIteratorPtr();
4775 //=============================================================================
4776 namespace // Finding concurrent hypotheses
4777 //=============================================================================
4781 * \brief mapping of mesh dimension into shape type
4783 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4785 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4787 case 0: aType = TopAbs_VERTEX; break;
4788 case 1: aType = TopAbs_EDGE; break;
4789 case 2: aType = TopAbs_FACE; break;
4791 default:aType = TopAbs_SOLID; break;
4796 //-----------------------------------------------------------------------------
4798 * \brief Internal structure used to find concurent submeshes
4800 * It represents a pair < submesh, concurent dimension >, where
4801 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4802 * with another submesh. In other words, it is dimension of a hypothesis assigned
4809 int _dim; //!< a dimension the algo can build (concurrent dimension)
4810 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4811 TopTools_MapOfShape _shapeMap;
4812 SMESH_subMesh* _subMesh;
4813 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4815 //-----------------------------------------------------------------------------
4816 // Return the algorithm
4817 const SMESH_Algo* GetAlgo() const
4818 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4820 //-----------------------------------------------------------------------------
4822 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4824 const TopoDS_Shape& theShape)
4826 _subMesh = (SMESH_subMesh*)theSubMesh;
4827 SetShape( theDim, theShape );
4830 //-----------------------------------------------------------------------------
4832 void SetShape(const int theDim,
4833 const TopoDS_Shape& theShape)
4836 _ownDim = SMESH_Gen::GetShapeDim(theShape);
4837 if (_dim >= _ownDim)
4838 _shapeMap.Add( theShape );
4840 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4841 for( ; anExp.More(); anExp.Next() )
4842 _shapeMap.Add( anExp.Current() );
4846 //-----------------------------------------------------------------------------
4847 //! Check sharing of sub-shapes
4848 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4849 const TopTools_MapOfShape& theToFind,
4850 const TopAbs_ShapeEnum theType)
4852 bool isShared = false;
4853 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4854 for (; !isShared && anItr.More(); anItr.Next() )
4856 const TopoDS_Shape aSubSh = anItr.Key();
4857 // check for case when concurrent dimensions are same
4858 isShared = theToFind.Contains( aSubSh );
4859 // check for sub-shape with concurrent dimension
4860 TopExp_Explorer anExp( aSubSh, theType );
4861 for ( ; !isShared && anExp.More(); anExp.Next() )
4862 isShared = theToFind.Contains( anExp.Current() );
4867 //-----------------------------------------------------------------------------
4868 //! check algorithms
4869 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4870 const SMESHDS_Hypothesis* theA2)
4872 if ( !theA1 || !theA2 ||
4873 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4874 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4875 return false; // one of the hypothesis is not algorithm
4876 // check algorithm names (should be equal)
4877 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4881 //-----------------------------------------------------------------------------
4882 //! Check if sub-shape hypotheses are concurrent
4883 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4885 if ( _subMesh == theOther->_subMesh )
4886 return false; // same sub-shape - should not be
4888 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4889 // any of the two submeshes is not on COMPOUND shape )
4890 // -> no concurrency
4891 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4892 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4893 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4894 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4895 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4898 // bool checkSubShape = ( _dim >= theOther->_dim )
4899 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4900 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4901 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4902 if ( !checkSubShape )
4905 // check algorithms to be same
4906 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4907 return true; // different algorithms -> concurrency !
4909 // check hypothesises for concurrence (skip first as algorithm)
4911 // pointers should be same, because it is referened from mesh hypothesis partition
4912 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4913 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4914 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4915 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4917 // the submeshes are concurrent if their algorithms has different parameters
4918 return nbSame != theOther->_hypotheses.size() - 1;
4921 // Return true if algorithm of this SMESH_DimHyp is used if no
4922 // sub-mesh order is imposed by the user
4923 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4925 // NeedDiscreteBoundary() algo has a higher priority
4926 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4927 theOther->GetAlgo()->NeedDiscreteBoundary() )
4928 return !this->GetAlgo()->NeedDiscreteBoundary();
4930 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4933 }; // end of SMESH_DimHyp
4934 //-----------------------------------------------------------------------------
4936 typedef list<const SMESH_DimHyp*> TDimHypList;
4938 //-----------------------------------------------------------------------------
4940 void addDimHypInstance(const int theDim,
4941 const TopoDS_Shape& theShape,
4942 const SMESH_Algo* theAlgo,
4943 const SMESH_subMesh* theSubMesh,
4944 const list <const SMESHDS_Hypothesis*>& theHypList,
4945 TDimHypList* theDimHypListArr )
4947 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4948 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4949 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4950 dimHyp->_hypotheses.push_front(theAlgo);
4951 listOfdimHyp.push_back( dimHyp );
4954 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4955 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4956 theHypList.begin(), theHypList.end() );
4959 //-----------------------------------------------------------------------------
4960 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4961 TDimHypList& theListOfConcurr)
4963 if ( theListOfConcurr.empty() )
4965 theListOfConcurr.push_back( theDimHyp );
4969 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4970 while ( hypIt != theListOfConcurr.end() &&
4971 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4973 theListOfConcurr.insert( hypIt, theDimHyp );
4977 //-----------------------------------------------------------------------------
4978 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4979 const TDimHypList& theListOfDimHyp,
4980 TDimHypList& theListOfConcurrHyp,
4981 set<int>& theSetOfConcurrId )
4983 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4984 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4986 const SMESH_DimHyp* curDimHyp = *rIt;
4987 if ( curDimHyp == theDimHyp )
4988 break; // meet own dimHyp pointer in same dimension
4990 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4991 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4993 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4998 //-----------------------------------------------------------------------------
4999 void unionLists(TListOfInt& theListOfId,
5000 TListOfListOfInt& theListOfListOfId,
5003 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5004 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5006 continue; //skip already treated lists
5007 // check if other list has any same submesh object
5008 TListOfInt& otherListOfId = *it;
5009 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5010 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5013 // union two lists (from source into target)
5014 TListOfInt::iterator it2 = otherListOfId.begin();
5015 for ( ; it2 != otherListOfId.end(); it2++ ) {
5016 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5017 theListOfId.push_back(*it2);
5019 // clear source list
5020 otherListOfId.clear();
5023 //-----------------------------------------------------------------------------
5025 //! free memory allocated for dimension-hypothesis objects
5026 void removeDimHyps( TDimHypList* theArrOfList )
5028 for (int i = 0; i < 4; i++ ) {
5029 TDimHypList& listOfdimHyp = theArrOfList[i];
5030 TDimHypList::const_iterator it = listOfdimHyp.begin();
5031 for ( ; it != listOfdimHyp.end(); it++ )
5036 //-----------------------------------------------------------------------------
5038 * \brief find common submeshes with given submesh
5039 * \param theSubMeshList list of already collected submesh to check
5040 * \param theSubMesh given submesh to intersect with other
5041 * \param theCommonSubMeshes collected common submeshes
5043 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5044 const SMESH_subMesh* theSubMesh,
5045 set<const SMESH_subMesh*>& theCommon )
5049 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5050 for ( ; it != theSubMeshList.end(); it++ )
5051 theSubMesh->FindIntersection( *it, theCommon );
5052 theSubMeshList.push_back( theSubMesh );
5053 //theCommon.insert( theSubMesh );
5058 //=============================================================================
5060 * \brief Return submesh objects list in meshing order
5062 //=============================================================================
5064 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5066 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5068 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5070 return aResult._retn();
5072 ::SMESH_Mesh& mesh = GetImpl();
5073 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
5074 if ( !anOrder.size() ) {
5076 // collect submeshes and detect concurrent algorithms and hypothesises
5077 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5079 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5080 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5081 ::SMESH_subMesh* sm = (*i_sm).second;
5083 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5085 // list of assigned hypothesises
5086 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5087 // Find out dimensions where the submesh can be concurrent.
5088 // We define the dimensions by algo of each of hypotheses in hypList
5089 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5090 for( ; hypIt != hypList.end(); hypIt++ ) {
5091 SMESH_Algo* anAlgo = 0;
5092 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5093 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5094 // hyp it-self is algo
5095 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5097 // try to find algorithm with help of sub-shapes
5098 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5099 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5100 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5103 continue; // no algorithm assigned to a current submesh
5105 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5106 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5108 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5109 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5110 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5112 } // end iterations on submesh
5114 // iterate on created dimension-hypotheses and check for concurrents
5115 for ( int i = 0; i < 4; i++ ) {
5116 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5117 // check for concurrents in own and other dimensions (step-by-step)
5118 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5119 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5120 const SMESH_DimHyp* dimHyp = *dhIt;
5121 TDimHypList listOfConcurr;
5122 set<int> setOfConcurrIds;
5123 // looking for concurrents and collect into own list
5124 for ( int j = i; j < 4; j++ )
5125 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5126 // check if any concurrents found
5127 if ( listOfConcurr.size() > 0 ) {
5128 // add own submesh to list of concurrent
5129 addInOrderOfPriority( dimHyp, listOfConcurr );
5130 list<int> listOfConcurrIds;
5131 TDimHypList::iterator hypIt = listOfConcurr.begin();
5132 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5133 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5134 anOrder.push_back( listOfConcurrIds );
5139 removeDimHyps(dimHypListArr);
5141 // now, minimise the number of concurrent groups
5142 // Here we assume that lists of submeshes can have same submesh
5143 // in case of multi-dimension algorithms, as result
5144 // list with common submesh has to be united into one list
5146 TListOfListOfInt::iterator listIt = anOrder.begin();
5147 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5148 unionLists( *listIt, anOrder, listIndx + 1 );
5150 // convert submesh ids into interface instances
5151 // and dump command into python
5152 convertMeshOrder( anOrder, aResult, false );
5154 return aResult._retn();
5157 //=============================================================================
5159 * \brief Set submesh object order
5160 * \param theSubMeshArray submesh array order
5162 //=============================================================================
5164 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5167 _preMeshInfo->ForgetOrLoad();
5170 ::SMESH_Mesh& mesh = GetImpl();
5172 TPythonDump aPythonDump; // prevent dump of called methods
5173 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5175 TListOfListOfInt subMeshOrder;
5176 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5178 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5179 TListOfInt subMeshIds;
5180 aPythonDump << "[ ";
5181 // Collect subMeshes which should be clear
5182 // do it list-by-list, because modification of submesh order
5183 // take effect between concurrent submeshes only
5184 set<const SMESH_subMesh*> subMeshToClear;
5185 list<const SMESH_subMesh*> subMeshList;
5186 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5188 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5190 aPythonDump << ", ";
5191 aPythonDump << subMesh;
5192 subMeshIds.push_back( subMesh->GetId() );
5193 // detect common parts of submeshes
5194 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5195 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5197 aPythonDump << " ]";
5198 subMeshOrder.push_back( subMeshIds );
5200 // clear collected submeshes
5201 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5202 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5203 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5204 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5206 aPythonDump << " ])";
5208 mesh.SetMeshOrder( subMeshOrder );
5214 //=============================================================================
5216 * \brief Convert submesh ids into submesh interfaces
5218 //=============================================================================
5220 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5221 SMESH::submesh_array_array& theResOrder,
5222 const bool theIsDump)
5224 int nbSet = theIdsOrder.size();
5225 TPythonDump aPythonDump; // prevent dump of called methods
5227 aPythonDump << "[ ";
5228 theResOrder.length(nbSet);
5229 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5231 for( ; it != theIdsOrder.end(); it++ ) {
5232 // translate submesh identificators into submesh objects
5233 // takeing into account real number of concurrent lists
5234 const TListOfInt& aSubOrder = (*it);
5235 if (!aSubOrder.size())
5238 aPythonDump << "[ ";
5239 // convert shape indeces into interfaces
5240 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5241 aResSubSet->length(aSubOrder.size());
5242 TListOfInt::const_iterator subIt = aSubOrder.begin();
5243 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
5244 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5246 SMESH::SMESH_subMesh_var subMesh =
5247 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5250 aPythonDump << ", ";
5251 aPythonDump << subMesh;
5253 aResSubSet[ j++ ] = subMesh;
5256 aPythonDump << " ]";
5257 theResOrder[ listIndx++ ] = aResSubSet;
5259 // correct number of lists
5260 theResOrder.length( listIndx );
5263 // finilise python dump
5264 aPythonDump << " ]";
5265 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5269 //================================================================================
5271 // Implementation of SMESH_MeshPartDS
5273 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5274 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5276 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5277 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5279 _meshDS = mesh_i->GetImpl().GetMeshDS();
5281 SetPersistentId( _meshDS->GetPersistentId() );
5283 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5285 // <meshPart> is the whole mesh
5286 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5288 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5289 myGroupSet = _meshDS->GetGroups();
5294 SMESH::long_array_var anIDs = meshPart->GetIDs();
5295 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5296 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5298 for (int i=0; i < anIDs->length(); i++)
5299 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5300 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5305 for (int i=0; i < anIDs->length(); i++)
5306 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5307 if ( _elements[ e->GetType() ].insert( e ).second )
5310 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5311 while ( nIt->more() )
5313 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5314 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5321 _meshDS = 0; // to enforce iteration on _elements and _nodes
5324 // -------------------------------------------------------------------------------------
5325 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5326 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5329 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5330 for ( ; partIt != meshPart.end(); ++partIt )
5331 if ( const SMDS_MeshElement * e = *partIt )
5332 if ( _elements[ e->GetType() ].insert( e ).second )
5335 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5336 while ( nIt->more() )
5338 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5339 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5345 // -------------------------------------------------------------------------------------
5346 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5348 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5350 typedef SMDS_SetIterator
5351 <const SMDS_MeshElement*,
5352 TIDSortedElemSet::const_iterator,
5353 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5354 SMDS_MeshElement::GeomFilter
5357 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5359 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5360 _elements[type].end(),
5361 SMDS_MeshElement::GeomFilter( geomType )));
5363 // -------------------------------------------------------------------------------------
5364 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5366 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5368 typedef SMDS_SetIterator
5369 <const SMDS_MeshElement*,
5370 TIDSortedElemSet::const_iterator,
5371 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5372 SMDS_MeshElement::EntityFilter
5375 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5377 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5378 _elements[type].end(),
5379 SMDS_MeshElement::EntityFilter( entity )));
5381 // -------------------------------------------------------------------------------------
5382 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5384 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5385 if ( type == SMDSAbs_All && !_meshDS )
5387 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5389 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5390 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5392 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5394 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5395 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5397 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5398 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5400 // -------------------------------------------------------------------------------------
5401 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5402 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5404 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5405 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5406 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5408 // -------------------------------------------------------------------------------------
5409 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5410 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5411 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5412 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5413 #undef _GET_ITER_DEFINE
5415 // END Implementation of SMESH_MeshPartDS
5417 //================================================================================