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 "SMDS_EdgePosition.hxx"
31 #include "SMDS_ElemIterator.hxx"
32 #include "SMDS_FacePosition.hxx"
33 #include "SMDS_IteratorOnIterators.hxx"
34 #include "SMDS_MeshGroup.hxx"
35 #include "SMDS_SetIterator.hxx"
36 #include "SMDS_VolumeTool.hxx"
37 #include "SMESHDS_Command.hxx"
38 #include "SMESHDS_CommandType.hxx"
39 #include "SMESHDS_Group.hxx"
40 #include "SMESHDS_GroupOnGeom.hxx"
41 #include "SMESH_Filter_i.hxx"
42 #include "SMESH_Gen_i.hxx"
43 #include "SMESH_Group.hxx"
44 #include "SMESH_Group_i.hxx"
45 #include "SMESH_MEDMesh_i.hxx"
46 #include "SMESH_MeshEditor.hxx"
47 #include "SMESH_MeshEditor_i.hxx"
48 #include "SMESH_MeshPartDS.hxx"
49 #include "SMESH_MesherHelper.hxx"
50 #include "SMESH_PreMeshInfo.hxx"
51 #include "SMESH_PythonDump.hxx"
52 #include "SMESH_subMesh_i.hxx"
55 #include <SALOMEDS_Attributes_wrap.hxx>
56 #include <SALOMEDS_wrap.hxx>
57 #include <SALOME_NamingService.hxx>
58 #include <Utils_ExceptHandlers.hxx>
59 #include <Utils_SINGLETON.hxx>
60 #include <utilities.h>
62 #include <GEOMImpl_Types.hxx>
63 #include <GEOM_wrap.hxx>
66 #include <BRep_Builder.hxx>
67 #include <OSD_Directory.hxx>
68 #include <OSD_File.hxx>
69 #include <OSD_Path.hxx>
70 #include <OSD_Protection.hxx>
71 #include <Standard_OutOfMemory.hxx>
72 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
73 #include <TColStd_MapOfInteger.hxx>
74 #include <TColStd_SequenceOfInteger.hxx>
75 #include <TCollection_AsciiString.hxx>
77 #include <TopExp_Explorer.hxx>
78 #include <TopTools_MapIteratorOfMapOfShape.hxx>
79 #include <TopTools_MapOfShape.hxx>
80 #include <TopoDS_Compound.hxx>
82 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 static int MYDEBUG = 0;
95 static int MYDEBUG = 0;
99 using SMESH::TPythonDump;
101 int SMESH_Mesh_i::_idGenerator = 0;
103 //=============================================================================
107 //=============================================================================
109 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
111 CORBA::Long studyId )
112 : SALOME::GenericObj_i( thePOA )
114 MESSAGE("SMESH_Mesh_i");
117 _id = _idGenerator++;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
130 MESSAGE("~SMESH_Mesh_i");
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 // _impl->RemoveGroup() is called by ~SMESH_GroupBase_i() (PAL6331)
138 //_impl->RemoveGroup( aGroup->GetLocalID() );
139 aGroup->myMeshServant = 0;
140 aGroup->UnRegister();
145 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
146 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
147 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
149 aSubMesh->UnRegister();
151 _mapSubMeshIor.clear();
153 // destroy hypotheses
154 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
155 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ )
156 if ( SMESH_Hypothesis_i* aHypo = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
162 delete _impl; _impl = NULL;
163 delete _preMeshInfo; _preMeshInfo = NULL;
166 //=============================================================================
170 * Associates <this> mesh with <theShape> and puts a reference
171 * to <theShape> into the current study;
172 * the previous shape is substituted by the new one.
174 //=============================================================================
176 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
177 throw (SALOME::SALOME_Exception)
179 Unexpect aCatch(SALOME_SalomeException);
181 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
183 catch(SALOME_Exception & S_ex) {
184 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
186 // to track changes of GEOM groups
187 addGeomGroupData( theShapeObject, _this() );
190 //================================================================================
192 * \brief return true if mesh has a shape to build a shape on
194 //================================================================================
196 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
197 throw (SALOME::SALOME_Exception)
199 Unexpect aCatch(SALOME_SalomeException);
202 res = _impl->HasShapeToMesh();
204 catch(SALOME_Exception & S_ex) {
205 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
210 //=======================================================================
211 //function : GetShapeToMesh
213 //=======================================================================
215 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
216 throw (SALOME::SALOME_Exception)
218 Unexpect aCatch(SALOME_SalomeException);
219 GEOM::GEOM_Object_var aShapeObj;
221 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
223 aShapeObj = _gen_i->ShapeToGeomObject( S );
225 catch(SALOME_Exception & S_ex) {
226 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
228 return aShapeObj._retn();
231 //================================================================================
233 * \brief Return false if the mesh is not yet fully loaded from the study file
235 //================================================================================
237 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
239 Unexpect aCatch(SALOME_SalomeException);
240 return !_preMeshInfo;
243 //================================================================================
245 * \brief Load full mesh data from the study file
247 //================================================================================
249 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
251 Unexpect aCatch(SALOME_SalomeException);
253 _preMeshInfo->FullLoadFromFile();
256 //================================================================================
258 * \brief Remove all nodes and elements
260 //================================================================================
262 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
264 Unexpect aCatch(SALOME_SalomeException);
266 _preMeshInfo->ForgetAllData();
270 CheckGeomGroupModif(); // issue 20145
272 catch(SALOME_Exception & S_ex) {
273 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
275 _impl->GetMeshDS()->Modified();
277 TPythonDump() << _this() << ".Clear()";
280 //================================================================================
282 * \brief Remove all nodes and elements for indicated shape
284 //================================================================================
286 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
287 throw (SALOME::SALOME_Exception)
289 Unexpect aCatch(SALOME_SalomeException);
291 _preMeshInfo->FullLoadFromFile();
294 _impl->ClearSubMesh( ShapeID );
296 catch(SALOME_Exception & S_ex) {
297 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
299 _impl->GetMeshDS()->Modified();
301 TPythonDump() << _this() << ".ClearSubMesh( " << ShapeID << " )";
304 //=============================================================================
306 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
308 //=============================================================================
310 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
312 SMESH::DriverMED_ReadStatus res;
315 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
316 res = SMESH::DRS_OK; break;
317 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
318 res = SMESH::DRS_EMPTY; break;
319 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
320 res = SMESH::DRS_WARN_RENUMBER; break;
321 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
322 res = SMESH::DRS_WARN_SKIP_ELEM; break;
323 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
324 res = SMESH::DRS_WARN_DESCENDING; break;
325 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
327 res = SMESH::DRS_FAIL; break;
332 //=============================================================================
334 * Convert ::SMESH_ComputeError to SMESH::ComputeError
336 //=============================================================================
338 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
340 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
341 errVar->subShapeID = -1;
342 errVar->hasBadMesh = false;
344 if ( !errorPtr || errorPtr->IsOK() )
346 errVar->code = SMESH::COMPERR_OK;
350 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
351 errVar->comment = errorPtr->myComment.c_str();
353 return errVar._retn();
356 //=============================================================================
360 * Imports mesh data from MED file
362 //=============================================================================
364 SMESH::DriverMED_ReadStatus
365 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
366 throw ( SALOME::SALOME_Exception )
368 Unexpect aCatch(SALOME_SalomeException);
371 status = _impl->MEDToMesh( theFileName, theMeshName );
373 catch( SALOME_Exception& S_ex ) {
374 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
377 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
380 CreateGroupServants();
382 int major, minor, release;
383 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
384 major = minor = release = -1;
385 _medFileInfo = new SALOME_MED::MedFileInfo();
386 _medFileInfo->fileName = theFileName;
387 _medFileInfo->fileSize = 0;
390 if ( ::_stati64( theFileName, &d ) != -1 )
393 if ( ::stat64( theFileName, &d ) != -1 )
395 _medFileInfo->fileSize = d.st_size;
396 _medFileInfo->major = major;
397 _medFileInfo->minor = minor;
398 _medFileInfo->release = release;
400 return ConvertDriverMEDReadStatus(status);
403 //================================================================================
405 * \brief Imports mesh data from the CGNS file
407 //================================================================================
409 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
410 const int theMeshIndex,
411 std::string& theMeshName )
412 throw ( SALOME::SALOME_Exception )
414 Unexpect aCatch(SALOME_SalomeException);
417 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
419 catch( SALOME_Exception& S_ex ) {
420 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
423 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
426 CreateGroupServants();
428 return ConvertDriverMEDReadStatus(status);
431 //================================================================================
433 * \brief Return string representation of a MED file version comprising nbDigits
435 //================================================================================
437 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
439 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
441 return CORBA::string_dup( ver.c_str() );
444 //=============================================================================
448 * Imports mesh data from MED file
450 //=============================================================================
452 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
453 throw ( SALOME::SALOME_Exception )
457 // Read mesh with name = <theMeshName> into SMESH_Mesh
458 _impl->UNVToMesh( theFileName );
460 CreateGroupServants();
462 SMESH_CATCH( SMESH::throwCorbaException );
467 //=============================================================================
471 * Imports mesh data from STL file
473 //=============================================================================
474 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
475 throw ( SALOME::SALOME_Exception )
479 // Read mesh with name = <theMeshName> into SMESH_Mesh
480 _impl->STLToMesh( theFileName );
482 SMESH_CATCH( SMESH::throwCorbaException );
487 //================================================================================
489 * \brief Function used in SMESH_CATCH by ImportGMFFile()
491 //================================================================================
495 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
497 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
501 //================================================================================
503 * \brief Imports data from a GMF file and returns an error description
505 //================================================================================
507 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
508 bool theMakeRequiredGroups )
509 throw (SALOME::SALOME_Exception)
511 SMESH_ComputeErrorPtr error;
514 #define SMESH_CAUGHT error =
517 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
519 SMESH_CATCH( exceptionToComputeError );
523 CreateGroupServants();
525 return ConvertComputeError( error );
528 //=============================================================================
532 //=============================================================================
534 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
536 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
537 (SMESH_Hypothesis::Hypothesis_Status theStatus)
540 RETURNCASE( HYP_OK );
541 RETURNCASE( HYP_MISSING );
542 RETURNCASE( HYP_CONCURENT );
543 RETURNCASE( HYP_BAD_PARAMETER );
544 RETURNCASE( HYP_HIDDEN_ALGO );
545 RETURNCASE( HYP_HIDING_ALGO );
546 RETURNCASE( HYP_UNKNOWN_FATAL );
547 RETURNCASE( HYP_INCOMPATIBLE );
548 RETURNCASE( HYP_NOTCONFORM );
549 RETURNCASE( HYP_ALREADY_EXIST );
550 RETURNCASE( HYP_BAD_DIM );
551 RETURNCASE( HYP_BAD_SUBSHAPE );
552 RETURNCASE( HYP_BAD_GEOMETRY );
553 RETURNCASE( HYP_NEED_SHAPE );
556 return SMESH::HYP_UNKNOWN_FATAL;
559 //=============================================================================
563 * calls internal addHypothesis() and then adds a reference to <anHyp> under
564 * the SObject actually having a reference to <aSubShape>.
565 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
567 //=============================================================================
569 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
570 SMESH::SMESH_Hypothesis_ptr anHyp)
571 throw(SALOME::SALOME_Exception)
573 Unexpect aCatch(SALOME_SalomeException);
575 _preMeshInfo->ForgetOrLoad();
577 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
579 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
580 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
581 aSubShapeObject, anHyp );
583 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
585 // Update Python script
586 //if(_impl->HasShapeToMesh()) {
587 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
588 << aSubShapeObject << ", " << anHyp << " )";
591 // TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
594 return ConvertHypothesisStatus(status);
597 //=============================================================================
601 //=============================================================================
603 SMESH_Hypothesis::Hypothesis_Status
604 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
605 SMESH::SMESH_Hypothesis_ptr anHyp)
607 if(MYDEBUG) MESSAGE("addHypothesis");
609 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
610 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
613 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
614 if (CORBA::is_nil(myHyp))
615 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
618 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
621 TopoDS_Shape myLocSubShape;
622 //use PseudoShape in case if mesh has no shape
624 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
626 myLocSubShape = _impl->GetShapeToMesh();
628 int hypId = myHyp->GetId();
629 status = _impl->AddHypothesis(myLocSubShape, hypId);
630 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
631 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
632 _mapHypo[hypId]->Register();
633 // assure there is a corresponding submesh
634 if ( !_impl->IsMainShape( myLocSubShape )) {
635 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
636 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
637 createSubMesh( aSubShapeObject );
641 catch(SALOME_Exception & S_ex)
643 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
648 //=============================================================================
652 //=============================================================================
654 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
655 SMESH::SMESH_Hypothesis_ptr anHyp)
656 throw(SALOME::SALOME_Exception)
658 Unexpect aCatch(SALOME_SalomeException);
660 _preMeshInfo->ForgetOrLoad();
662 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
664 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
665 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
666 aSubShapeObject, anHyp );
668 // Update Python script
669 // Update Python script
670 if(_impl->HasShapeToMesh()) {
671 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
672 << aSubShapeObject << ", " << anHyp << " )";
675 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
679 return ConvertHypothesisStatus(status);
682 //=============================================================================
686 //=============================================================================
688 SMESH_Hypothesis::Hypothesis_Status
689 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
690 SMESH::SMESH_Hypothesis_ptr anHyp)
692 if(MYDEBUG) MESSAGE("removeHypothesis()");
693 // **** proposer liste de sub-shape (selection multiple)
695 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
696 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
698 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
699 if (CORBA::is_nil(myHyp))
700 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
702 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
705 TopoDS_Shape myLocSubShape;
706 //use PseudoShape in case if mesh has no shape
708 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
710 myLocSubShape = _impl->GetShapeToMesh();
712 int hypId = myHyp->GetId();
713 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
714 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
715 // _mapHypo.erase( hypId );
717 catch(SALOME_Exception & S_ex)
719 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
724 //=============================================================================
728 //=============================================================================
730 SMESH::ListOfHypothesis *
731 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
732 throw(SALOME::SALOME_Exception)
734 Unexpect aCatch(SALOME_SalomeException);
735 if (MYDEBUG) MESSAGE("GetHypothesisList");
736 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
737 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
739 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
742 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
743 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
744 myLocSubShape = _impl->GetShapeToMesh();
745 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
746 int i = 0, n = aLocalList.size();
749 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
750 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
751 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
752 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
757 catch(SALOME_Exception & S_ex) {
758 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
761 return aList._retn();
764 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
766 Unexpect aCatch(SALOME_SalomeException);
767 if (MYDEBUG) MESSAGE("GetSubMeshes");
769 SMESH::submesh_array_var aList = new SMESH::submesh_array();
772 TPythonDump aPythonDump;
773 if ( !_mapSubMeshIor.empty() )
777 aList->length( _mapSubMeshIor.size() );
779 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
780 for ( ; it != _mapSubMeshIor.end(); it++ ) {
781 if ( CORBA::is_nil( it->second )) continue;
782 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
784 if (i > 1) aPythonDump << ", ";
785 aPythonDump << it->second;
789 catch(SALOME_Exception & S_ex) {
790 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
793 // Update Python script
794 if ( !_mapSubMeshIor.empty() )
795 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
797 return aList._retn();
800 //=============================================================================
804 //=============================================================================
805 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
806 const char* theName )
807 throw(SALOME::SALOME_Exception)
809 Unexpect aCatch(SALOME_SalomeException);
810 MESSAGE("SMESH_Mesh_i::GetSubMesh");
811 if (CORBA::is_nil(aSubShapeObject))
812 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
815 SMESH::SMESH_subMesh_var subMesh;
816 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
818 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
820 //Get or Create the SMESH_subMesh object implementation
822 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
824 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
826 TopoDS_Iterator it( myLocSubShape );
828 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
830 subMesh = getSubMesh( subMeshId );
832 // create a new subMesh object servant if there is none for the shape
833 if ( subMesh->_is_nil() )
834 subMesh = createSubMesh( aSubShapeObject );
835 if ( _gen_i->CanPublishInStudy( subMesh )) {
836 SALOMEDS::SObject_wrap aSO =
837 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
838 subMesh, aSubShapeObject, theName );
839 if ( !aSO->_is_nil()) {
840 // Update Python script
841 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
842 << aSubShapeObject << ", '" << theName << "' )";
846 catch(SALOME_Exception & S_ex) {
847 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
849 return subMesh._retn();
852 //=============================================================================
856 //=============================================================================
858 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
859 throw (SALOME::SALOME_Exception)
863 if ( theSubMesh->_is_nil() )
866 GEOM::GEOM_Object_var aSubShapeObject;
867 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
868 if ( !aStudy->_is_nil() ) {
869 // Remove submesh's SObject
870 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
871 if ( !anSO->_is_nil() ) {
872 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
873 SALOMEDS::SObject_wrap anObj, aRef;
874 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
875 anObj->ReferencedObject( aRef.inout() ))
877 CORBA::Object_var obj = aRef->GetObject();
878 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
880 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
881 // aSubShapeObject = theSubMesh->GetSubShape();
883 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
884 builder->RemoveObjectWithChildren( anSO );
886 // Update Python script
887 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
891 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
893 _preMeshInfo->ForgetOrLoad();
895 SMESH_CATCH( SMESH::throwCorbaException );
898 //=============================================================================
902 //=============================================================================
904 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
905 const char* theName )
906 throw(SALOME::SALOME_Exception)
908 Unexpect aCatch(SALOME_SalomeException);
910 _preMeshInfo->FullLoadFromFile();
912 SMESH::SMESH_Group_var aNewGroup =
913 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
915 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
916 SALOMEDS::SObject_wrap aSO =
917 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
918 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
919 if ( !aSO->_is_nil()) {
920 // Update Python script
921 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
922 << theElemType << ", '" << theName << "' )";
925 return aNewGroup._retn();
929 //=============================================================================
933 //=============================================================================
934 SMESH::SMESH_GroupOnGeom_ptr
935 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
937 GEOM::GEOM_Object_ptr theGeomObj)
938 throw(SALOME::SALOME_Exception)
940 Unexpect aCatch(SALOME_SalomeException);
942 _preMeshInfo->FullLoadFromFile();
944 SMESH::SMESH_GroupOnGeom_var aNewGroup;
946 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
947 if ( !aShape.IsNull() )
949 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
950 ( createGroup( theElemType, theName, aShape ));
952 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
953 SALOMEDS::SObject_wrap aSO =
954 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
955 aNewGroup, theGeomObj, theName);
956 if ( !aSO->_is_nil()) {
957 // Update Python script
958 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
959 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
964 return aNewGroup._retn();
967 //================================================================================
969 * \brief Creates a group whose contents is defined by filter
970 * \param theElemType - group type
971 * \param theName - group name
972 * \param theFilter - the filter
973 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
975 //================================================================================
977 SMESH::SMESH_GroupOnFilter_ptr
978 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
980 SMESH::Filter_ptr theFilter )
981 throw (SALOME::SALOME_Exception)
983 Unexpect aCatch(SALOME_SalomeException);
985 _preMeshInfo->FullLoadFromFile();
987 if ( CORBA::is_nil( theFilter ))
988 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
990 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
992 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
994 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
995 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
998 if ( !aNewGroup->_is_nil() )
999 aNewGroup->SetFilter( theFilter );
1001 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1003 SALOMEDS::SObject_wrap aSO =
1004 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
1005 GEOM::GEOM_Object::_nil(), theName);
1006 if ( !aSO->_is_nil()) {
1007 // Update Python script
1008 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
1009 << theElemType << ", '" << theName << "', " << theFilter << " )";
1013 return aNewGroup._retn();
1016 //=============================================================================
1020 //=============================================================================
1022 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1023 throw (SALOME::SALOME_Exception)
1025 if ( theGroup->_is_nil() )
1030 SMESH_GroupBase_i* aGroup =
1031 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1035 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1036 if ( !aStudy->_is_nil() ) {
1037 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1039 if ( !aGroupSO->_is_nil() ) {
1040 // Update Python script
1041 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
1043 // Remove group's SObject
1044 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1045 builder->RemoveObjectWithChildren( aGroupSO );
1049 // Remove the group from SMESH data structures
1050 removeGroup( aGroup->GetLocalID() );
1052 SMESH_CATCH( SMESH::throwCorbaException );
1055 //=============================================================================
1057 * Remove group with its contents
1059 //=============================================================================
1061 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1062 throw (SALOME::SALOME_Exception)
1066 _preMeshInfo->FullLoadFromFile();
1068 if ( theGroup->_is_nil() )
1071 SMESH_GroupBase_i* aGroup =
1072 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1076 SMESH::long_array_var anIds = aGroup->GetListOfID();
1077 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
1079 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
1082 if ( aGroup->GetType() == SMESH::NODE )
1083 aMeshEditor->RemoveNodes( anIds );
1085 aMeshEditor->RemoveElements( anIds );
1087 // Update Python script (theGroup must be alive for this)
1088 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
1091 RemoveGroup( theGroup );
1093 SMESH_CATCH( SMESH::throwCorbaException );
1096 //================================================================================
1098 * \brief Get the list of groups existing in the mesh
1099 * \retval SMESH::ListOfGroups * - list of groups
1101 //================================================================================
1103 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1105 Unexpect aCatch(SALOME_SalomeException);
1106 if (MYDEBUG) MESSAGE("GetGroups");
1108 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1111 TPythonDump aPythonDump;
1112 if ( !_mapGroups.empty() )
1114 aPythonDump << "[ ";
1116 aList->length( _mapGroups.size() );
1118 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1119 for ( ; it != _mapGroups.end(); it++ ) {
1120 if ( CORBA::is_nil( it->second )) continue;
1121 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1123 if (i > 1) aPythonDump << ", ";
1124 aPythonDump << it->second;
1128 catch(SALOME_Exception & S_ex) {
1129 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1131 aPythonDump << " ] = " << _this() << ".GetGroups()";
1133 return aList._retn();
1136 //=============================================================================
1138 * Get number of groups existing in the mesh
1140 //=============================================================================
1142 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1144 Unexpect aCatch(SALOME_SalomeException);
1145 return _mapGroups.size();
1148 //=============================================================================
1150 * New group is created. All mesh elements that are
1151 * present in initial groups are added to the new one
1153 //=============================================================================
1154 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1155 SMESH::SMESH_GroupBase_ptr theGroup2,
1156 const char* theName )
1157 throw (SALOME::SALOME_Exception)
1159 SMESH::SMESH_Group_var aResGrp;
1163 _preMeshInfo->FullLoadFromFile();
1165 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1166 theGroup1->GetType() != theGroup2->GetType() )
1167 return SMESH::SMESH_Group::_nil();
1172 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1173 if ( aResGrp->_is_nil() )
1174 return SMESH::SMESH_Group::_nil();
1176 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1177 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1179 TColStd_MapOfInteger aResMap;
1181 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1182 aResMap.Add( anIds1[ i1 ] );
1184 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1185 aResMap.Add( anIds2[ i2 ] );
1187 SMESH::long_array_var aResIds = new SMESH::long_array;
1188 aResIds->length( aResMap.Extent() );
1191 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1192 for( ; anIter.More(); anIter.Next() )
1193 aResIds[ resI++ ] = anIter.Key();
1195 aResGrp->Add( aResIds );
1197 // Update Python script
1198 pyDump << aResGrp << " = " << _this() << ".UnionGroups( "
1199 << theGroup1 << ", " << theGroup2 << ", '"
1200 << theName << "' )";
1202 SMESH_CATCH( SMESH::throwCorbaException );
1204 return aResGrp._retn();
1207 //=============================================================================
1209 \brief Union list of groups. New group is created. All mesh elements that are
1210 present in initial groups are added to the new one.
1211 \param theGroups list of groups
1212 \param theName name of group to be created
1213 \return pointer on the group
1215 //=============================================================================
1216 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1217 const char* theName )
1218 throw (SALOME::SALOME_Exception)
1221 _preMeshInfo->FullLoadFromFile();
1224 return SMESH::SMESH_Group::_nil();
1226 SMESH::SMESH_Group_var aResGrp;
1230 vector< int > anIds;
1231 SMESH::ElementType aType = SMESH::ALL;
1232 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1234 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1235 if ( CORBA::is_nil( aGrp ) )
1239 SMESH::ElementType aCurrType = aGrp->GetType();
1240 if ( aType == SMESH::ALL )
1244 if ( aType != aCurrType )
1245 return SMESH::SMESH_Group::_nil();
1249 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1250 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1252 int aCurrId = aCurrIds[ i ];
1253 anIds.push_back( aCurrId );
1260 aResGrp = CreateGroup( aType, theName );
1261 if ( aResGrp->_is_nil() )
1262 return SMESH::SMESH_Group::_nil();
1264 // Create array of identifiers
1265 SMESH::long_array_var aResIds = new SMESH::long_array;
1266 aResIds->length( anIds.size() );
1268 for ( size_t i = 0; i<anIds.size(); i++ )
1269 aResIds[ i ] = anIds[i];
1270 aResGrp->Add( aResIds );
1272 // Update Python script
1273 pyDump << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1274 << &theGroups << ", '" << theName << "' )";
1276 SMESH_CATCH( SMESH::throwCorbaException );
1278 return aResGrp._retn();
1281 //=============================================================================
1283 * New group is created. All mesh elements that are
1284 * present in both initial groups are added to the new one.
1286 //=============================================================================
1287 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1288 SMESH::SMESH_GroupBase_ptr theGroup2,
1289 const char* theName )
1290 throw (SALOME::SALOME_Exception)
1292 SMESH::SMESH_Group_var aResGrp;
1296 _preMeshInfo->FullLoadFromFile();
1298 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1299 theGroup1->GetType() != theGroup2->GetType() )
1300 return SMESH::SMESH_Group::_nil();
1304 // Create Intersection
1305 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1306 if ( aResGrp->_is_nil() )
1309 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1310 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1312 TColStd_MapOfInteger aMap1;
1314 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1315 aMap1.Add( anIds1[ i1 ] );
1317 TColStd_SequenceOfInteger aSeq;
1318 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1319 if ( aMap1.Contains( anIds2[ i2 ] ) )
1320 aSeq.Append( anIds2[ i2 ] );
1322 SMESH::long_array_var aResIds = new SMESH::long_array;
1323 aResIds->length( aSeq.Length() );
1324 for ( size_t resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1325 aResIds[ resI ] = aSeq( resI + 1 );
1326 aResGrp->Add( aResIds );
1328 // Update Python script
1329 pyDump << aResGrp << " = " << _this() << ".IntersectGroups( "
1330 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1332 SMESH_CATCH( SMESH::throwCorbaException );
1334 return aResGrp._retn();
1337 //=============================================================================
1339 \brief Intersect list of groups. New group is created. All mesh elements that
1340 are present in all initial groups simultaneously are added to the new one.
1341 \param theGroups list of groups
1342 \param theName name of group to be created
1343 \return pointer on the group
1345 //=============================================================================
1346 SMESH::SMESH_Group_ptr
1347 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1348 const char* theName )
1349 throw (SALOME::SALOME_Exception)
1351 SMESH::SMESH_Group_var aResGrp;
1355 _preMeshInfo->FullLoadFromFile();
1358 return SMESH::SMESH_Group::_nil();
1360 NCollection_DataMap< int, int > anIdToCount;
1361 SMESH::ElementType aType = SMESH::ALL;
1362 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1364 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1365 if ( CORBA::is_nil( aGrp ) )
1369 SMESH::ElementType aCurrType = aGrp->GetType();
1370 if ( aType == SMESH::ALL )
1374 if ( aType != aCurrType )
1375 return SMESH::SMESH_Group::_nil();
1378 // calculates number of occurance ids in groups
1379 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1380 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1382 int aCurrId = aCurrIds[ i ];
1383 if ( !anIdToCount.IsBound( aCurrId ) )
1384 anIdToCount.Bind( aCurrId, 1 );
1386 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1390 // create map of ids
1391 int nbGrp = theGroups.length();
1392 vector< int > anIds;
1393 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1394 for ( ; anIter.More(); anIter.Next() )
1396 int aCurrId = anIter.Key();
1397 int aCurrNb = anIter.Value();
1398 if ( aCurrNb == nbGrp )
1399 anIds.push_back( aCurrId );
1405 aResGrp = CreateGroup( aType, theName );
1406 if ( aResGrp->_is_nil() )
1407 return SMESH::SMESH_Group::_nil();
1409 // Create array of identifiers
1410 SMESH::long_array_var aResIds = new SMESH::long_array;
1411 aResIds->length( anIds.size() );
1413 for ( size_t i = 0; i<anIds.size(); i++ )
1414 aResIds[ i ] = anIds[i];
1415 aResGrp->Add( aResIds );
1417 // Update Python script
1418 pyDump << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1419 << &theGroups << ", '" << theName << "' )";
1421 SMESH_CATCH( SMESH::throwCorbaException );
1423 return aResGrp._retn();
1426 //=============================================================================
1428 * New group is created. All mesh elements that are present in
1429 * main group but do not present in tool group are added to the new one
1431 //=============================================================================
1432 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1433 SMESH::SMESH_GroupBase_ptr theGroup2,
1434 const char* theName )
1435 throw (SALOME::SALOME_Exception)
1437 SMESH::SMESH_Group_var aResGrp;
1441 _preMeshInfo->FullLoadFromFile();
1443 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1444 theGroup1->GetType() != theGroup2->GetType() )
1445 return SMESH::SMESH_Group::_nil();
1450 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1451 if ( aResGrp->_is_nil() )
1454 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1455 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1457 TColStd_MapOfInteger aMap2;
1459 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1460 aMap2.Add( anIds2[ i2 ] );
1462 TColStd_SequenceOfInteger aSeq;
1463 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1464 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1465 aSeq.Append( anIds1[ i1 ] );
1467 SMESH::long_array_var aResIds = new SMESH::long_array;
1468 aResIds->length( aSeq.Length() );
1470 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1471 aResIds[ resI ] = aSeq( resI + 1 );
1472 aResGrp->Add( aResIds );
1474 // Update Python script
1475 pyDump << aResGrp << " = " << _this() << ".CutGroups( "
1476 << theGroup1 << ", " << theGroup2 << ", '"
1477 << theName << "' )";
1479 SMESH_CATCH( SMESH::throwCorbaException );
1481 return aResGrp._retn();
1484 //=============================================================================
1486 \brief Cut lists of groups. New group is created. All mesh elements that are
1487 present in main groups but do not present in tool groups are added to the new one
1488 \param theMainGroups list of main groups
1489 \param theToolGroups list of tool groups
1490 \param theName name of group to be created
1491 \return pointer on the group
1493 //=============================================================================
1494 SMESH::SMESH_Group_ptr
1495 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1496 const SMESH::ListOfGroups& theToolGroups,
1497 const char* theName )
1498 throw (SALOME::SALOME_Exception)
1500 SMESH::SMESH_Group_var aResGrp;
1504 _preMeshInfo->FullLoadFromFile();
1507 return SMESH::SMESH_Group::_nil();
1509 set< int > aToolIds;
1510 SMESH::ElementType aType = SMESH::ALL;
1512 // iterate through tool groups
1513 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1515 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1516 if ( CORBA::is_nil( aGrp ) )
1520 SMESH::ElementType aCurrType = aGrp->GetType();
1521 if ( aType == SMESH::ALL )
1525 if ( aType != aCurrType )
1526 return SMESH::SMESH_Group::_nil();
1530 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1531 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1533 int aCurrId = aCurrIds[ i ];
1534 aToolIds.insert( aCurrId );
1538 vector< int > anIds; // result
1540 // Iterate through main group
1541 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1543 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1544 if ( CORBA::is_nil( aGrp ) )
1548 SMESH::ElementType aCurrType = aGrp->GetType();
1549 if ( aType == SMESH::ALL )
1553 if ( aType != aCurrType )
1554 return SMESH::SMESH_Group::_nil();
1558 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1559 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1561 int aCurrId = aCurrIds[ i ];
1562 if ( !aToolIds.count( aCurrId ) )
1563 anIds.push_back( aCurrId );
1570 aResGrp = CreateGroup( aType, theName );
1571 if ( aResGrp->_is_nil() )
1572 return SMESH::SMESH_Group::_nil();
1574 // Create array of identifiers
1575 SMESH::long_array_var aResIds = new SMESH::long_array;
1576 aResIds->length( anIds.size() );
1578 for (int i=0; i<anIds.size(); i++ )
1579 aResIds[ i ] = anIds[i];
1580 aResGrp->Add( aResIds );
1582 // Update Python script
1583 pyDump << aResGrp << " = " << _this() << ".CutListOfGroups( "
1584 << &theMainGroups << ", " << &theToolGroups << ", '"
1585 << theName << "' )";
1587 SMESH_CATCH( SMESH::throwCorbaException );
1589 return aResGrp._retn();
1592 //=============================================================================
1594 \brief Create groups of entities from existing groups of superior dimensions
1596 1) extract all nodes from each group,
1597 2) combine all elements of specified dimension laying on these nodes.
1598 \param theGroups list of source groups
1599 \param theElemType dimension of elements
1600 \param theName name of new group
1601 \return pointer on new group
1605 //=============================================================================
1607 SMESH::SMESH_Group_ptr
1608 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1609 SMESH::ElementType theElemType,
1610 const char* theName )
1611 throw (SALOME::SALOME_Exception)
1613 SMESH::SMESH_Group_var aResGrp;
1617 _preMeshInfo->FullLoadFromFile();
1619 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1621 if ( !theName || !aMeshDS )
1622 return SMESH::SMESH_Group::_nil();
1624 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1630 aResGrp = CreateGroup( theElemType, theName );
1631 if ( aResGrp->_is_nil() )
1632 return SMESH::SMESH_Group::_nil();
1634 SMESHDS_GroupBase* groupBaseDS =
1635 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1636 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1638 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1640 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1641 if ( CORBA::is_nil( aGrp ) )
1644 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1645 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1647 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1649 while ( elIt->more() ) {
1650 const SMDS_MeshElement* el = elIt->next();
1651 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1652 while ( nIt->more() )
1653 resGroupCore.Add( nIt->next() );
1656 else // get elements of theElemType based on nodes of every element of group
1658 while ( elIt->more() )
1660 const SMDS_MeshElement* el = elIt->next(); // an element of group
1661 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1662 TIDSortedElemSet checkedElems;
1663 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1664 while ( nIt->more() )
1666 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1667 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1668 // check nodes of elements of theElemType around el
1669 while ( elOfTypeIt->more() )
1671 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1672 if ( !checkedElems.insert( elOfType ).second ) continue;
1674 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1675 bool allNodesOK = true;
1676 while ( nIt2->more() && allNodesOK )
1677 allNodesOK = elNodes.count( nIt2->next() );
1679 resGroupCore.Add( elOfType );
1686 // Update Python script
1687 pyDump << aResGrp << " = " << _this() << ".CreateDimGroup( "
1688 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1690 SMESH_CATCH( SMESH::throwCorbaException );
1692 return aResGrp._retn();
1695 //================================================================================
1697 * \brief Remember GEOM group data
1699 //================================================================================
1701 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1702 CORBA::Object_ptr theSmeshObj)
1704 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1707 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1708 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1709 if ( groupSO->_is_nil() )
1712 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1713 GEOM::GEOM_IGroupOperations_wrap groupOp =
1714 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1715 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1718 _geomGroupData.push_back( TGeomGroupData() );
1719 TGeomGroupData & groupData = _geomGroupData.back();
1721 CORBA::String_var entry = groupSO->GetID();
1722 groupData._groupEntry = entry.in();
1724 for ( int i = 0; i < ids->length(); ++i )
1725 groupData._indices.insert( ids[i] );
1727 groupData._smeshObject = theSmeshObj;
1730 //================================================================================
1732 * Remove GEOM group data relating to removed smesh object
1734 //================================================================================
1736 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1738 list<TGeomGroupData>::iterator
1739 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1740 for ( ; data != dataEnd; ++data ) {
1741 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1742 _geomGroupData.erase( data );
1748 //================================================================================
1750 * \brief Return new group contents if it has been changed and update group data
1752 //================================================================================
1754 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1756 TopoDS_Shape newShape;
1759 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1760 if ( study->_is_nil() ) return newShape; // means "not changed"
1761 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1762 if ( !groupSO->_is_nil() )
1764 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1765 if ( CORBA::is_nil( groupObj )) return newShape;
1766 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1768 // get indices of group items
1769 set<int> curIndices;
1770 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1771 GEOM::GEOM_IGroupOperations_wrap groupOp =
1772 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1773 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1774 for ( int i = 0; i < ids->length(); ++i )
1775 curIndices.insert( ids[i] );
1777 if ( groupData._indices == curIndices )
1778 return newShape; // group not changed
1781 groupData._indices = curIndices;
1783 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1784 if ( !geomClient ) return newShape;
1785 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1786 geomClient->RemoveShapeFromBuffer( groupIOR );
1787 newShape = _gen_i->GeomObjectToShape( geomGroup );
1790 if ( newShape.IsNull() ) {
1791 // geom group becomes empty - return empty compound
1792 TopoDS_Compound compound;
1793 BRep_Builder().MakeCompound(compound);
1794 newShape = compound;
1801 //=============================================================================
1803 * \brief Storage of shape and index used in CheckGeomGroupModif()
1805 //=============================================================================
1806 struct TIndexedShape
1809 TopoDS_Shape _shape;
1810 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1813 //=============================================================================
1815 * \brief Update objects depending on changed geom groups
1817 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1818 * issue 0020210: Update of a smesh group after modification of the associated geom group
1820 //=============================================================================
1822 void SMESH_Mesh_i::CheckGeomGroupModif()
1824 if ( !_impl->HasShapeToMesh() ) return;
1826 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1827 if ( study->_is_nil() ) return;
1829 CORBA::Long nbEntities = NbNodes() + NbElements();
1831 // Check if group contents changed
1833 typedef map< string, TopoDS_Shape > TEntry2Geom;
1834 TEntry2Geom newGroupContents;
1836 list<TGeomGroupData>::iterator
1837 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1838 for ( ; data != dataEnd; ++data )
1840 pair< TEntry2Geom::iterator, bool > it_new =
1841 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1842 bool processedGroup = !it_new.second;
1843 TopoDS_Shape& newShape = it_new.first->second;
1844 if ( !processedGroup )
1845 newShape = newGroupShape( *data );
1846 if ( newShape.IsNull() )
1847 continue; // no changes
1850 _preMeshInfo->ForgetOrLoad();
1852 if ( processedGroup ) { // update group indices
1853 list<TGeomGroupData>::iterator data2 = data;
1854 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1855 data->_indices = data2->_indices;
1858 // Update SMESH objects according to new GEOM group contents
1860 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1861 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1863 int oldID = submesh->GetId();
1864 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1866 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1868 // update hypotheses
1869 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1870 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1871 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1873 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1874 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1876 // care of submeshes
1877 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1878 int newID = newSubmesh->GetId();
1879 if ( newID != oldID ) {
1880 _mapSubMesh [ newID ] = newSubmesh;
1881 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1882 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1883 _mapSubMesh. erase(oldID);
1884 _mapSubMesh_i. erase(oldID);
1885 _mapSubMeshIor.erase(oldID);
1886 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1891 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1892 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1893 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1895 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1897 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1898 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1899 ds->SetShape( newShape );
1904 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1905 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1907 // Remove groups and submeshes basing on removed sub-shapes
1909 TopTools_MapOfShape newShapeMap;
1910 TopoDS_Iterator shapeIt( newShape );
1911 for ( ; shapeIt.More(); shapeIt.Next() )
1912 newShapeMap.Add( shapeIt.Value() );
1914 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1915 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1917 if ( newShapeMap.Contains( shapeIt.Value() ))
1919 TopTools_IndexedMapOfShape oldShapeMap;
1920 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1921 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1923 const TopoDS_Shape& oldShape = oldShapeMap(i);
1924 int oldInd = meshDS->ShapeToIndex( oldShape );
1926 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1927 if ( i_smIor != _mapSubMeshIor.end() ) {
1928 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1931 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1932 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1934 // check if a group bases on oldInd shape
1935 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1936 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1937 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1938 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1940 RemoveGroup( i_grp->second ); // several groups can base on same shape
1941 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1946 // Reassign hypotheses and update groups after setting the new shape to mesh
1948 // collect anassigned hypotheses
1949 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1950 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1951 TShapeHypList assignedHyps;
1952 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1954 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1955 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1956 if ( !hyps.empty() ) {
1957 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1958 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1959 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1962 // collect shapes supporting groups
1963 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1964 TShapeTypeList groupData;
1965 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1966 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1967 for ( ; grIt != groups.end(); ++grIt )
1969 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1971 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1973 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1974 _impl->ShapeToMesh( newShape );
1976 // reassign hypotheses
1977 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1978 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1980 TIndexedShape& geom = indS_hyps->first;
1981 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1982 int oldID = geom._index;
1983 int newID = meshDS->ShapeToIndex( geom._shape );
1984 if ( oldID == 1 ) { // main shape
1986 geom._shape = newShape;
1990 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1991 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1992 // care of submeshes
1993 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1994 if ( newID != oldID ) {
1995 _mapSubMesh [ newID ] = newSubmesh;
1996 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1997 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1998 _mapSubMesh. erase(oldID);
1999 _mapSubMesh_i. erase(oldID);
2000 _mapSubMeshIor.erase(oldID);
2001 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2005 TShapeTypeList::iterator geomType = groupData.begin();
2006 for ( ; geomType != groupData.end(); ++geomType )
2008 const TIndexedShape& geom = geomType->first;
2009 int oldID = geom._index;
2010 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2013 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2014 CORBA::String_var name = groupSO->GetName();
2016 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2018 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2019 group_i->changeLocalId( newID );
2022 break; // everything has been updated
2025 } // loop on group data
2029 CORBA::Long newNbEntities = NbNodes() + NbElements();
2030 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2031 if ( newNbEntities != nbEntities )
2033 // Add all SObjects with icons to soToUpdateIcons
2034 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2036 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2037 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2038 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2040 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2041 i_gr != _mapGroups.end(); ++i_gr ) // groups
2042 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2045 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2046 for ( ; so != soToUpdateIcons.end(); ++so )
2047 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2050 //=============================================================================
2052 * \brief Create standalone group from a group on geometry or filter
2054 //=============================================================================
2056 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2057 throw (SALOME::SALOME_Exception)
2059 SMESH::SMESH_Group_var aGroup;
2064 _preMeshInfo->FullLoadFromFile();
2066 if ( theGroup->_is_nil() )
2067 return aGroup._retn();
2069 SMESH_GroupBase_i* aGroupToRem =
2070 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2072 return aGroup._retn();
2074 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2076 int anId = aGroupToRem->GetLocalID();
2077 if ( !_impl->ConvertToStandalone( anId ) )
2078 return aGroup._retn();
2079 removeGeomGroupData( theGroup );
2081 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2083 // remove old instance of group from own map
2084 _mapGroups.erase( anId );
2086 SALOMEDS::StudyBuilder_var builder;
2087 SALOMEDS::SObject_wrap aGroupSO;
2088 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2089 if ( !aStudy->_is_nil() ) {
2090 builder = aStudy->NewBuilder();
2091 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2092 if ( !aGroupSO->_is_nil() )
2094 // remove reference to geometry
2095 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2096 for ( ; chItr->More(); chItr->Next() )
2097 // Remove group's child SObject
2098 builder->RemoveObject( chItr->Value() );
2100 // Update Python script
2101 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2102 << aGroupSO << " )";
2104 // change icon of Group on Filter
2107 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2108 const int isEmpty = ( elemTypes->length() == 0 );
2111 SALOMEDS::GenericAttribute_wrap anAttr =
2112 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2113 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2114 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2120 // remember new group in own map
2121 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2122 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2124 // register CORBA object for persistence
2125 _gen_i->RegisterObject( aGroup );
2127 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2128 builder->SetIOR( aGroupSO, ior.in() );
2130 SMESH_CATCH( SMESH::throwCorbaException );
2132 return aGroup._retn();
2135 //=============================================================================
2139 //=============================================================================
2141 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2143 if(MYDEBUG) MESSAGE( "createSubMesh" );
2144 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2146 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2147 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2148 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2149 SMESH::SMESH_subMesh_var subMesh
2150 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2152 _mapSubMesh[subMeshId] = mySubMesh;
2153 _mapSubMesh_i[subMeshId] = subMeshServant;
2154 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2156 // register CORBA object for persistence
2157 int nextId = _gen_i->RegisterObject( subMesh );
2158 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2160 // to track changes of GEOM groups
2161 addGeomGroupData( theSubShapeObject, subMesh );
2163 return subMesh._retn();
2166 //=======================================================================
2167 //function : getSubMesh
2169 //=======================================================================
2171 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2173 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2174 if ( it == _mapSubMeshIor.end() )
2175 return SMESH::SMESH_subMesh::_nil();
2177 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2181 //=============================================================================
2185 //=============================================================================
2187 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2188 GEOM::GEOM_Object_ptr theSubShapeObject )
2190 bool isHypChanged = false;
2191 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2192 return isHypChanged;
2194 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2196 CORBA::Long shapeId = theSubMesh->GetId();
2197 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2199 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2202 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2203 isHypChanged = !hyps.empty();
2204 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2205 for ( ; hyp != hyps.end(); ++hyp )
2206 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2213 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2214 isHypChanged = ( aHypList->length() > 0 );
2215 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2216 removeHypothesis( theSubShapeObject, aHypList[i] );
2219 catch( const SALOME::SALOME_Exception& ) {
2220 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2222 removeGeomGroupData( theSubShapeObject );
2224 int subMeshId = theSubMesh->GetId();
2226 _mapSubMesh.erase(subMeshId);
2227 _mapSubMesh_i.erase(subMeshId);
2228 _mapSubMeshIor.erase(subMeshId);
2230 return isHypChanged;
2233 //=============================================================================
2237 //=============================================================================
2239 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2240 const char* theName,
2241 const TopoDS_Shape& theShape,
2242 const SMESH_PredicatePtr& thePredicate )
2244 std::string newName;
2245 if ( !theName || strlen( theName ) == 0 )
2247 std::set< std::string > presentNames;
2248 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2249 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2250 presentNames.insert( i_gr->second->GetName() );
2252 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2253 } while ( !presentNames.insert( newName ).second );
2254 theName = newName.c_str();
2257 SMESH::SMESH_GroupBase_var aGroup;
2258 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2260 SMESH_GroupBase_i* aGroupImpl;
2261 if ( !theShape.IsNull() )
2262 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2263 else if ( thePredicate )
2264 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2266 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2268 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2269 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2271 // register CORBA object for persistence
2272 int nextId = _gen_i->RegisterObject( aGroup );
2273 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2275 // to track changes of GEOM groups
2276 if ( !theShape.IsNull() ) {
2277 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2278 addGeomGroupData( geom, aGroup );
2281 return aGroup._retn();
2284 //=============================================================================
2286 * SMESH_Mesh_i::removeGroup
2288 * Should be called by ~SMESH_Group_i()
2290 //=============================================================================
2292 void SMESH_Mesh_i::removeGroup( const int theId )
2294 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2295 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2296 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2297 _mapGroups.erase( theId );
2298 removeGeomGroupData( group );
2299 if (! _impl->RemoveGroup( theId ))
2301 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2302 RemoveGroup( group );
2307 //=============================================================================
2311 //=============================================================================
2313 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2314 throw(SALOME::SALOME_Exception)
2316 SMESH::log_array_var aLog;
2320 _preMeshInfo->FullLoadFromFile();
2322 list < SMESHDS_Command * >logDS = _impl->GetLog();
2323 aLog = new SMESH::log_array;
2325 int lg = logDS.size();
2328 list < SMESHDS_Command * >::iterator its = logDS.begin();
2329 while(its != logDS.end()){
2330 SMESHDS_Command *com = *its;
2331 int comType = com->GetType();
2333 int lgcom = com->GetNumber();
2335 const list < int >&intList = com->GetIndexes();
2336 int inum = intList.size();
2338 list < int >::const_iterator ii = intList.begin();
2339 const list < double >&coordList = com->GetCoords();
2340 int rnum = coordList.size();
2342 list < double >::const_iterator ir = coordList.begin();
2343 aLog[indexLog].commandType = comType;
2344 aLog[indexLog].number = lgcom;
2345 aLog[indexLog].coords.length(rnum);
2346 aLog[indexLog].indexes.length(inum);
2347 for(int i = 0; i < rnum; i++){
2348 aLog[indexLog].coords[i] = *ir;
2349 //MESSAGE(" "<<i<<" "<<ir.Value());
2352 for(int i = 0; i < inum; i++){
2353 aLog[indexLog].indexes[i] = *ii;
2354 //MESSAGE(" "<<i<<" "<<ii.Value());
2363 SMESH_CATCH( SMESH::throwCorbaException );
2365 return aLog._retn();
2369 //=============================================================================
2373 //=============================================================================
2375 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2379 SMESH_CATCH( SMESH::throwCorbaException );
2382 //=============================================================================
2386 //=============================================================================
2388 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2393 //=============================================================================
2397 //=============================================================================
2399 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2404 //=============================================================================
2407 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2408 // issue 0020918: groups removal is caused by hyp modification
2409 // issue 0021208: to forget not loaded mesh data at hyp modification
2410 struct TCallUp_i : public SMESH_Mesh::TCallUp
2412 SMESH_Mesh_i* _mesh;
2413 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2414 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2415 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2416 virtual void Load () { _mesh->Load(); }
2420 //================================================================================
2422 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2424 //================================================================================
2426 void SMESH_Mesh_i::onHypothesisModified()
2429 _preMeshInfo->ForgetOrLoad();
2432 //=============================================================================
2436 //=============================================================================
2438 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2440 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2443 _impl->SetCallUp( new TCallUp_i(this));
2446 //=============================================================================
2450 //=============================================================================
2452 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2454 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2458 //=============================================================================
2460 * Return mesh editor
2462 //=============================================================================
2464 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2465 throw (SALOME::SALOME_Exception)
2467 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2471 _preMeshInfo->FullLoadFromFile();
2473 // Create MeshEditor
2474 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2475 aMeshEdVar = aMeshEditor->_this();
2477 // Update Python script
2478 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2480 SMESH_CATCH( SMESH::throwCorbaException );
2482 return aMeshEdVar._retn();
2485 //=============================================================================
2487 * Return mesh edition previewer
2489 //=============================================================================
2491 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2492 throw (SALOME::SALOME_Exception)
2494 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2498 _preMeshInfo->FullLoadFromFile();
2500 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2501 aMeshEdVar = aMeshEditor->_this();
2503 SMESH_CATCH( SMESH::throwCorbaException );
2505 return aMeshEdVar._retn();
2508 //================================================================================
2510 * \brief Return true if the mesh has been edited since a last total re-compute
2511 * and those modifications may prevent successful partial re-compute
2513 //================================================================================
2515 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2517 Unexpect aCatch(SALOME_SalomeException);
2518 return _impl->HasModificationsToDiscard();
2521 //================================================================================
2523 * \brief Returns a random unique color
2525 //================================================================================
2527 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2529 const int MAX_ATTEMPTS = 100;
2531 double tolerance = 0.5;
2532 SALOMEDS::Color col;
2536 // generate random color
2537 double red = (double)rand() / RAND_MAX;
2538 double green = (double)rand() / RAND_MAX;
2539 double blue = (double)rand() / RAND_MAX;
2540 // check existence in the list of the existing colors
2541 bool matched = false;
2542 std::list<SALOMEDS::Color>::const_iterator it;
2543 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2544 SALOMEDS::Color color = *it;
2545 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2546 matched = tol < tolerance;
2548 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2549 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2557 //=============================================================================
2559 * Sets auto-color mode. If it is on, groups get unique random colors
2561 //=============================================================================
2563 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2565 Unexpect aCatch(SALOME_SalomeException);
2566 _impl->SetAutoColor(theAutoColor);
2568 TPythonDump pyDump; // not to dump group->SetColor() from below code
2569 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2571 std::list<SALOMEDS::Color> aReservedColors;
2572 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2573 for ( ; it != _mapGroups.end(); it++ ) {
2574 if ( CORBA::is_nil( it->second )) continue;
2575 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2576 it->second->SetColor( aColor );
2577 aReservedColors.push_back( aColor );
2581 //=============================================================================
2583 * Returns true if auto-color mode is on
2585 //=============================================================================
2587 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2589 Unexpect aCatch(SALOME_SalomeException);
2590 return _impl->GetAutoColor();
2593 //=============================================================================
2595 * Checks if there are groups with equal names
2597 //=============================================================================
2599 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2601 return _impl->HasDuplicatedGroupNamesMED();
2604 //================================================================================
2606 * \brief Care of a file before exporting mesh into it
2608 //================================================================================
2610 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2612 TCollection_AsciiString aFullName ((char*)file);
2613 OSD_Path aPath (aFullName);
2614 OSD_File aFile (aPath);
2615 if (aFile.Exists()) {
2616 // existing filesystem node
2617 if (aFile.KindOfFile() == OSD_FILE) {
2618 if (aFile.IsWriteable()) {
2623 if (aFile.Failed()) {
2624 TCollection_AsciiString msg ("File ");
2625 msg += aFullName + " cannot be replaced.";
2626 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2629 TCollection_AsciiString msg ("File ");
2630 msg += aFullName + " cannot be overwritten.";
2631 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2634 TCollection_AsciiString msg ("Location ");
2635 msg += aFullName + " is not a file.";
2636 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2639 // nonexisting file; check if it can be created
2641 aFile.Build(OSD_WriteOnly, OSD_Protection());
2642 if (aFile.Failed()) {
2643 TCollection_AsciiString msg ("You cannot create the file ");
2644 msg += aFullName + ". Check the directory existance and access rights.";
2645 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2653 //================================================================================
2655 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2656 * \param file - file name
2657 * \param overwrite - to erase the file or not
2658 * \retval string - mesh name
2660 //================================================================================
2662 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2663 CORBA::Boolean overwrite)
2666 PrepareForWriting(file, overwrite);
2667 string aMeshName = "Mesh";
2668 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2669 if ( !aStudy->_is_nil() ) {
2670 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2671 if ( !aMeshSO->_is_nil() ) {
2672 CORBA::String_var name = aMeshSO->GetName();
2674 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2675 if ( !aStudy->GetProperties()->IsLocked() )
2677 SALOMEDS::GenericAttribute_wrap anAttr;
2678 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2679 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2680 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2681 ASSERT(!aFileName->_is_nil());
2682 aFileName->SetValue(file);
2683 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2684 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2685 ASSERT(!aFileType->_is_nil());
2686 aFileType->SetValue("FICHIERMED");
2690 // Update Python script
2691 // set name of mesh before export
2692 TPythonDump() << _gen_i << ".SetName(" << _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 throw(SALOME::SALOME_Exception)
2712 Unexpect aCatch(SALOME_SalomeException);
2714 _preMeshInfo->FullLoadFromFile();
2716 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2717 TPythonDump() << _this() << ".ExportToMEDX( r'"
2718 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2720 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2723 //================================================================================
2725 * \brief Export a mesh to a med file
2727 //================================================================================
2729 void SMESH_Mesh_i::ExportToMED (const char* file,
2730 CORBA::Boolean auto_groups,
2731 SMESH::MED_VERSION theVersion)
2732 throw(SALOME::SALOME_Exception)
2734 ExportToMEDX(file,auto_groups,theVersion,true);
2737 //================================================================================
2739 * \brief Export a mesh to a med file
2741 //================================================================================
2743 void SMESH_Mesh_i::ExportMED (const char* file,
2744 CORBA::Boolean auto_groups)
2745 throw(SALOME::SALOME_Exception)
2747 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2750 //================================================================================
2752 * \brief Export a mesh to a SAUV file
2754 //================================================================================
2756 void SMESH_Mesh_i::ExportSAUV (const char* file,
2757 CORBA::Boolean auto_groups)
2758 throw(SALOME::SALOME_Exception)
2760 Unexpect aCatch(SALOME_SalomeException);
2762 _preMeshInfo->FullLoadFromFile();
2764 string aMeshName = prepareMeshNameAndGroups(file, true);
2765 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2766 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2770 //================================================================================
2772 * \brief Export a mesh to a DAT file
2774 //================================================================================
2776 void SMESH_Mesh_i::ExportDAT (const char *file)
2777 throw(SALOME::SALOME_Exception)
2779 Unexpect aCatch(SALOME_SalomeException);
2781 _preMeshInfo->FullLoadFromFile();
2783 // Update Python script
2784 // check names of groups
2786 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2789 PrepareForWriting(file);
2790 _impl->ExportDAT(file);
2793 //================================================================================
2795 * \brief Export a mesh to an UNV file
2797 //================================================================================
2799 void SMESH_Mesh_i::ExportUNV (const char *file)
2800 throw(SALOME::SALOME_Exception)
2802 Unexpect aCatch(SALOME_SalomeException);
2804 _preMeshInfo->FullLoadFromFile();
2806 // Update Python script
2807 // check names of groups
2809 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2812 PrepareForWriting(file);
2813 _impl->ExportUNV(file);
2816 //================================================================================
2818 * \brief Export a mesh to an STL file
2820 //================================================================================
2822 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2823 throw(SALOME::SALOME_Exception)
2825 Unexpect aCatch(SALOME_SalomeException);
2827 _preMeshInfo->FullLoadFromFile();
2829 // Update Python script
2830 // check names of groups
2832 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2835 PrepareForWriting(file);
2836 _impl->ExportSTL(file, isascii);
2839 //================================================================================
2841 * \brief Export a part of mesh to a med file
2843 //================================================================================
2845 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2847 CORBA::Boolean auto_groups,
2848 ::SMESH::MED_VERSION version,
2849 ::CORBA::Boolean overwrite)
2850 throw (SALOME::SALOME_Exception)
2852 Unexpect aCatch(SALOME_SalomeException);
2854 _preMeshInfo->FullLoadFromFile();
2856 PrepareForWriting(file, overwrite);
2858 string aMeshName = "Mesh";
2859 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2860 if ( !aStudy->_is_nil() ) {
2861 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2862 if ( !SO->_is_nil() ) {
2863 CORBA::String_var name = SO->GetName();
2867 SMESH_MeshPartDS partDS( meshPart );
2868 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2870 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2871 << auto_groups << ", " << version << ", " << overwrite << " )";
2874 //================================================================================
2876 * \brief Export a part of mesh to a DAT file
2878 //================================================================================
2880 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2882 throw (SALOME::SALOME_Exception)
2884 Unexpect aCatch(SALOME_SalomeException);
2886 _preMeshInfo->FullLoadFromFile();
2888 PrepareForWriting(file);
2890 SMESH_MeshPartDS partDS( meshPart );
2891 _impl->ExportDAT(file,&partDS);
2893 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2895 //================================================================================
2897 * \brief Export a part of mesh to an UNV file
2899 //================================================================================
2901 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2903 throw (SALOME::SALOME_Exception)
2905 Unexpect aCatch(SALOME_SalomeException);
2907 _preMeshInfo->FullLoadFromFile();
2909 PrepareForWriting(file);
2911 SMESH_MeshPartDS partDS( meshPart );
2912 _impl->ExportUNV(file, &partDS);
2914 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2916 //================================================================================
2918 * \brief Export a part of mesh to an STL file
2920 //================================================================================
2922 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2924 ::CORBA::Boolean isascii)
2925 throw (SALOME::SALOME_Exception)
2927 Unexpect aCatch(SALOME_SalomeException);
2929 _preMeshInfo->FullLoadFromFile();
2931 PrepareForWriting(file);
2933 SMESH_MeshPartDS partDS( meshPart );
2934 _impl->ExportSTL(file, isascii, &partDS);
2936 TPythonDump() << _this() << ".ExportPartToSTL( "
2937 << meshPart<< ", r'" << file << "', " << isascii << ")";
2940 //================================================================================
2942 * \brief Export a part of mesh to an STL file
2944 //================================================================================
2946 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2948 CORBA::Boolean overwrite)
2949 throw (SALOME::SALOME_Exception)
2952 Unexpect aCatch(SALOME_SalomeException);
2954 _preMeshInfo->FullLoadFromFile();
2956 PrepareForWriting(file,overwrite);
2958 SMESH_MeshPartDS partDS( meshPart );
2959 _impl->ExportCGNS(file, &partDS);
2961 TPythonDump() << _this() << ".ExportCGNS( "
2962 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2964 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2968 //================================================================================
2970 * \brief Export a part of mesh to a GMF file
2972 //================================================================================
2974 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
2976 bool withRequiredGroups)
2977 throw (SALOME::SALOME_Exception)
2979 Unexpect aCatch(SALOME_SalomeException);
2981 _preMeshInfo->FullLoadFromFile();
2983 PrepareForWriting(file,/*overwrite=*/true);
2985 SMESH_MeshPartDS partDS( meshPart );
2986 _impl->ExportGMF(file, &partDS, withRequiredGroups);
2988 TPythonDump() << _this() << ".ExportGMF( "
2989 << meshPart<< ", r'"
2991 << withRequiredGroups << ")";
2994 //=============================================================================
2996 * Return implementation of SALOME_MED::MESH interfaces
2998 //=============================================================================
3000 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
3002 Unexpect aCatch(SALOME_SalomeException);
3004 _preMeshInfo->FullLoadFromFile();
3006 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
3007 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
3008 return aMesh._retn();
3011 //=============================================================================
3013 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3015 Unexpect aCatch(SALOME_SalomeException);
3017 return _preMeshInfo->NbNodes();
3019 return _impl->NbNodes();
3022 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3024 Unexpect aCatch(SALOME_SalomeException);
3026 return _preMeshInfo->NbElements();
3028 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3031 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3033 Unexpect aCatch(SALOME_SalomeException);
3035 return _preMeshInfo->Nb0DElements();
3037 return _impl->Nb0DElements();
3040 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3042 Unexpect aCatch(SALOME_SalomeException);
3044 return _preMeshInfo->NbBalls();
3046 return _impl->NbBalls();
3049 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3051 Unexpect aCatch(SALOME_SalomeException);
3053 return _preMeshInfo->NbEdges();
3055 return _impl->NbEdges();
3058 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3059 throw(SALOME::SALOME_Exception)
3061 Unexpect aCatch(SALOME_SalomeException);
3063 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3065 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3068 //=============================================================================
3070 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3072 Unexpect aCatch(SALOME_SalomeException);
3074 return _preMeshInfo->NbFaces();
3076 return _impl->NbFaces();
3079 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3081 Unexpect aCatch(SALOME_SalomeException);
3083 return _preMeshInfo->NbTriangles();
3085 return _impl->NbTriangles();
3088 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3090 Unexpect aCatch(SALOME_SalomeException);
3092 return _preMeshInfo->NbBiQuadTriangles();
3094 return _impl->NbBiQuadTriangles();
3097 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3099 Unexpect aCatch(SALOME_SalomeException);
3101 return _preMeshInfo->NbQuadrangles();
3103 return _impl->NbQuadrangles();
3106 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3108 Unexpect aCatch(SALOME_SalomeException);
3110 return _preMeshInfo->NbBiQuadQuadrangles();
3112 return _impl->NbBiQuadQuadrangles();
3115 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3117 Unexpect aCatch(SALOME_SalomeException);
3119 return _preMeshInfo->NbPolygons();
3121 return _impl->NbPolygons();
3124 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3125 throw(SALOME::SALOME_Exception)
3127 Unexpect aCatch(SALOME_SalomeException);
3129 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3131 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3134 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3135 throw(SALOME::SALOME_Exception)
3137 Unexpect aCatch(SALOME_SalomeException);
3139 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3141 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3144 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3145 throw(SALOME::SALOME_Exception)
3147 Unexpect aCatch(SALOME_SalomeException);
3149 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3151 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3154 //=============================================================================
3156 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3158 Unexpect aCatch(SALOME_SalomeException);
3160 return _preMeshInfo->NbVolumes();
3162 return _impl->NbVolumes();
3165 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3167 Unexpect aCatch(SALOME_SalomeException);
3169 return _preMeshInfo->NbTetras();
3171 return _impl->NbTetras();
3174 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3176 Unexpect aCatch(SALOME_SalomeException);
3178 return _preMeshInfo->NbHexas();
3180 return _impl->NbHexas();
3183 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3185 Unexpect aCatch(SALOME_SalomeException);
3187 return _preMeshInfo->NbTriQuadHexas();
3189 return _impl->NbTriQuadraticHexas();
3192 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3194 Unexpect aCatch(SALOME_SalomeException);
3196 return _preMeshInfo->NbPyramids();
3198 return _impl->NbPyramids();
3201 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3203 Unexpect aCatch(SALOME_SalomeException);
3205 return _preMeshInfo->NbPrisms();
3207 return _impl->NbPrisms();
3210 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3212 Unexpect aCatch(SALOME_SalomeException);
3214 return _preMeshInfo->NbHexPrisms();
3216 return _impl->NbHexagonalPrisms();
3219 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3221 Unexpect aCatch(SALOME_SalomeException);
3223 return _preMeshInfo->NbPolyhedrons();
3225 return _impl->NbPolyhedrons();
3228 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3229 throw(SALOME::SALOME_Exception)
3231 Unexpect aCatch(SALOME_SalomeException);
3233 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3235 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3238 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3239 throw(SALOME::SALOME_Exception)
3241 Unexpect aCatch(SALOME_SalomeException);
3243 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3245 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3248 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3249 throw(SALOME::SALOME_Exception)
3251 Unexpect aCatch(SALOME_SalomeException);
3253 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3255 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3258 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3259 throw(SALOME::SALOME_Exception)
3261 Unexpect aCatch(SALOME_SalomeException);
3263 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3265 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3268 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3269 throw(SALOME::SALOME_Exception)
3271 Unexpect aCatch(SALOME_SalomeException);
3273 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3275 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3278 //=============================================================================
3280 * Returns nb of published sub-meshes
3282 //=============================================================================
3284 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3286 Unexpect aCatch(SALOME_SalomeException);
3287 return _mapSubMesh_i.size();
3290 //=============================================================================
3292 * Dumps mesh into a string
3294 //=============================================================================
3296 char* SMESH_Mesh_i::Dump()
3300 return CORBA::string_dup( os.str().c_str() );
3303 //=============================================================================
3305 * Method of SMESH_IDSource interface
3307 //=============================================================================
3309 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3311 return GetElementsId();
3314 //=============================================================================
3316 * Returns ids of all elements
3318 //=============================================================================
3320 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3321 throw (SALOME::SALOME_Exception)
3323 Unexpect aCatch(SALOME_SalomeException);
3325 _preMeshInfo->FullLoadFromFile();
3327 SMESH::long_array_var aResult = new SMESH::long_array();
3328 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3330 if ( aSMESHDS_Mesh == NULL )
3331 return aResult._retn();
3333 long nbElements = NbElements();
3334 aResult->length( nbElements );
3335 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3336 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3337 aResult[i] = anIt->next()->GetID();
3339 return aResult._retn();
3343 //=============================================================================
3345 * Returns ids of all elements of given type
3347 //=============================================================================
3349 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3350 throw (SALOME::SALOME_Exception)
3352 Unexpect aCatch(SALOME_SalomeException);
3354 _preMeshInfo->FullLoadFromFile();
3356 SMESH::long_array_var aResult = new SMESH::long_array();
3357 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3359 if ( aSMESHDS_Mesh == NULL )
3360 return aResult._retn();
3362 long nbElements = NbElements();
3364 // No sense in returning ids of elements along with ids of nodes:
3365 // when theElemType == SMESH::ALL, return node ids only if
3366 // there are no elements
3367 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3368 return GetNodesId();
3370 aResult->length( nbElements );
3374 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3375 while ( i < nbElements && anIt->more() ) {
3376 const SMDS_MeshElement* anElem = anIt->next();
3377 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3378 aResult[i++] = anElem->GetID();
3381 aResult->length( i );
3383 return aResult._retn();
3386 //=============================================================================
3388 * Returns ids of all nodes
3390 //=============================================================================
3392 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3393 throw (SALOME::SALOME_Exception)
3395 Unexpect aCatch(SALOME_SalomeException);
3397 _preMeshInfo->FullLoadFromFile();
3399 SMESH::long_array_var aResult = new SMESH::long_array();
3400 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3402 if ( aSMESHDS_Mesh == NULL )
3403 return aResult._retn();
3405 long nbNodes = NbNodes();
3406 aResult->length( nbNodes );
3407 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3408 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3409 aResult[i] = anIt->next()->GetID();
3411 return aResult._retn();
3414 //=============================================================================
3418 //=============================================================================
3420 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3421 throw (SALOME::SALOME_Exception)
3423 SMESH::ElementType type;
3427 _preMeshInfo->FullLoadFromFile();
3429 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3431 SMESH_CATCH( SMESH::throwCorbaException );
3436 //=============================================================================
3440 //=============================================================================
3442 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3443 throw (SALOME::SALOME_Exception)
3446 _preMeshInfo->FullLoadFromFile();
3448 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3450 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3452 return ( SMESH::EntityType ) e->GetEntityType();
3455 //=============================================================================
3457 * Returns ID of elements for given submesh
3459 //=============================================================================
3460 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3461 throw (SALOME::SALOME_Exception)
3463 SMESH::long_array_var aResult = new SMESH::long_array();
3467 _preMeshInfo->FullLoadFromFile();
3469 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3470 if(!SM) return aResult._retn();
3472 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3473 if(!SDSM) return aResult._retn();
3475 aResult->length(SDSM->NbElements());
3477 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3479 while ( eIt->more() ) {
3480 aResult[i++] = eIt->next()->GetID();
3483 SMESH_CATCH( SMESH::throwCorbaException );
3485 return aResult._retn();
3489 //=============================================================================
3491 * Returns ID of nodes for given submesh
3492 * If param all==true - returns all nodes, else -
3493 * returns only nodes on shapes.
3495 //=============================================================================
3496 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3498 throw (SALOME::SALOME_Exception)
3500 SMESH::long_array_var aResult = new SMESH::long_array();
3504 _preMeshInfo->FullLoadFromFile();
3506 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3507 if(!SM) return aResult._retn();
3509 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3510 if(!SDSM) return aResult._retn();
3513 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3514 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3515 while ( nIt->more() ) {
3516 const SMDS_MeshNode* elem = nIt->next();
3517 theElems.insert( elem->GetID() );
3520 else { // all nodes of submesh elements
3521 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3522 while ( eIt->more() ) {
3523 const SMDS_MeshElement* anElem = eIt->next();
3524 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3525 while ( nIt->more() ) {
3526 const SMDS_MeshElement* elem = nIt->next();
3527 theElems.insert( elem->GetID() );
3532 aResult->length(theElems.size());
3533 set<int>::iterator itElem;
3535 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3536 aResult[i++] = *itElem;
3538 SMESH_CATCH( SMESH::throwCorbaException );
3540 return aResult._retn();
3543 //=============================================================================
3545 * Returns type of elements for given submesh
3547 //=============================================================================
3549 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3550 throw (SALOME::SALOME_Exception)
3552 SMESH::ElementType type;
3556 _preMeshInfo->FullLoadFromFile();
3558 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3559 if(!SM) return SMESH::ALL;
3561 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3562 if(!SDSM) return SMESH::ALL;
3564 if(SDSM->NbElements()==0)
3565 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3567 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3568 const SMDS_MeshElement* anElem = eIt->next();
3570 type = ( SMESH::ElementType ) anElem->GetType();
3572 SMESH_CATCH( SMESH::throwCorbaException );
3578 //=============================================================================
3580 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3582 //=============================================================================
3584 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3587 _preMeshInfo->FullLoadFromFile();
3589 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3591 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3596 //=============================================================================
3598 * Get XYZ coordinates of node as list of double
3599 * If there is not node for given ID - returns empty list
3601 //=============================================================================
3603 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3606 _preMeshInfo->FullLoadFromFile();
3608 SMESH::double_array_var aResult = new SMESH::double_array();
3609 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3610 if ( aSMESHDS_Mesh == NULL )
3611 return aResult._retn();
3614 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3616 return aResult._retn();
3620 aResult[0] = aNode->X();
3621 aResult[1] = aNode->Y();
3622 aResult[2] = aNode->Z();
3623 return aResult._retn();
3627 //=============================================================================
3629 * For given node returns list of IDs of inverse elements
3630 * If there is not node for given ID - returns empty list
3632 //=============================================================================
3634 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3637 _preMeshInfo->FullLoadFromFile();
3639 SMESH::long_array_var aResult = new SMESH::long_array();
3640 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3641 if ( aSMESHDS_Mesh == NULL )
3642 return aResult._retn();
3645 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3647 return aResult._retn();
3649 // find inverse elements
3650 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3651 TColStd_SequenceOfInteger IDs;
3652 while(eIt->more()) {
3653 const SMDS_MeshElement* elem = eIt->next();
3654 IDs.Append(elem->GetID());
3656 if(IDs.Length()>0) {
3657 aResult->length(IDs.Length());
3659 for(; i<=IDs.Length(); i++) {
3660 aResult[i-1] = IDs.Value(i);
3663 return aResult._retn();
3666 //=============================================================================
3668 * \brief Return position of a node on shape
3670 //=============================================================================
3672 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3675 _preMeshInfo->FullLoadFromFile();
3677 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3678 aNodePosition->shapeID = 0;
3679 aNodePosition->shapeType = GEOM::SHAPE;
3681 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3682 if ( !mesh ) return aNodePosition;
3684 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3686 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3688 aNodePosition->shapeID = aNode->getshapeId();
3689 switch ( pos->GetTypeOfPosition() ) {
3691 aNodePosition->shapeType = GEOM::EDGE;
3692 aNodePosition->params.length(1);
3693 aNodePosition->params[0] =
3694 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3697 aNodePosition->shapeType = GEOM::FACE;
3698 aNodePosition->params.length(2);
3699 aNodePosition->params[0] =
3700 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3701 aNodePosition->params[1] =
3702 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3704 case SMDS_TOP_VERTEX:
3705 aNodePosition->shapeType = GEOM::VERTEX;
3707 case SMDS_TOP_3DSPACE:
3708 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3709 aNodePosition->shapeType = GEOM::SOLID;
3710 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3711 aNodePosition->shapeType = GEOM::SHELL;
3717 return aNodePosition;
3720 //=============================================================================
3722 * \brief Return position of an element on shape
3724 //=============================================================================
3726 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
3729 _preMeshInfo->FullLoadFromFile();
3731 SMESH::ElementPosition anElementPosition;
3732 anElementPosition.shapeID = 0;
3733 anElementPosition.shapeType = GEOM::SHAPE;
3735 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3736 if ( !mesh ) return anElementPosition;
3738 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
3740 anElementPosition.shapeID = anElem->getshapeId();
3741 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
3742 if ( !aSp.IsNull() ) {
3743 switch ( aSp.ShapeType() ) {
3745 anElementPosition.shapeType = GEOM::EDGE;
3748 anElementPosition.shapeType = GEOM::FACE;
3751 anElementPosition.shapeType = GEOM::VERTEX;
3754 anElementPosition.shapeType = GEOM::SOLID;
3757 anElementPosition.shapeType = GEOM::SHELL;
3763 return anElementPosition;
3766 //=============================================================================
3768 * If given element is node returns IDs of shape from position
3769 * If there is not node for given ID - returns -1
3771 //=============================================================================
3773 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3776 _preMeshInfo->FullLoadFromFile();
3778 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3779 if ( aSMESHDS_Mesh == NULL )
3783 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3785 return aNode->getshapeId();
3792 //=============================================================================
3794 * For given element returns ID of result shape after
3795 * ::FindShape() from SMESH_MeshEditor
3796 * If there is not element for given ID - returns -1
3798 //=============================================================================
3800 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3803 _preMeshInfo->FullLoadFromFile();
3805 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3806 if ( aSMESHDS_Mesh == NULL )
3809 // try to find element
3810 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3814 ::SMESH_MeshEditor aMeshEditor(_impl);
3815 int index = aMeshEditor.FindShape( elem );
3823 //=============================================================================
3825 * Returns number of nodes for given element
3826 * If there is not element for given ID - returns -1
3828 //=============================================================================
3830 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3833 _preMeshInfo->FullLoadFromFile();
3835 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3836 if ( aSMESHDS_Mesh == NULL ) return -1;
3837 // try to find element
3838 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3839 if(!elem) return -1;
3840 return elem->NbNodes();
3844 //=============================================================================
3846 * Returns ID of node by given index for given element
3847 * If there is not element for given ID - returns -1
3848 * If there is not node for given index - returns -2
3850 //=============================================================================
3852 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3855 _preMeshInfo->FullLoadFromFile();
3857 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3858 if ( aSMESHDS_Mesh == NULL ) return -1;
3859 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3860 if(!elem) return -1;
3861 if( index>=elem->NbNodes() || index<0 ) return -1;
3862 return elem->GetNode(index)->GetID();
3865 //=============================================================================
3867 * Returns IDs of nodes of given element
3869 //=============================================================================
3871 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3874 _preMeshInfo->FullLoadFromFile();
3876 SMESH::long_array_var aResult = new SMESH::long_array();
3877 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3879 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3881 aResult->length( elem->NbNodes() );
3882 for ( int i = 0; i < elem->NbNodes(); ++i )
3883 aResult[ i ] = elem->GetNode( i )->GetID();
3886 return aResult._retn();
3889 //=============================================================================
3891 * Returns true if given node is medium node
3892 * in given quadratic element
3894 //=============================================================================
3896 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3899 _preMeshInfo->FullLoadFromFile();
3901 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3902 if ( aSMESHDS_Mesh == NULL ) return false;
3904 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3905 if(!aNode) return false;
3906 // try to find element
3907 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3908 if(!elem) return false;
3910 return elem->IsMediumNode(aNode);
3914 //=============================================================================
3916 * Returns true if given node is medium node
3917 * in one of quadratic elements
3919 //=============================================================================
3921 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3922 SMESH::ElementType theElemType)
3925 _preMeshInfo->FullLoadFromFile();
3927 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3928 if ( aSMESHDS_Mesh == NULL ) return false;
3931 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3932 if(!aNode) return false;
3934 SMESH_MesherHelper aHelper( *(_impl) );
3936 SMDSAbs_ElementType aType;
3937 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3938 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3939 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3940 else aType = SMDSAbs_All;
3942 return aHelper.IsMedium(aNode,aType);
3946 //=============================================================================
3948 * Returns number of edges for given element
3950 //=============================================================================
3952 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3955 _preMeshInfo->FullLoadFromFile();
3957 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3958 if ( aSMESHDS_Mesh == NULL ) return -1;
3959 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3960 if(!elem) return -1;
3961 return elem->NbEdges();
3965 //=============================================================================
3967 * Returns number of faces for given element
3969 //=============================================================================
3971 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3974 _preMeshInfo->FullLoadFromFile();
3976 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3977 if ( aSMESHDS_Mesh == NULL ) return -1;
3978 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3979 if(!elem) return -1;
3980 return elem->NbFaces();
3983 //=======================================================================
3984 //function : GetElemFaceNodes
3985 //purpose : Returns nodes of given face (counted from zero) for given element.
3986 //=======================================================================
3988 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3989 CORBA::Short faceIndex)
3992 _preMeshInfo->FullLoadFromFile();
3994 SMESH::long_array_var aResult = new SMESH::long_array();
3995 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3997 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3999 SMDS_VolumeTool vtool( elem );
4000 if ( faceIndex < vtool.NbFaces() )
4002 aResult->length( vtool.NbFaceNodes( faceIndex ));
4003 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4004 for ( int i = 0; i < aResult->length(); ++i )
4005 aResult[ i ] = nn[ i ]->GetID();
4009 return aResult._retn();
4012 //=======================================================================
4013 //function : FindElementByNodes
4014 //purpose : Returns an element based on all given nodes.
4015 //=======================================================================
4017 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4020 _preMeshInfo->FullLoadFromFile();
4022 CORBA::Long elemID(0);
4023 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4025 vector< const SMDS_MeshNode * > nn( nodes.length() );
4026 for ( int i = 0; i < nodes.length(); ++i )
4027 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4030 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4031 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4032 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4033 _impl->NbVolumes( ORDER_QUADRATIC )))
4034 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4036 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4041 //=============================================================================
4043 * Returns true if given element is polygon
4045 //=============================================================================
4047 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4050 _preMeshInfo->FullLoadFromFile();
4052 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4053 if ( aSMESHDS_Mesh == NULL ) return false;
4054 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4055 if(!elem) return false;
4056 return elem->IsPoly();
4060 //=============================================================================
4062 * Returns true if given element is quadratic
4064 //=============================================================================
4066 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4069 _preMeshInfo->FullLoadFromFile();
4071 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4072 if ( aSMESHDS_Mesh == NULL ) return false;
4073 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4074 if(!elem) return false;
4075 return elem->IsQuadratic();
4078 //=============================================================================
4080 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4082 //=============================================================================
4084 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4087 _preMeshInfo->FullLoadFromFile();
4089 if ( const SMDS_BallElement* ball =
4090 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4091 return ball->GetDiameter();
4096 //=============================================================================
4098 * Returns bary center for given element
4100 //=============================================================================
4102 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4105 _preMeshInfo->FullLoadFromFile();
4107 SMESH::double_array_var aResult = new SMESH::double_array();
4108 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4109 if ( aSMESHDS_Mesh == NULL )
4110 return aResult._retn();
4112 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4114 return aResult._retn();
4116 if(elem->GetType()==SMDSAbs_Volume) {
4117 SMDS_VolumeTool aTool;
4118 if(aTool.Set(elem)) {
4120 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4125 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4127 double x=0., y=0., z=0.;
4128 for(; anIt->more(); ) {
4130 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4144 return aResult._retn();
4147 //================================================================================
4149 * \brief Create a group of elements preventing computation of a sub-shape
4151 //================================================================================
4153 SMESH::ListOfGroups*
4154 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4155 const char* theGroupName )
4156 throw ( SALOME::SALOME_Exception )
4158 Unexpect aCatch(SALOME_SalomeException);
4160 if ( !theGroupName || strlen( theGroupName) == 0 )
4161 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4163 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4165 // submesh by subshape id
4166 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4167 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4170 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4171 if ( error && !error->myBadElements.empty())
4173 // sort bad elements by type
4174 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4175 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4176 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4177 for ( ; elemIt != elemEnd; ++elemIt )
4179 const SMDS_MeshElement* elem = *elemIt;
4180 if ( !elem ) continue;
4182 if ( elem->GetID() < 1 )
4184 // elem is a temporary element, make a real element
4185 vector< const SMDS_MeshNode* > nodes;
4186 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4187 while ( nIt->more() && elem )
4189 nodes.push_back( nIt->next() );
4190 if ( nodes.back()->GetID() < 1 )
4191 elem = 0; // a temporary element on temporary nodes
4195 ::SMESH_MeshEditor editor( _impl );
4196 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4200 elemsByType[ elem->GetType() ].push_back( elem );
4203 // how many groups to create?
4205 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4206 nbTypes += int( !elemsByType[ i ].empty() );
4207 groups->length( nbTypes );
4210 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4212 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4213 if ( elems.empty() ) continue;
4215 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4216 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4218 SALOMEDS::SObject_wrap aSO =
4219 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), groups[ iG ],
4220 GEOM::GEOM_Object::_nil(), theGroupName);
4221 aSO->_is_nil(); // avoid "unused variable" warning
4223 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4224 if ( !grp_i ) continue;
4226 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4227 for ( size_t iE = 0; iE < elems.size(); ++iE )
4228 grpDS->SMDSGroup().Add( elems[ iE ]);
4233 return groups._retn();
4236 //=============================================================================
4238 * Create and publish group servants if any groups were imported or created anyhow
4240 //=============================================================================
4242 void SMESH_Mesh_i::CreateGroupServants()
4244 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4247 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4248 while ( groupIt->more() )
4250 ::SMESH_Group* group = groupIt->next();
4251 int anId = group->GetGroupDS()->GetID();
4253 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4254 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4256 addedIDs.insert( anId );
4258 SMESH_GroupBase_i* aGroupImpl;
4260 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4261 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4263 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4264 shape = groupOnGeom->GetShape();
4267 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4270 SMESH::SMESH_GroupBase_var groupVar =
4271 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4272 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4274 // register CORBA object for persistence
4275 int nextId = _gen_i->RegisterObject( groupVar );
4276 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
4278 // publishing the groups in the study
4279 if ( !aStudy->_is_nil() ) {
4280 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4281 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4284 if ( !addedIDs.empty() )
4287 set<int>::iterator id = addedIDs.begin();
4288 for ( ; id != addedIDs.end(); ++id )
4290 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4291 int i = std::distance( _mapGroups.begin(), it );
4292 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4297 //=============================================================================
4299 * \brief Return groups cantained in _mapGroups by their IDs
4301 //=============================================================================
4303 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4305 int nbGroups = groupIDs.size();
4306 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4307 aList->length( nbGroups );
4309 list<int>::const_iterator ids = groupIDs.begin();
4310 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4312 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4313 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4314 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4316 aList->length( nbGroups );
4317 return aList._retn();
4320 //=============================================================================
4322 * \brief Return information about imported file
4324 //=============================================================================
4326 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4328 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4329 if ( !res.operator->() ) {
4330 res = new SALOME_MED::MedFileInfo;
4332 res->fileSize = res->major = res->minor = res->release = -1;
4337 //=============================================================================
4339 * \brief Pass names of mesh groups from study to mesh DS
4341 //=============================================================================
4343 void SMESH_Mesh_i::checkGroupNames()
4345 int nbGrp = NbGroups();
4349 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4350 if ( aStudy->_is_nil() )
4351 return; // nothing to do
4353 SMESH::ListOfGroups* grpList = 0;
4354 // avoid dump of "GetGroups"
4356 // store python dump into a local variable inside local scope
4357 SMESH::TPythonDump pDump; // do not delete this line of code
4358 grpList = GetGroups();
4361 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4362 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4365 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4366 if ( aGrpSO->_is_nil() )
4368 // correct name of the mesh group if necessary
4369 const char* guiName = aGrpSO->GetName();
4370 if ( strcmp(guiName, aGrp->GetName()) )
4371 aGrp->SetName( guiName );
4375 //=============================================================================
4377 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4379 //=============================================================================
4380 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4382 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4386 //=============================================================================
4388 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4390 //=============================================================================
4391 char* SMESH_Mesh_i::GetParameters()
4393 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4394 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4397 //=============================================================================
4399 * \brief Returns list of notebook variables used for last Mesh operation
4401 //=============================================================================
4402 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4404 SMESH::string_array_var aResult = new SMESH::string_array();
4405 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4407 char *aParameters = GetParameters();
4408 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4409 if(!aStudy->_is_nil()) {
4410 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4411 if(aSections->length() > 0) {
4412 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4413 aResult->length(aVars.length());
4414 for(int i = 0;i < aVars.length();i++)
4415 aResult[i] = CORBA::string_dup( aVars[i]);
4419 return aResult._retn();
4422 //=======================================================================
4423 //function : GetTypes
4424 //purpose : Returns types of elements it contains
4425 //=======================================================================
4427 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4430 return _preMeshInfo->GetTypes();
4432 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4436 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4437 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4438 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4439 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4440 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4441 types->length( nbTypes );
4443 return types._retn();
4446 //=======================================================================
4447 //function : GetMesh
4448 //purpose : Returns self
4449 //=======================================================================
4451 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4453 return SMESH::SMESH_Mesh::_duplicate( _this() );
4456 //=======================================================================
4457 //function : IsMeshInfoCorrect
4458 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4459 // * happen if mesh data is not yet fully loaded from the file of study.
4460 //=======================================================================
4462 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4464 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4467 //=============================================================================
4469 * \brief Returns statistic of mesh elements
4471 //=============================================================================
4473 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4476 return _preMeshInfo->GetMeshInfo();
4478 SMESH::long_array_var aRes = new SMESH::long_array();
4479 aRes->length(SMESH::Entity_Last);
4480 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4482 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4484 return aRes._retn();
4485 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4486 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4487 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4488 return aRes._retn();
4491 //=============================================================================
4493 * \brief Collect statistic of mesh elements given by iterator
4495 //=============================================================================
4497 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4498 SMESH::long_array& theInfo)
4500 if (!theItr) return;
4501 while (theItr->more())
4502 theInfo[ theItr->next()->GetEntityType() ]++;
4505 //=============================================================================
4506 namespace // Finding concurrent hypotheses
4507 //=============================================================================
4511 * \brief mapping of mesh dimension into shape type
4513 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4515 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4517 case 0: aType = TopAbs_VERTEX; break;
4518 case 1: aType = TopAbs_EDGE; break;
4519 case 2: aType = TopAbs_FACE; break;
4521 default:aType = TopAbs_SOLID; break;
4526 //-----------------------------------------------------------------------------
4528 * \brief Internal structure used to find concurent submeshes
4530 * It represents a pair < submesh, concurent dimension >, where
4531 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4532 * with another submesh. In other words, it is dimension of a hypothesis assigned
4539 int _dim; //!< a dimension the algo can build (concurrent dimension)
4540 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4541 TopTools_MapOfShape _shapeMap;
4542 SMESH_subMesh* _subMesh;
4543 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4545 //-----------------------------------------------------------------------------
4546 // Return the algorithm
4547 const SMESH_Algo* GetAlgo() const
4548 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4550 //-----------------------------------------------------------------------------
4552 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4554 const TopoDS_Shape& theShape)
4556 _subMesh = (SMESH_subMesh*)theSubMesh;
4557 SetShape( theDim, theShape );
4560 //-----------------------------------------------------------------------------
4562 void SetShape(const int theDim,
4563 const TopoDS_Shape& theShape)
4566 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4567 if (_dim >= _ownDim)
4568 _shapeMap.Add( theShape );
4570 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4571 for( ; anExp.More(); anExp.Next() )
4572 _shapeMap.Add( anExp.Current() );
4576 //-----------------------------------------------------------------------------
4577 //! Check sharing of sub-shapes
4578 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4579 const TopTools_MapOfShape& theToFind,
4580 const TopAbs_ShapeEnum theType)
4582 bool isShared = false;
4583 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4584 for (; !isShared && anItr.More(); anItr.Next() )
4586 const TopoDS_Shape aSubSh = anItr.Key();
4587 // check for case when concurrent dimensions are same
4588 isShared = theToFind.Contains( aSubSh );
4589 // check for sub-shape with concurrent dimension
4590 TopExp_Explorer anExp( aSubSh, theType );
4591 for ( ; !isShared && anExp.More(); anExp.Next() )
4592 isShared = theToFind.Contains( anExp.Current() );
4597 //-----------------------------------------------------------------------------
4598 //! check algorithms
4599 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4600 const SMESHDS_Hypothesis* theA2)
4602 if ( !theA1 || !theA2 ||
4603 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4604 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4605 return false; // one of the hypothesis is not algorithm
4606 // check algorithm names (should be equal)
4607 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4611 //-----------------------------------------------------------------------------
4612 //! Check if sub-shape hypotheses are concurrent
4613 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4615 if ( _subMesh == theOther->_subMesh )
4616 return false; // same sub-shape - should not be
4618 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4619 // any of the two submeshes is not on COMPOUND shape )
4620 // -> no concurrency
4621 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4622 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4623 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4624 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4625 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4628 // bool checkSubShape = ( _dim >= theOther->_dim )
4629 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4630 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4631 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4632 if ( !checkSubShape )
4635 // check algorithms to be same
4636 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4637 return true; // different algorithms -> concurrency !
4639 // check hypothesises for concurrence (skip first as algorithm)
4641 // pointers should be same, because it is referened from mesh hypothesis partition
4642 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4643 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4644 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4645 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4647 // the submeshes are concurrent if their algorithms has different parameters
4648 return nbSame != theOther->_hypotheses.size() - 1;
4651 // Return true if algorithm of this SMESH_DimHyp is used if no
4652 // sub-mesh order is imposed by the user
4653 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4655 // NeedDiscreteBoundary() algo has a higher priority
4656 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4657 theOther->GetAlgo()->NeedDiscreteBoundary() )
4658 return !this->GetAlgo()->NeedDiscreteBoundary();
4660 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4663 }; // end of SMESH_DimHyp
4664 //-----------------------------------------------------------------------------
4666 typedef list<const SMESH_DimHyp*> TDimHypList;
4668 //-----------------------------------------------------------------------------
4670 void addDimHypInstance(const int theDim,
4671 const TopoDS_Shape& theShape,
4672 const SMESH_Algo* theAlgo,
4673 const SMESH_subMesh* theSubMesh,
4674 const list <const SMESHDS_Hypothesis*>& theHypList,
4675 TDimHypList* theDimHypListArr )
4677 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4678 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4679 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4680 dimHyp->_hypotheses.push_front(theAlgo);
4681 listOfdimHyp.push_back( dimHyp );
4684 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4685 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4686 theHypList.begin(), theHypList.end() );
4689 //-----------------------------------------------------------------------------
4690 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4691 TDimHypList& theListOfConcurr)
4693 if ( theListOfConcurr.empty() )
4695 theListOfConcurr.push_back( theDimHyp );
4699 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4700 while ( hypIt != theListOfConcurr.end() &&
4701 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4703 theListOfConcurr.insert( hypIt, theDimHyp );
4707 //-----------------------------------------------------------------------------
4708 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4709 const TDimHypList& theListOfDimHyp,
4710 TDimHypList& theListOfConcurrHyp,
4711 set<int>& theSetOfConcurrId )
4713 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4714 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4716 const SMESH_DimHyp* curDimHyp = *rIt;
4717 if ( curDimHyp == theDimHyp )
4718 break; // meet own dimHyp pointer in same dimension
4720 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4721 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4723 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4728 //-----------------------------------------------------------------------------
4729 void unionLists(TListOfInt& theListOfId,
4730 TListOfListOfInt& theListOfListOfId,
4733 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4734 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4736 continue; //skip already treated lists
4737 // check if other list has any same submesh object
4738 TListOfInt& otherListOfId = *it;
4739 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4740 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4743 // union two lists (from source into target)
4744 TListOfInt::iterator it2 = otherListOfId.begin();
4745 for ( ; it2 != otherListOfId.end(); it2++ ) {
4746 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4747 theListOfId.push_back(*it2);
4749 // clear source list
4750 otherListOfId.clear();
4753 //-----------------------------------------------------------------------------
4755 //! free memory allocated for dimension-hypothesis objects
4756 void removeDimHyps( TDimHypList* theArrOfList )
4758 for (int i = 0; i < 4; i++ ) {
4759 TDimHypList& listOfdimHyp = theArrOfList[i];
4760 TDimHypList::const_iterator it = listOfdimHyp.begin();
4761 for ( ; it != listOfdimHyp.end(); it++ )
4766 //-----------------------------------------------------------------------------
4768 * \brief find common submeshes with given submesh
4769 * \param theSubMeshList list of already collected submesh to check
4770 * \param theSubMesh given submesh to intersect with other
4771 * \param theCommonSubMeshes collected common submeshes
4773 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4774 const SMESH_subMesh* theSubMesh,
4775 set<const SMESH_subMesh*>& theCommon )
4779 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4780 for ( ; it != theSubMeshList.end(); it++ )
4781 theSubMesh->FindIntersection( *it, theCommon );
4782 theSubMeshList.push_back( theSubMesh );
4783 //theCommon.insert( theSubMesh );
4788 //=============================================================================
4790 * \brief Return submesh objects list in meshing order
4792 //=============================================================================
4794 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4796 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4798 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4800 return aResult._retn();
4802 ::SMESH_Mesh& mesh = GetImpl();
4803 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4804 if ( !anOrder.size() ) {
4806 // collect submeshes and detect concurrent algorithms and hypothesises
4807 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4809 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4810 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4811 ::SMESH_subMesh* sm = (*i_sm).second;
4813 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4815 // list of assigned hypothesises
4816 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4817 // Find out dimensions where the submesh can be concurrent.
4818 // We define the dimensions by algo of each of hypotheses in hypList
4819 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4820 for( ; hypIt != hypList.end(); hypIt++ ) {
4821 SMESH_Algo* anAlgo = 0;
4822 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4823 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4824 // hyp it-self is algo
4825 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4827 // try to find algorithm with help of sub-shapes
4828 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4829 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4830 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4833 continue; // no algorithm assigned to a current submesh
4835 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4836 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4838 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4839 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4840 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4842 } // end iterations on submesh
4844 // iterate on created dimension-hypotheses and check for concurrents
4845 for ( int i = 0; i < 4; i++ ) {
4846 const TDimHypList& listOfDimHyp = dimHypListArr[i];
4847 // check for concurrents in own and other dimensions (step-by-step)
4848 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4849 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4850 const SMESH_DimHyp* dimHyp = *dhIt;
4851 TDimHypList listOfConcurr;
4852 set<int> setOfConcurrIds;
4853 // looking for concurrents and collect into own list
4854 for ( int j = i; j < 4; j++ )
4855 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
4856 // check if any concurrents found
4857 if ( listOfConcurr.size() > 0 ) {
4858 // add own submesh to list of concurrent
4859 addInOrderOfPriority( dimHyp, listOfConcurr );
4860 list<int> listOfConcurrIds;
4861 TDimHypList::iterator hypIt = listOfConcurr.begin();
4862 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
4863 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
4864 anOrder.push_back( listOfConcurrIds );
4869 removeDimHyps(dimHypListArr);
4871 // now, minimise the number of concurrent groups
4872 // Here we assume that lists of submeshes can have same submesh
4873 // in case of multi-dimension algorithms, as result
4874 // list with common submesh has to be united into one list
4876 TListOfListOfInt::iterator listIt = anOrder.begin();
4877 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4878 unionLists( *listIt, anOrder, listIndx + 1 );
4880 // convert submesh ids into interface instances
4881 // and dump command into python
4882 convertMeshOrder( anOrder, aResult, false );
4884 return aResult._retn();
4887 //=============================================================================
4889 * \brief Set submesh object order
4890 * \param theSubMeshArray submesh array order
4892 //=============================================================================
4894 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4897 _preMeshInfo->ForgetOrLoad();
4900 ::SMESH_Mesh& mesh = GetImpl();
4902 TPythonDump aPythonDump; // prevent dump of called methods
4903 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4905 TListOfListOfInt subMeshOrder;
4906 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4908 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4909 TListOfInt subMeshIds;
4910 aPythonDump << "[ ";
4911 // Collect subMeshes which should be clear
4912 // do it list-by-list, because modification of submesh order
4913 // take effect between concurrent submeshes only
4914 set<const SMESH_subMesh*> subMeshToClear;
4915 list<const SMESH_subMesh*> subMeshList;
4916 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4918 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4920 aPythonDump << ", ";
4921 aPythonDump << subMesh;
4922 subMeshIds.push_back( subMesh->GetId() );
4923 // detect common parts of submeshes
4924 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4925 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4927 aPythonDump << " ]";
4928 subMeshOrder.push_back( subMeshIds );
4930 // clear collected submeshes
4931 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4932 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
4933 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
4934 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4936 aPythonDump << " ])";
4938 mesh.SetMeshOrder( subMeshOrder );
4944 //=============================================================================
4946 * \brief Convert submesh ids into submesh interfaces
4948 //=============================================================================
4950 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4951 SMESH::submesh_array_array& theResOrder,
4952 const bool theIsDump)
4954 int nbSet = theIdsOrder.size();
4955 TPythonDump aPythonDump; // prevent dump of called methods
4957 aPythonDump << "[ ";
4958 theResOrder.length(nbSet);
4959 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4961 for( ; it != theIdsOrder.end(); it++ ) {
4962 // translate submesh identificators into submesh objects
4963 // takeing into account real number of concurrent lists
4964 const TListOfInt& aSubOrder = (*it);
4965 if (!aSubOrder.size())
4968 aPythonDump << "[ ";
4969 // convert shape indeces into interfaces
4970 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4971 aResSubSet->length(aSubOrder.size());
4972 TListOfInt::const_iterator subIt = aSubOrder.begin();
4973 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4974 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4976 SMESH::SMESH_subMesh_var subMesh =
4977 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4980 aPythonDump << ", ";
4981 aPythonDump << subMesh;
4983 aResSubSet[ j++ ] = subMesh;
4986 aPythonDump << " ]";
4987 theResOrder[ listIndx++ ] = aResSubSet;
4989 // correct number of lists
4990 theResOrder.length( listIndx );
4993 // finilise python dump
4994 aPythonDump << " ]";
4995 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4999 //================================================================================
5001 // Implementation of SMESH_MeshPartDS
5003 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5004 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5006 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5007 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5009 _meshDS = mesh_i->GetImpl().GetMeshDS();
5011 SetPersistentId( _meshDS->GetPersistentId() );
5013 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5015 // <meshPart> is the whole mesh
5016 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5018 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5019 myGroupSet = _meshDS->GetGroups();
5024 SMESH::long_array_var anIDs = meshPart->GetIDs();
5025 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5026 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5028 for (int i=0; i < anIDs->length(); i++)
5029 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5030 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5035 for (int i=0; i < anIDs->length(); i++)
5036 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5037 if ( _elements[ e->GetType() ].insert( e ).second )
5040 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5041 while ( nIt->more() )
5043 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5044 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5051 _meshDS = 0; // to enforce iteration on _elements and _nodes
5054 // -------------------------------------------------------------------------------------
5055 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5056 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5059 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5060 for ( ; partIt != meshPart.end(); ++partIt )
5061 if ( const SMDS_MeshElement * e = *partIt )
5062 if ( _elements[ e->GetType() ].insert( e ).second )
5065 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5066 while ( nIt->more() )
5068 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5069 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5075 // -------------------------------------------------------------------------------------
5076 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5078 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5080 typedef SMDS_SetIterator
5081 <const SMDS_MeshElement*,
5082 TIDSortedElemSet::const_iterator,
5083 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5084 SMDS_MeshElement::GeomFilter
5087 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5089 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5090 _elements[type].end(),
5091 SMDS_MeshElement::GeomFilter( geomType )));
5093 // -------------------------------------------------------------------------------------
5094 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5096 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5098 typedef SMDS_SetIterator
5099 <const SMDS_MeshElement*,
5100 TIDSortedElemSet::const_iterator,
5101 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5102 SMDS_MeshElement::EntityFilter
5105 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5107 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5108 _elements[type].end(),
5109 SMDS_MeshElement::EntityFilter( entity )));
5111 // -------------------------------------------------------------------------------------
5112 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5114 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5115 if ( type == SMDSAbs_All && !_meshDS )
5117 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5119 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5120 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5122 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5124 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5125 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5127 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5128 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5130 // -------------------------------------------------------------------------------------
5131 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5132 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5134 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5135 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5136 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5138 // -------------------------------------------------------------------------------------
5139 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5140 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5141 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5142 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5143 #undef _GET_ITER_DEFINE
5145 // END Implementation of SMESH_MeshPartDS
5147 //================================================================================