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() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1113 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);
1132 // Update Python script
1133 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1134 aPythonDump << " ] = " << _this() << ".GetGroups()";
1136 return aList._retn();
1139 //=============================================================================
1141 * Get number of groups existing in the mesh
1143 //=============================================================================
1145 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1147 Unexpect aCatch(SALOME_SalomeException);
1148 return _mapGroups.size();
1151 //=============================================================================
1153 * New group is created. All mesh elements that are
1154 * present in initial groups are added to the new one
1156 //=============================================================================
1157 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1158 SMESH::SMESH_GroupBase_ptr theGroup2,
1159 const char* theName )
1160 throw (SALOME::SALOME_Exception)
1162 SMESH::SMESH_Group_var aResGrp;
1166 _preMeshInfo->FullLoadFromFile();
1168 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1169 theGroup1->GetType() != theGroup2->GetType() )
1170 return SMESH::SMESH_Group::_nil();
1175 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1176 if ( aResGrp->_is_nil() )
1177 return SMESH::SMESH_Group::_nil();
1179 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1180 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1182 TColStd_MapOfInteger aResMap;
1184 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1185 aResMap.Add( anIds1[ i1 ] );
1187 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1188 aResMap.Add( anIds2[ i2 ] );
1190 SMESH::long_array_var aResIds = new SMESH::long_array;
1191 aResIds->length( aResMap.Extent() );
1194 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1195 for( ; anIter.More(); anIter.Next() )
1196 aResIds[ resI++ ] = anIter.Key();
1198 aResGrp->Add( aResIds );
1200 // Update Python script
1201 pyDump << aResGrp << " = " << _this() << ".UnionGroups( "
1202 << theGroup1 << ", " << theGroup2 << ", '"
1203 << theName << "' )";
1205 SMESH_CATCH( SMESH::throwCorbaException );
1207 return aResGrp._retn();
1210 //=============================================================================
1212 \brief Union list of groups. New group is created. All mesh elements that are
1213 present in initial groups are added to the new one.
1214 \param theGroups list of groups
1215 \param theName name of group to be created
1216 \return pointer on the group
1218 //=============================================================================
1219 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1220 const char* theName )
1221 throw (SALOME::SALOME_Exception)
1224 _preMeshInfo->FullLoadFromFile();
1227 return SMESH::SMESH_Group::_nil();
1229 SMESH::SMESH_Group_var aResGrp;
1233 vector< int > anIds;
1234 SMESH::ElementType aType = SMESH::ALL;
1235 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1237 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1238 if ( CORBA::is_nil( aGrp ) )
1242 SMESH::ElementType aCurrType = aGrp->GetType();
1243 if ( aType == SMESH::ALL )
1247 if ( aType != aCurrType )
1248 return SMESH::SMESH_Group::_nil();
1252 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1253 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1255 int aCurrId = aCurrIds[ i ];
1256 anIds.push_back( aCurrId );
1263 aResGrp = CreateGroup( aType, theName );
1264 if ( aResGrp->_is_nil() )
1265 return SMESH::SMESH_Group::_nil();
1267 // Create array of identifiers
1268 SMESH::long_array_var aResIds = new SMESH::long_array;
1269 aResIds->length( anIds.size() );
1271 for ( size_t i = 0; i<anIds.size(); i++ )
1272 aResIds[ i ] = anIds[i];
1273 aResGrp->Add( aResIds );
1275 // Update Python script
1276 pyDump << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1277 << &theGroups << ", '" << theName << "' )";
1279 SMESH_CATCH( SMESH::throwCorbaException );
1281 return aResGrp._retn();
1284 //=============================================================================
1286 * New group is created. All mesh elements that are
1287 * present in both initial groups are added to the new one.
1289 //=============================================================================
1290 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1291 SMESH::SMESH_GroupBase_ptr theGroup2,
1292 const char* theName )
1293 throw (SALOME::SALOME_Exception)
1295 SMESH::SMESH_Group_var aResGrp;
1299 _preMeshInfo->FullLoadFromFile();
1301 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1302 theGroup1->GetType() != theGroup2->GetType() )
1303 return SMESH::SMESH_Group::_nil();
1307 // Create Intersection
1308 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1309 if ( aResGrp->_is_nil() )
1312 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1313 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1315 TColStd_MapOfInteger aMap1;
1317 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1318 aMap1.Add( anIds1[ i1 ] );
1320 TColStd_SequenceOfInteger aSeq;
1321 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1322 if ( aMap1.Contains( anIds2[ i2 ] ) )
1323 aSeq.Append( anIds2[ i2 ] );
1325 SMESH::long_array_var aResIds = new SMESH::long_array;
1326 aResIds->length( aSeq.Length() );
1327 for ( size_t resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1328 aResIds[ resI ] = aSeq( resI + 1 );
1329 aResGrp->Add( aResIds );
1331 // Update Python script
1332 pyDump << aResGrp << " = " << _this() << ".IntersectGroups( "
1333 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1335 SMESH_CATCH( SMESH::throwCorbaException );
1337 return aResGrp._retn();
1340 //=============================================================================
1342 \brief Intersect list of groups. New group is created. All mesh elements that
1343 are present in all initial groups simultaneously are added to the new one.
1344 \param theGroups list of groups
1345 \param theName name of group to be created
1346 \return pointer on the group
1348 //=============================================================================
1349 SMESH::SMESH_Group_ptr
1350 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1351 const char* theName )
1352 throw (SALOME::SALOME_Exception)
1354 SMESH::SMESH_Group_var aResGrp;
1358 _preMeshInfo->FullLoadFromFile();
1361 return SMESH::SMESH_Group::_nil();
1363 NCollection_DataMap< int, int > anIdToCount;
1364 SMESH::ElementType aType = SMESH::ALL;
1365 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1367 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1368 if ( CORBA::is_nil( aGrp ) )
1372 SMESH::ElementType aCurrType = aGrp->GetType();
1373 if ( aType == SMESH::ALL )
1377 if ( aType != aCurrType )
1378 return SMESH::SMESH_Group::_nil();
1381 // calculates number of occurance ids in groups
1382 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1383 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1385 int aCurrId = aCurrIds[ i ];
1386 if ( !anIdToCount.IsBound( aCurrId ) )
1387 anIdToCount.Bind( aCurrId, 1 );
1389 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1393 // create map of ids
1394 int nbGrp = theGroups.length();
1395 vector< int > anIds;
1396 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1397 for ( ; anIter.More(); anIter.Next() )
1399 int aCurrId = anIter.Key();
1400 int aCurrNb = anIter.Value();
1401 if ( aCurrNb == nbGrp )
1402 anIds.push_back( aCurrId );
1408 aResGrp = CreateGroup( aType, theName );
1409 if ( aResGrp->_is_nil() )
1410 return SMESH::SMESH_Group::_nil();
1412 // Create array of identifiers
1413 SMESH::long_array_var aResIds = new SMESH::long_array;
1414 aResIds->length( anIds.size() );
1416 for ( size_t i = 0; i<anIds.size(); i++ )
1417 aResIds[ i ] = anIds[i];
1418 aResGrp->Add( aResIds );
1420 // Update Python script
1421 pyDump << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1422 << &theGroups << ", '" << theName << "' )";
1424 SMESH_CATCH( SMESH::throwCorbaException );
1426 return aResGrp._retn();
1429 //=============================================================================
1431 * New group is created. All mesh elements that are present in
1432 * main group but do not present in tool group are added to the new one
1434 //=============================================================================
1435 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1436 SMESH::SMESH_GroupBase_ptr theGroup2,
1437 const char* theName )
1438 throw (SALOME::SALOME_Exception)
1440 SMESH::SMESH_Group_var aResGrp;
1444 _preMeshInfo->FullLoadFromFile();
1446 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1447 theGroup1->GetType() != theGroup2->GetType() )
1448 return SMESH::SMESH_Group::_nil();
1453 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1454 if ( aResGrp->_is_nil() )
1457 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1458 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1460 TColStd_MapOfInteger aMap2;
1462 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1463 aMap2.Add( anIds2[ i2 ] );
1465 TColStd_SequenceOfInteger aSeq;
1466 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1467 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1468 aSeq.Append( anIds1[ i1 ] );
1470 SMESH::long_array_var aResIds = new SMESH::long_array;
1471 aResIds->length( aSeq.Length() );
1473 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1474 aResIds[ resI ] = aSeq( resI + 1 );
1475 aResGrp->Add( aResIds );
1477 // Update Python script
1478 pyDump << aResGrp << " = " << _this() << ".CutGroups( "
1479 << theGroup1 << ", " << theGroup2 << ", '"
1480 << theName << "' )";
1482 SMESH_CATCH( SMESH::throwCorbaException );
1484 return aResGrp._retn();
1487 //=============================================================================
1489 \brief Cut lists of groups. New group is created. All mesh elements that are
1490 present in main groups but do not present in tool groups are added to the new one
1491 \param theMainGroups list of main groups
1492 \param theToolGroups list of tool groups
1493 \param theName name of group to be created
1494 \return pointer on the group
1496 //=============================================================================
1497 SMESH::SMESH_Group_ptr
1498 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1499 const SMESH::ListOfGroups& theToolGroups,
1500 const char* theName )
1501 throw (SALOME::SALOME_Exception)
1503 SMESH::SMESH_Group_var aResGrp;
1507 _preMeshInfo->FullLoadFromFile();
1510 return SMESH::SMESH_Group::_nil();
1512 set< int > aToolIds;
1513 SMESH::ElementType aType = SMESH::ALL;
1515 // iterate through tool groups
1516 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1518 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1519 if ( CORBA::is_nil( aGrp ) )
1523 SMESH::ElementType aCurrType = aGrp->GetType();
1524 if ( aType == SMESH::ALL )
1528 if ( aType != aCurrType )
1529 return SMESH::SMESH_Group::_nil();
1533 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1534 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1536 int aCurrId = aCurrIds[ i ];
1537 aToolIds.insert( aCurrId );
1541 vector< int > anIds; // result
1543 // Iterate through main group
1544 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1546 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1547 if ( CORBA::is_nil( aGrp ) )
1551 SMESH::ElementType aCurrType = aGrp->GetType();
1552 if ( aType == SMESH::ALL )
1556 if ( aType != aCurrType )
1557 return SMESH::SMESH_Group::_nil();
1561 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1562 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1564 int aCurrId = aCurrIds[ i ];
1565 if ( !aToolIds.count( aCurrId ) )
1566 anIds.push_back( aCurrId );
1573 aResGrp = CreateGroup( aType, theName );
1574 if ( aResGrp->_is_nil() )
1575 return SMESH::SMESH_Group::_nil();
1577 // Create array of identifiers
1578 SMESH::long_array_var aResIds = new SMESH::long_array;
1579 aResIds->length( anIds.size() );
1581 for (int i=0; i<anIds.size(); i++ )
1582 aResIds[ i ] = anIds[i];
1583 aResGrp->Add( aResIds );
1585 // Update Python script
1586 pyDump << aResGrp << " = " << _this() << ".CutListOfGroups( "
1587 << &theMainGroups << ", " << &theToolGroups << ", '"
1588 << theName << "' )";
1590 SMESH_CATCH( SMESH::throwCorbaException );
1592 return aResGrp._retn();
1595 //=============================================================================
1597 \brief Create groups of entities from existing groups of superior dimensions
1599 1) extract all nodes from each group,
1600 2) combine all elements of specified dimension laying on these nodes.
1601 \param theGroups list of source groups
1602 \param theElemType dimension of elements
1603 \param theName name of new group
1604 \return pointer on new group
1608 //=============================================================================
1610 SMESH::SMESH_Group_ptr
1611 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1612 SMESH::ElementType theElemType,
1613 const char* theName )
1614 throw (SALOME::SALOME_Exception)
1616 SMESH::SMESH_Group_var aResGrp;
1620 _preMeshInfo->FullLoadFromFile();
1622 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1624 if ( !theName || !aMeshDS )
1625 return SMESH::SMESH_Group::_nil();
1627 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1633 aResGrp = CreateGroup( theElemType, theName );
1634 if ( aResGrp->_is_nil() )
1635 return SMESH::SMESH_Group::_nil();
1637 SMESHDS_GroupBase* groupBaseDS =
1638 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1639 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1641 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1643 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1644 if ( CORBA::is_nil( aGrp ) )
1647 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1648 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1650 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1652 while ( elIt->more() ) {
1653 const SMDS_MeshElement* el = elIt->next();
1654 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1655 while ( nIt->more() )
1656 resGroupCore.Add( nIt->next() );
1659 else // get elements of theElemType based on nodes of every element of group
1661 while ( elIt->more() )
1663 const SMDS_MeshElement* el = elIt->next(); // an element of group
1664 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1665 TIDSortedElemSet checkedElems;
1666 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1667 while ( nIt->more() )
1669 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1670 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1671 // check nodes of elements of theElemType around el
1672 while ( elOfTypeIt->more() )
1674 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1675 if ( !checkedElems.insert( elOfType ).second ) continue;
1677 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1678 bool allNodesOK = true;
1679 while ( nIt2->more() && allNodesOK )
1680 allNodesOK = elNodes.count( nIt2->next() );
1682 resGroupCore.Add( elOfType );
1689 // Update Python script
1690 pyDump << aResGrp << " = " << _this() << ".CreateDimGroup( "
1691 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1693 SMESH_CATCH( SMESH::throwCorbaException );
1695 return aResGrp._retn();
1698 //================================================================================
1700 * \brief Remember GEOM group data
1702 //================================================================================
1704 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1705 CORBA::Object_ptr theSmeshObj)
1707 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1710 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1711 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1712 if ( groupSO->_is_nil() )
1715 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1716 GEOM::GEOM_IGroupOperations_wrap groupOp =
1717 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1718 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1721 _geomGroupData.push_back( TGeomGroupData() );
1722 TGeomGroupData & groupData = _geomGroupData.back();
1724 CORBA::String_var entry = groupSO->GetID();
1725 groupData._groupEntry = entry.in();
1727 for ( int i = 0; i < ids->length(); ++i )
1728 groupData._indices.insert( ids[i] );
1730 groupData._smeshObject = theSmeshObj;
1733 //================================================================================
1735 * Remove GEOM group data relating to removed smesh object
1737 //================================================================================
1739 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1741 list<TGeomGroupData>::iterator
1742 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1743 for ( ; data != dataEnd; ++data ) {
1744 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1745 _geomGroupData.erase( data );
1751 //================================================================================
1753 * \brief Return new group contents if it has been changed and update group data
1755 //================================================================================
1757 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1759 TopoDS_Shape newShape;
1762 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1763 if ( study->_is_nil() ) return newShape; // means "not changed"
1764 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1765 if ( !groupSO->_is_nil() )
1767 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1768 if ( CORBA::is_nil( groupObj )) return newShape;
1769 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1771 // get indices of group items
1772 set<int> curIndices;
1773 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1774 GEOM::GEOM_IGroupOperations_wrap groupOp =
1775 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1776 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1777 for ( int i = 0; i < ids->length(); ++i )
1778 curIndices.insert( ids[i] );
1780 if ( groupData._indices == curIndices )
1781 return newShape; // group not changed
1784 groupData._indices = curIndices;
1786 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1787 if ( !geomClient ) return newShape;
1788 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1789 geomClient->RemoveShapeFromBuffer( groupIOR );
1790 newShape = _gen_i->GeomObjectToShape( geomGroup );
1793 if ( newShape.IsNull() ) {
1794 // geom group becomes empty - return empty compound
1795 TopoDS_Compound compound;
1796 BRep_Builder().MakeCompound(compound);
1797 newShape = compound;
1804 //=============================================================================
1806 * \brief Storage of shape and index used in CheckGeomGroupModif()
1808 //=============================================================================
1809 struct TIndexedShape
1812 TopoDS_Shape _shape;
1813 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1816 //=============================================================================
1818 * \brief Update objects depending on changed geom groups
1820 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1821 * issue 0020210: Update of a smesh group after modification of the associated geom group
1823 //=============================================================================
1825 void SMESH_Mesh_i::CheckGeomGroupModif()
1827 if ( !_impl->HasShapeToMesh() ) return;
1829 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1830 if ( study->_is_nil() ) return;
1832 CORBA::Long nbEntities = NbNodes() + NbElements();
1834 // Check if group contents changed
1836 typedef map< string, TopoDS_Shape > TEntry2Geom;
1837 TEntry2Geom newGroupContents;
1839 list<TGeomGroupData>::iterator
1840 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1841 for ( ; data != dataEnd; ++data )
1843 pair< TEntry2Geom::iterator, bool > it_new =
1844 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1845 bool processedGroup = !it_new.second;
1846 TopoDS_Shape& newShape = it_new.first->second;
1847 if ( !processedGroup )
1848 newShape = newGroupShape( *data );
1849 if ( newShape.IsNull() )
1850 continue; // no changes
1853 _preMeshInfo->ForgetOrLoad();
1855 if ( processedGroup ) { // update group indices
1856 list<TGeomGroupData>::iterator data2 = data;
1857 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1858 data->_indices = data2->_indices;
1861 // Update SMESH objects according to new GEOM group contents
1863 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1864 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1866 int oldID = submesh->GetId();
1867 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1869 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1871 // update hypotheses
1872 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1873 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1874 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1876 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1877 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1879 // care of submeshes
1880 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1881 int newID = newSubmesh->GetId();
1882 if ( newID != oldID ) {
1883 _mapSubMesh [ newID ] = newSubmesh;
1884 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1885 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1886 _mapSubMesh. erase(oldID);
1887 _mapSubMesh_i. erase(oldID);
1888 _mapSubMeshIor.erase(oldID);
1889 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1894 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1895 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1896 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1898 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1900 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1901 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1902 ds->SetShape( newShape );
1907 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1908 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1910 // Remove groups and submeshes basing on removed sub-shapes
1912 TopTools_MapOfShape newShapeMap;
1913 TopoDS_Iterator shapeIt( newShape );
1914 for ( ; shapeIt.More(); shapeIt.Next() )
1915 newShapeMap.Add( shapeIt.Value() );
1917 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1918 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1920 if ( newShapeMap.Contains( shapeIt.Value() ))
1922 TopTools_IndexedMapOfShape oldShapeMap;
1923 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1924 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1926 const TopoDS_Shape& oldShape = oldShapeMap(i);
1927 int oldInd = meshDS->ShapeToIndex( oldShape );
1929 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1930 if ( i_smIor != _mapSubMeshIor.end() ) {
1931 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1934 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1935 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1937 // check if a group bases on oldInd shape
1938 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1939 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1940 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1941 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1943 RemoveGroup( i_grp->second ); // several groups can base on same shape
1944 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1949 // Reassign hypotheses and update groups after setting the new shape to mesh
1951 // collect anassigned hypotheses
1952 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1953 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1954 TShapeHypList assignedHyps;
1955 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1957 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1958 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1959 if ( !hyps.empty() ) {
1960 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1961 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1962 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1965 // collect shapes supporting groups
1966 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1967 TShapeTypeList groupData;
1968 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1969 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1970 for ( ; grIt != groups.end(); ++grIt )
1972 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1974 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1976 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1977 _impl->ShapeToMesh( newShape );
1979 // reassign hypotheses
1980 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1981 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1983 TIndexedShape& geom = indS_hyps->first;
1984 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1985 int oldID = geom._index;
1986 int newID = meshDS->ShapeToIndex( geom._shape );
1987 if ( oldID == 1 ) { // main shape
1989 geom._shape = newShape;
1993 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1994 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1995 // care of submeshes
1996 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1997 if ( newID != oldID ) {
1998 _mapSubMesh [ newID ] = newSubmesh;
1999 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2000 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2001 _mapSubMesh. erase(oldID);
2002 _mapSubMesh_i. erase(oldID);
2003 _mapSubMeshIor.erase(oldID);
2004 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2008 TShapeTypeList::iterator geomType = groupData.begin();
2009 for ( ; geomType != groupData.end(); ++geomType )
2011 const TIndexedShape& geom = geomType->first;
2012 int oldID = geom._index;
2013 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2016 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2017 CORBA::String_var name = groupSO->GetName();
2019 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2021 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2022 group_i->changeLocalId( newID );
2025 break; // everything has been updated
2028 } // loop on group data
2032 CORBA::Long newNbEntities = NbNodes() + NbElements();
2033 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2034 if ( newNbEntities != nbEntities )
2036 // Add all SObjects with icons to soToUpdateIcons
2037 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2039 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2040 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2041 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2043 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2044 i_gr != _mapGroups.end(); ++i_gr ) // groups
2045 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2048 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2049 for ( ; so != soToUpdateIcons.end(); ++so )
2050 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2053 //=============================================================================
2055 * \brief Create standalone group from a group on geometry or filter
2057 //=============================================================================
2059 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2060 throw (SALOME::SALOME_Exception)
2062 SMESH::SMESH_Group_var aGroup;
2067 _preMeshInfo->FullLoadFromFile();
2069 if ( theGroup->_is_nil() )
2070 return aGroup._retn();
2072 SMESH_GroupBase_i* aGroupToRem =
2073 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2075 return aGroup._retn();
2077 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2079 int anId = aGroupToRem->GetLocalID();
2080 if ( !_impl->ConvertToStandalone( anId ) )
2081 return aGroup._retn();
2082 removeGeomGroupData( theGroup );
2084 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2086 // remove old instance of group from own map
2087 _mapGroups.erase( anId );
2089 SALOMEDS::StudyBuilder_var builder;
2090 SALOMEDS::SObject_wrap aGroupSO;
2091 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2092 if ( !aStudy->_is_nil() ) {
2093 builder = aStudy->NewBuilder();
2094 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2095 if ( !aGroupSO->_is_nil() )
2097 // remove reference to geometry
2098 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2099 for ( ; chItr->More(); chItr->Next() )
2100 // Remove group's child SObject
2101 builder->RemoveObject( chItr->Value() );
2103 // Update Python script
2104 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2105 << aGroupSO << " )";
2107 // change icon of Group on Filter
2110 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2111 const int isEmpty = ( elemTypes->length() == 0 );
2114 SALOMEDS::GenericAttribute_wrap anAttr =
2115 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2116 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2117 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2123 // remember new group in own map
2124 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2125 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2127 // register CORBA object for persistence
2128 _gen_i->RegisterObject( aGroup );
2130 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2131 builder->SetIOR( aGroupSO, ior.in() );
2133 SMESH_CATCH( SMESH::throwCorbaException );
2135 return aGroup._retn();
2138 //=============================================================================
2142 //=============================================================================
2144 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2146 if(MYDEBUG) MESSAGE( "createSubMesh" );
2147 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2149 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2150 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2151 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2152 SMESH::SMESH_subMesh_var subMesh
2153 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2155 _mapSubMesh[subMeshId] = mySubMesh;
2156 _mapSubMesh_i[subMeshId] = subMeshServant;
2157 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2159 // register CORBA object for persistence
2160 int nextId = _gen_i->RegisterObject( subMesh );
2161 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2163 // to track changes of GEOM groups
2164 addGeomGroupData( theSubShapeObject, subMesh );
2166 return subMesh._retn();
2169 //=======================================================================
2170 //function : getSubMesh
2172 //=======================================================================
2174 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2176 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2177 if ( it == _mapSubMeshIor.end() )
2178 return SMESH::SMESH_subMesh::_nil();
2180 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2184 //=============================================================================
2188 //=============================================================================
2190 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2191 GEOM::GEOM_Object_ptr theSubShapeObject )
2193 bool isHypChanged = false;
2194 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2195 return isHypChanged;
2197 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2199 CORBA::Long shapeId = theSubMesh->GetId();
2200 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2202 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2205 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2206 isHypChanged = !hyps.empty();
2207 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2208 for ( ; hyp != hyps.end(); ++hyp )
2209 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2216 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2217 isHypChanged = ( aHypList->length() > 0 );
2218 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2219 removeHypothesis( theSubShapeObject, aHypList[i] );
2222 catch( const SALOME::SALOME_Exception& ) {
2223 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2225 removeGeomGroupData( theSubShapeObject );
2227 int subMeshId = theSubMesh->GetId();
2229 _mapSubMesh.erase(subMeshId);
2230 _mapSubMesh_i.erase(subMeshId);
2231 _mapSubMeshIor.erase(subMeshId);
2233 return isHypChanged;
2236 //=============================================================================
2240 //=============================================================================
2242 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2243 const char* theName,
2244 const TopoDS_Shape& theShape,
2245 const SMESH_PredicatePtr& thePredicate )
2247 std::string newName;
2248 if ( !theName || strlen( theName ) == 0 )
2250 std::set< std::string > presentNames;
2251 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2252 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2253 presentNames.insert( i_gr->second->GetName() );
2255 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2256 } while ( !presentNames.insert( newName ).second );
2257 theName = newName.c_str();
2260 SMESH::SMESH_GroupBase_var aGroup;
2261 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2263 SMESH_GroupBase_i* aGroupImpl;
2264 if ( !theShape.IsNull() )
2265 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2266 else if ( thePredicate )
2267 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2269 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2271 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2272 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2274 // register CORBA object for persistence
2275 int nextId = _gen_i->RegisterObject( aGroup );
2276 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2278 // to track changes of GEOM groups
2279 if ( !theShape.IsNull() ) {
2280 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2281 addGeomGroupData( geom, aGroup );
2284 return aGroup._retn();
2287 //=============================================================================
2289 * SMESH_Mesh_i::removeGroup
2291 * Should be called by ~SMESH_Group_i()
2293 //=============================================================================
2295 void SMESH_Mesh_i::removeGroup( const int theId )
2297 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2298 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2299 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2300 _mapGroups.erase( theId );
2301 removeGeomGroupData( group );
2302 if (! _impl->RemoveGroup( theId ))
2304 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2305 RemoveGroup( group );
2310 //=============================================================================
2314 //=============================================================================
2316 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2317 throw(SALOME::SALOME_Exception)
2319 SMESH::log_array_var aLog;
2323 _preMeshInfo->FullLoadFromFile();
2325 list < SMESHDS_Command * >logDS = _impl->GetLog();
2326 aLog = new SMESH::log_array;
2328 int lg = logDS.size();
2331 list < SMESHDS_Command * >::iterator its = logDS.begin();
2332 while(its != logDS.end()){
2333 SMESHDS_Command *com = *its;
2334 int comType = com->GetType();
2336 int lgcom = com->GetNumber();
2338 const list < int >&intList = com->GetIndexes();
2339 int inum = intList.size();
2341 list < int >::const_iterator ii = intList.begin();
2342 const list < double >&coordList = com->GetCoords();
2343 int rnum = coordList.size();
2345 list < double >::const_iterator ir = coordList.begin();
2346 aLog[indexLog].commandType = comType;
2347 aLog[indexLog].number = lgcom;
2348 aLog[indexLog].coords.length(rnum);
2349 aLog[indexLog].indexes.length(inum);
2350 for(int i = 0; i < rnum; i++){
2351 aLog[indexLog].coords[i] = *ir;
2352 //MESSAGE(" "<<i<<" "<<ir.Value());
2355 for(int i = 0; i < inum; i++){
2356 aLog[indexLog].indexes[i] = *ii;
2357 //MESSAGE(" "<<i<<" "<<ii.Value());
2366 SMESH_CATCH( SMESH::throwCorbaException );
2368 return aLog._retn();
2372 //=============================================================================
2376 //=============================================================================
2378 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2382 SMESH_CATCH( SMESH::throwCorbaException );
2385 //=============================================================================
2389 //=============================================================================
2391 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2396 //=============================================================================
2400 //=============================================================================
2402 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2407 //=============================================================================
2410 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2411 // issue 0020918: groups removal is caused by hyp modification
2412 // issue 0021208: to forget not loaded mesh data at hyp modification
2413 struct TCallUp_i : public SMESH_Mesh::TCallUp
2415 SMESH_Mesh_i* _mesh;
2416 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2417 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2418 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2419 virtual void Load () { _mesh->Load(); }
2423 //================================================================================
2425 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2427 //================================================================================
2429 void SMESH_Mesh_i::onHypothesisModified()
2432 _preMeshInfo->ForgetOrLoad();
2435 //=============================================================================
2439 //=============================================================================
2441 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2443 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2446 _impl->SetCallUp( new TCallUp_i(this));
2449 //=============================================================================
2453 //=============================================================================
2455 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2457 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2461 //=============================================================================
2463 * Return mesh editor
2465 //=============================================================================
2467 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2468 throw (SALOME::SALOME_Exception)
2470 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2474 _preMeshInfo->FullLoadFromFile();
2476 // Create MeshEditor
2477 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2478 aMeshEdVar = aMeshEditor->_this();
2480 // Update Python script
2481 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2483 SMESH_CATCH( SMESH::throwCorbaException );
2485 return aMeshEdVar._retn();
2488 //=============================================================================
2490 * Return mesh edition previewer
2492 //=============================================================================
2494 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2495 throw (SALOME::SALOME_Exception)
2497 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2501 _preMeshInfo->FullLoadFromFile();
2503 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2504 aMeshEdVar = aMeshEditor->_this();
2506 SMESH_CATCH( SMESH::throwCorbaException );
2508 return aMeshEdVar._retn();
2511 //================================================================================
2513 * \brief Return true if the mesh has been edited since a last total re-compute
2514 * and those modifications may prevent successful partial re-compute
2516 //================================================================================
2518 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2520 Unexpect aCatch(SALOME_SalomeException);
2521 return _impl->HasModificationsToDiscard();
2524 //================================================================================
2526 * \brief Returns a random unique color
2528 //================================================================================
2530 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2532 const int MAX_ATTEMPTS = 100;
2534 double tolerance = 0.5;
2535 SALOMEDS::Color col;
2539 // generate random color
2540 double red = (double)rand() / RAND_MAX;
2541 double green = (double)rand() / RAND_MAX;
2542 double blue = (double)rand() / RAND_MAX;
2543 // check existence in the list of the existing colors
2544 bool matched = false;
2545 std::list<SALOMEDS::Color>::const_iterator it;
2546 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2547 SALOMEDS::Color color = *it;
2548 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2549 matched = tol < tolerance;
2551 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2552 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2560 //=============================================================================
2562 * Sets auto-color mode. If it is on, groups get unique random colors
2564 //=============================================================================
2566 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2568 Unexpect aCatch(SALOME_SalomeException);
2569 _impl->SetAutoColor(theAutoColor);
2571 TPythonDump pyDump; // not to dump group->SetColor() from below code
2572 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2574 std::list<SALOMEDS::Color> aReservedColors;
2575 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2576 for ( ; it != _mapGroups.end(); it++ ) {
2577 if ( CORBA::is_nil( it->second )) continue;
2578 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2579 it->second->SetColor( aColor );
2580 aReservedColors.push_back( aColor );
2584 //=============================================================================
2586 * Returns true if auto-color mode is on
2588 //=============================================================================
2590 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2592 Unexpect aCatch(SALOME_SalomeException);
2593 return _impl->GetAutoColor();
2596 //=============================================================================
2598 * Checks if there are groups with equal names
2600 //=============================================================================
2602 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2604 return _impl->HasDuplicatedGroupNamesMED();
2607 //================================================================================
2609 * \brief Care of a file before exporting mesh into it
2611 //================================================================================
2613 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2615 TCollection_AsciiString aFullName ((char*)file);
2616 OSD_Path aPath (aFullName);
2617 OSD_File aFile (aPath);
2618 if (aFile.Exists()) {
2619 // existing filesystem node
2620 if (aFile.KindOfFile() == OSD_FILE) {
2621 if (aFile.IsWriteable()) {
2626 if (aFile.Failed()) {
2627 TCollection_AsciiString msg ("File ");
2628 msg += aFullName + " cannot be replaced.";
2629 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2632 TCollection_AsciiString msg ("File ");
2633 msg += aFullName + " cannot be overwritten.";
2634 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2637 TCollection_AsciiString msg ("Location ");
2638 msg += aFullName + " is not a file.";
2639 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2642 // nonexisting file; check if it can be created
2644 aFile.Build(OSD_WriteOnly, OSD_Protection());
2645 if (aFile.Failed()) {
2646 TCollection_AsciiString msg ("You cannot create the file ");
2647 msg += aFullName + ". Check the directory existance and access rights.";
2648 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2656 //================================================================================
2658 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2659 * \param file - file name
2660 * \param overwrite - to erase the file or not
2661 * \retval string - mesh name
2663 //================================================================================
2665 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2666 CORBA::Boolean overwrite)
2669 PrepareForWriting(file, overwrite);
2670 string aMeshName = "Mesh";
2671 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2672 if ( !aStudy->_is_nil() ) {
2673 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2674 if ( !aMeshSO->_is_nil() ) {
2675 CORBA::String_var name = aMeshSO->GetName();
2677 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2678 if ( !aStudy->GetProperties()->IsLocked() )
2680 SALOMEDS::GenericAttribute_wrap anAttr;
2681 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2682 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2683 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2684 ASSERT(!aFileName->_is_nil());
2685 aFileName->SetValue(file);
2686 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2687 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2688 ASSERT(!aFileType->_is_nil());
2689 aFileType->SetValue("FICHIERMED");
2693 // Update Python script
2694 // set name of mesh before export
2695 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2697 // check names of groups
2703 //================================================================================
2705 * \brief Export to med file
2707 //================================================================================
2709 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2710 CORBA::Boolean auto_groups,
2711 SMESH::MED_VERSION theVersion,
2712 CORBA::Boolean overwrite)
2713 throw(SALOME::SALOME_Exception)
2715 Unexpect aCatch(SALOME_SalomeException);
2717 _preMeshInfo->FullLoadFromFile();
2719 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2720 TPythonDump() << _this() << ".ExportToMEDX( r'"
2721 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2723 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2726 //================================================================================
2728 * \brief Export a mesh to a med file
2730 //================================================================================
2732 void SMESH_Mesh_i::ExportToMED (const char* file,
2733 CORBA::Boolean auto_groups,
2734 SMESH::MED_VERSION theVersion)
2735 throw(SALOME::SALOME_Exception)
2737 ExportToMEDX(file,auto_groups,theVersion,true);
2740 //================================================================================
2742 * \brief Export a mesh to a med file
2744 //================================================================================
2746 void SMESH_Mesh_i::ExportMED (const char* file,
2747 CORBA::Boolean auto_groups)
2748 throw(SALOME::SALOME_Exception)
2750 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2753 //================================================================================
2755 * \brief Export a mesh to a SAUV file
2757 //================================================================================
2759 void SMESH_Mesh_i::ExportSAUV (const char* file,
2760 CORBA::Boolean auto_groups)
2761 throw(SALOME::SALOME_Exception)
2763 Unexpect aCatch(SALOME_SalomeException);
2765 _preMeshInfo->FullLoadFromFile();
2767 string aMeshName = prepareMeshNameAndGroups(file, true);
2768 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2769 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2773 //================================================================================
2775 * \brief Export a mesh to a DAT file
2777 //================================================================================
2779 void SMESH_Mesh_i::ExportDAT (const char *file)
2780 throw(SALOME::SALOME_Exception)
2782 Unexpect aCatch(SALOME_SalomeException);
2784 _preMeshInfo->FullLoadFromFile();
2786 // Update Python script
2787 // check names of groups
2789 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2792 PrepareForWriting(file);
2793 _impl->ExportDAT(file);
2796 //================================================================================
2798 * \brief Export a mesh to an UNV file
2800 //================================================================================
2802 void SMESH_Mesh_i::ExportUNV (const char *file)
2803 throw(SALOME::SALOME_Exception)
2805 Unexpect aCatch(SALOME_SalomeException);
2807 _preMeshInfo->FullLoadFromFile();
2809 // Update Python script
2810 // check names of groups
2812 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2815 PrepareForWriting(file);
2816 _impl->ExportUNV(file);
2819 //================================================================================
2821 * \brief Export a mesh to an STL file
2823 //================================================================================
2825 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2826 throw(SALOME::SALOME_Exception)
2828 Unexpect aCatch(SALOME_SalomeException);
2830 _preMeshInfo->FullLoadFromFile();
2832 // Update Python script
2833 // check names of groups
2835 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2838 PrepareForWriting(file);
2839 _impl->ExportSTL(file, isascii);
2842 //================================================================================
2844 * \brief Export a part of mesh to a med file
2846 //================================================================================
2848 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2850 CORBA::Boolean auto_groups,
2851 ::SMESH::MED_VERSION version,
2852 ::CORBA::Boolean overwrite)
2853 throw (SALOME::SALOME_Exception)
2855 Unexpect aCatch(SALOME_SalomeException);
2857 _preMeshInfo->FullLoadFromFile();
2859 PrepareForWriting(file, overwrite);
2861 string aMeshName = "Mesh";
2862 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2863 if ( !aStudy->_is_nil() ) {
2864 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2865 if ( !SO->_is_nil() ) {
2866 CORBA::String_var name = SO->GetName();
2870 SMESH_MeshPartDS partDS( meshPart );
2871 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2873 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2874 << auto_groups << ", " << version << ", " << overwrite << " )";
2877 //================================================================================
2879 * \brief Export a part of mesh to a DAT file
2881 //================================================================================
2883 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2885 throw (SALOME::SALOME_Exception)
2887 Unexpect aCatch(SALOME_SalomeException);
2889 _preMeshInfo->FullLoadFromFile();
2891 PrepareForWriting(file);
2893 SMESH_MeshPartDS partDS( meshPart );
2894 _impl->ExportDAT(file,&partDS);
2896 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2898 //================================================================================
2900 * \brief Export a part of mesh to an UNV file
2902 //================================================================================
2904 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2906 throw (SALOME::SALOME_Exception)
2908 Unexpect aCatch(SALOME_SalomeException);
2910 _preMeshInfo->FullLoadFromFile();
2912 PrepareForWriting(file);
2914 SMESH_MeshPartDS partDS( meshPart );
2915 _impl->ExportUNV(file, &partDS);
2917 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2919 //================================================================================
2921 * \brief Export a part of mesh to an STL file
2923 //================================================================================
2925 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2927 ::CORBA::Boolean isascii)
2928 throw (SALOME::SALOME_Exception)
2930 Unexpect aCatch(SALOME_SalomeException);
2932 _preMeshInfo->FullLoadFromFile();
2934 PrepareForWriting(file);
2936 SMESH_MeshPartDS partDS( meshPart );
2937 _impl->ExportSTL(file, isascii, &partDS);
2939 TPythonDump() << _this() << ".ExportPartToSTL( "
2940 << meshPart<< ", r'" << file << "', " << isascii << ")";
2943 //================================================================================
2945 * \brief Export a part of mesh to an STL file
2947 //================================================================================
2949 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2951 CORBA::Boolean overwrite)
2952 throw (SALOME::SALOME_Exception)
2955 Unexpect aCatch(SALOME_SalomeException);
2957 _preMeshInfo->FullLoadFromFile();
2959 PrepareForWriting(file,overwrite);
2961 SMESH_MeshPartDS partDS( meshPart );
2962 _impl->ExportCGNS(file, &partDS);
2964 TPythonDump() << _this() << ".ExportCGNS( "
2965 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2967 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2971 //================================================================================
2973 * \brief Export a part of mesh to a GMF file
2975 //================================================================================
2977 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
2979 bool withRequiredGroups)
2980 throw (SALOME::SALOME_Exception)
2982 Unexpect aCatch(SALOME_SalomeException);
2984 _preMeshInfo->FullLoadFromFile();
2986 PrepareForWriting(file,/*overwrite=*/true);
2988 SMESH_MeshPartDS partDS( meshPart );
2989 _impl->ExportGMF(file, &partDS, withRequiredGroups);
2991 TPythonDump() << _this() << ".ExportGMF( "
2992 << meshPart<< ", r'"
2994 << withRequiredGroups << ")";
2997 //=============================================================================
2999 * Return implementation of SALOME_MED::MESH interfaces
3001 //=============================================================================
3003 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
3005 Unexpect aCatch(SALOME_SalomeException);
3007 _preMeshInfo->FullLoadFromFile();
3009 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
3010 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
3011 return aMesh._retn();
3014 //=============================================================================
3016 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3018 Unexpect aCatch(SALOME_SalomeException);
3020 return _preMeshInfo->NbNodes();
3022 return _impl->NbNodes();
3025 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3027 Unexpect aCatch(SALOME_SalomeException);
3029 return _preMeshInfo->NbElements();
3031 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3034 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3036 Unexpect aCatch(SALOME_SalomeException);
3038 return _preMeshInfo->Nb0DElements();
3040 return _impl->Nb0DElements();
3043 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3045 Unexpect aCatch(SALOME_SalomeException);
3047 return _preMeshInfo->NbBalls();
3049 return _impl->NbBalls();
3052 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3054 Unexpect aCatch(SALOME_SalomeException);
3056 return _preMeshInfo->NbEdges();
3058 return _impl->NbEdges();
3061 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3062 throw(SALOME::SALOME_Exception)
3064 Unexpect aCatch(SALOME_SalomeException);
3066 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3068 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3071 //=============================================================================
3073 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3075 Unexpect aCatch(SALOME_SalomeException);
3077 return _preMeshInfo->NbFaces();
3079 return _impl->NbFaces();
3082 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3084 Unexpect aCatch(SALOME_SalomeException);
3086 return _preMeshInfo->NbTriangles();
3088 return _impl->NbTriangles();
3091 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3093 Unexpect aCatch(SALOME_SalomeException);
3095 return _preMeshInfo->NbBiQuadTriangles();
3097 return _impl->NbBiQuadTriangles();
3100 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3102 Unexpect aCatch(SALOME_SalomeException);
3104 return _preMeshInfo->NbQuadrangles();
3106 return _impl->NbQuadrangles();
3109 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3111 Unexpect aCatch(SALOME_SalomeException);
3113 return _preMeshInfo->NbBiQuadQuadrangles();
3115 return _impl->NbBiQuadQuadrangles();
3118 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3120 Unexpect aCatch(SALOME_SalomeException);
3122 return _preMeshInfo->NbPolygons();
3124 return _impl->NbPolygons();
3127 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3128 throw(SALOME::SALOME_Exception)
3130 Unexpect aCatch(SALOME_SalomeException);
3132 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3134 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3137 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3138 throw(SALOME::SALOME_Exception)
3140 Unexpect aCatch(SALOME_SalomeException);
3142 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3144 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3147 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3148 throw(SALOME::SALOME_Exception)
3150 Unexpect aCatch(SALOME_SalomeException);
3152 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3154 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3157 //=============================================================================
3159 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3161 Unexpect aCatch(SALOME_SalomeException);
3163 return _preMeshInfo->NbVolumes();
3165 return _impl->NbVolumes();
3168 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3170 Unexpect aCatch(SALOME_SalomeException);
3172 return _preMeshInfo->NbTetras();
3174 return _impl->NbTetras();
3177 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3179 Unexpect aCatch(SALOME_SalomeException);
3181 return _preMeshInfo->NbHexas();
3183 return _impl->NbHexas();
3186 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3188 Unexpect aCatch(SALOME_SalomeException);
3190 return _preMeshInfo->NbTriQuadHexas();
3192 return _impl->NbTriQuadraticHexas();
3195 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3197 Unexpect aCatch(SALOME_SalomeException);
3199 return _preMeshInfo->NbPyramids();
3201 return _impl->NbPyramids();
3204 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3206 Unexpect aCatch(SALOME_SalomeException);
3208 return _preMeshInfo->NbPrisms();
3210 return _impl->NbPrisms();
3213 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3215 Unexpect aCatch(SALOME_SalomeException);
3217 return _preMeshInfo->NbHexPrisms();
3219 return _impl->NbHexagonalPrisms();
3222 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3224 Unexpect aCatch(SALOME_SalomeException);
3226 return _preMeshInfo->NbPolyhedrons();
3228 return _impl->NbPolyhedrons();
3231 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3232 throw(SALOME::SALOME_Exception)
3234 Unexpect aCatch(SALOME_SalomeException);
3236 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3238 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3241 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3242 throw(SALOME::SALOME_Exception)
3244 Unexpect aCatch(SALOME_SalomeException);
3246 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3248 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3251 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3252 throw(SALOME::SALOME_Exception)
3254 Unexpect aCatch(SALOME_SalomeException);
3256 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3258 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3261 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3262 throw(SALOME::SALOME_Exception)
3264 Unexpect aCatch(SALOME_SalomeException);
3266 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3268 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3271 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3272 throw(SALOME::SALOME_Exception)
3274 Unexpect aCatch(SALOME_SalomeException);
3276 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3278 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3281 //=============================================================================
3283 * Returns nb of published sub-meshes
3285 //=============================================================================
3287 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3289 Unexpect aCatch(SALOME_SalomeException);
3290 return _mapSubMesh_i.size();
3293 //=============================================================================
3295 * Dumps mesh into a string
3297 //=============================================================================
3299 char* SMESH_Mesh_i::Dump()
3303 return CORBA::string_dup( os.str().c_str() );
3306 //=============================================================================
3308 * Method of SMESH_IDSource interface
3310 //=============================================================================
3312 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3314 return GetElementsId();
3317 //=============================================================================
3319 * Returns ids of all elements
3321 //=============================================================================
3323 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3324 throw (SALOME::SALOME_Exception)
3326 Unexpect aCatch(SALOME_SalomeException);
3328 _preMeshInfo->FullLoadFromFile();
3330 SMESH::long_array_var aResult = new SMESH::long_array();
3331 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3333 if ( aSMESHDS_Mesh == NULL )
3334 return aResult._retn();
3336 long nbElements = NbElements();
3337 aResult->length( nbElements );
3338 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3339 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3340 aResult[i] = anIt->next()->GetID();
3342 return aResult._retn();
3346 //=============================================================================
3348 * Returns ids of all elements of given type
3350 //=============================================================================
3352 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3353 throw (SALOME::SALOME_Exception)
3355 Unexpect aCatch(SALOME_SalomeException);
3357 _preMeshInfo->FullLoadFromFile();
3359 SMESH::long_array_var aResult = new SMESH::long_array();
3360 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3362 if ( aSMESHDS_Mesh == NULL )
3363 return aResult._retn();
3365 long nbElements = NbElements();
3367 // No sense in returning ids of elements along with ids of nodes:
3368 // when theElemType == SMESH::ALL, return node ids only if
3369 // there are no elements
3370 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3371 return GetNodesId();
3373 aResult->length( nbElements );
3377 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3378 while ( i < nbElements && anIt->more() ) {
3379 const SMDS_MeshElement* anElem = anIt->next();
3380 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3381 aResult[i++] = anElem->GetID();
3384 aResult->length( i );
3386 return aResult._retn();
3389 //=============================================================================
3391 * Returns ids of all nodes
3393 //=============================================================================
3395 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3396 throw (SALOME::SALOME_Exception)
3398 Unexpect aCatch(SALOME_SalomeException);
3400 _preMeshInfo->FullLoadFromFile();
3402 SMESH::long_array_var aResult = new SMESH::long_array();
3403 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3405 if ( aSMESHDS_Mesh == NULL )
3406 return aResult._retn();
3408 long nbNodes = NbNodes();
3409 aResult->length( nbNodes );
3410 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3411 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3412 aResult[i] = anIt->next()->GetID();
3414 return aResult._retn();
3417 //=============================================================================
3421 //=============================================================================
3423 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3424 throw (SALOME::SALOME_Exception)
3426 SMESH::ElementType type;
3430 _preMeshInfo->FullLoadFromFile();
3432 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3434 SMESH_CATCH( SMESH::throwCorbaException );
3439 //=============================================================================
3443 //=============================================================================
3445 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3446 throw (SALOME::SALOME_Exception)
3449 _preMeshInfo->FullLoadFromFile();
3451 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3453 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3455 return ( SMESH::EntityType ) e->GetEntityType();
3458 //=============================================================================
3460 * Returns ID of elements for given submesh
3462 //=============================================================================
3463 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3464 throw (SALOME::SALOME_Exception)
3466 SMESH::long_array_var aResult = new SMESH::long_array();
3470 _preMeshInfo->FullLoadFromFile();
3472 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3473 if(!SM) return aResult._retn();
3475 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3476 if(!SDSM) return aResult._retn();
3478 aResult->length(SDSM->NbElements());
3480 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3482 while ( eIt->more() ) {
3483 aResult[i++] = eIt->next()->GetID();
3486 SMESH_CATCH( SMESH::throwCorbaException );
3488 return aResult._retn();
3492 //=============================================================================
3494 * Returns ID of nodes for given submesh
3495 * If param all==true - returns all nodes, else -
3496 * returns only nodes on shapes.
3498 //=============================================================================
3499 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3501 throw (SALOME::SALOME_Exception)
3503 SMESH::long_array_var aResult = new SMESH::long_array();
3507 _preMeshInfo->FullLoadFromFile();
3509 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3510 if(!SM) return aResult._retn();
3512 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3513 if(!SDSM) return aResult._retn();
3516 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3517 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3518 while ( nIt->more() ) {
3519 const SMDS_MeshNode* elem = nIt->next();
3520 theElems.insert( elem->GetID() );
3523 else { // all nodes of submesh elements
3524 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3525 while ( eIt->more() ) {
3526 const SMDS_MeshElement* anElem = eIt->next();
3527 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3528 while ( nIt->more() ) {
3529 const SMDS_MeshElement* elem = nIt->next();
3530 theElems.insert( elem->GetID() );
3535 aResult->length(theElems.size());
3536 set<int>::iterator itElem;
3538 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3539 aResult[i++] = *itElem;
3541 SMESH_CATCH( SMESH::throwCorbaException );
3543 return aResult._retn();
3546 //=============================================================================
3548 * Returns type of elements for given submesh
3550 //=============================================================================
3552 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3553 throw (SALOME::SALOME_Exception)
3555 SMESH::ElementType type;
3559 _preMeshInfo->FullLoadFromFile();
3561 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3562 if(!SM) return SMESH::ALL;
3564 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3565 if(!SDSM) return SMESH::ALL;
3567 if(SDSM->NbElements()==0)
3568 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3570 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3571 const SMDS_MeshElement* anElem = eIt->next();
3573 type = ( SMESH::ElementType ) anElem->GetType();
3575 SMESH_CATCH( SMESH::throwCorbaException );
3581 //=============================================================================
3583 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3585 //=============================================================================
3587 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3590 _preMeshInfo->FullLoadFromFile();
3592 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3594 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3599 //=============================================================================
3601 * Get XYZ coordinates of node as list of double
3602 * If there is not node for given ID - returns empty list
3604 //=============================================================================
3606 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3609 _preMeshInfo->FullLoadFromFile();
3611 SMESH::double_array_var aResult = new SMESH::double_array();
3612 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3613 if ( aSMESHDS_Mesh == NULL )
3614 return aResult._retn();
3617 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3619 return aResult._retn();
3623 aResult[0] = aNode->X();
3624 aResult[1] = aNode->Y();
3625 aResult[2] = aNode->Z();
3626 return aResult._retn();
3630 //=============================================================================
3632 * For given node returns list of IDs of inverse elements
3633 * If there is not node for given ID - returns empty list
3635 //=============================================================================
3637 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3640 _preMeshInfo->FullLoadFromFile();
3642 SMESH::long_array_var aResult = new SMESH::long_array();
3643 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3644 if ( aSMESHDS_Mesh == NULL )
3645 return aResult._retn();
3648 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3650 return aResult._retn();
3652 // find inverse elements
3653 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3654 TColStd_SequenceOfInteger IDs;
3655 while(eIt->more()) {
3656 const SMDS_MeshElement* elem = eIt->next();
3657 IDs.Append(elem->GetID());
3659 if(IDs.Length()>0) {
3660 aResult->length(IDs.Length());
3662 for(; i<=IDs.Length(); i++) {
3663 aResult[i-1] = IDs.Value(i);
3666 return aResult._retn();
3669 //=============================================================================
3671 * \brief Return position of a node on shape
3673 //=============================================================================
3675 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3678 _preMeshInfo->FullLoadFromFile();
3680 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3681 aNodePosition->shapeID = 0;
3682 aNodePosition->shapeType = GEOM::SHAPE;
3684 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3685 if ( !mesh ) return aNodePosition;
3687 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3689 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3691 aNodePosition->shapeID = aNode->getshapeId();
3692 switch ( pos->GetTypeOfPosition() ) {
3694 aNodePosition->shapeType = GEOM::EDGE;
3695 aNodePosition->params.length(1);
3696 aNodePosition->params[0] =
3697 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3700 aNodePosition->shapeType = GEOM::FACE;
3701 aNodePosition->params.length(2);
3702 aNodePosition->params[0] =
3703 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3704 aNodePosition->params[1] =
3705 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3707 case SMDS_TOP_VERTEX:
3708 aNodePosition->shapeType = GEOM::VERTEX;
3710 case SMDS_TOP_3DSPACE:
3711 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3712 aNodePosition->shapeType = GEOM::SOLID;
3713 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3714 aNodePosition->shapeType = GEOM::SHELL;
3720 return aNodePosition;
3723 //=============================================================================
3725 * \brief Return position of an element on shape
3727 //=============================================================================
3729 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
3732 _preMeshInfo->FullLoadFromFile();
3734 SMESH::ElementPosition anElementPosition;
3735 anElementPosition.shapeID = 0;
3736 anElementPosition.shapeType = GEOM::SHAPE;
3738 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3739 if ( !mesh ) return anElementPosition;
3741 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
3743 anElementPosition.shapeID = anElem->getshapeId();
3744 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
3745 if ( !aSp.IsNull() ) {
3746 switch ( aSp.ShapeType() ) {
3748 anElementPosition.shapeType = GEOM::EDGE;
3751 anElementPosition.shapeType = GEOM::FACE;
3754 anElementPosition.shapeType = GEOM::VERTEX;
3757 anElementPosition.shapeType = GEOM::SOLID;
3760 anElementPosition.shapeType = GEOM::SHELL;
3766 return anElementPosition;
3769 //=============================================================================
3771 * If given element is node returns IDs of shape from position
3772 * If there is not node for given ID - returns -1
3774 //=============================================================================
3776 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3779 _preMeshInfo->FullLoadFromFile();
3781 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3782 if ( aSMESHDS_Mesh == NULL )
3786 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3788 return aNode->getshapeId();
3795 //=============================================================================
3797 * For given element returns ID of result shape after
3798 * ::FindShape() from SMESH_MeshEditor
3799 * If there is not element for given ID - returns -1
3801 //=============================================================================
3803 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3806 _preMeshInfo->FullLoadFromFile();
3808 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3809 if ( aSMESHDS_Mesh == NULL )
3812 // try to find element
3813 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3817 ::SMESH_MeshEditor aMeshEditor(_impl);
3818 int index = aMeshEditor.FindShape( elem );
3826 //=============================================================================
3828 * Returns number of nodes for given element
3829 * If there is not element for given ID - returns -1
3831 //=============================================================================
3833 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3836 _preMeshInfo->FullLoadFromFile();
3838 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3839 if ( aSMESHDS_Mesh == NULL ) return -1;
3840 // try to find element
3841 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3842 if(!elem) return -1;
3843 return elem->NbNodes();
3847 //=============================================================================
3849 * Returns ID of node by given index for given element
3850 * If there is not element for given ID - returns -1
3851 * If there is not node for given index - returns -2
3853 //=============================================================================
3855 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3858 _preMeshInfo->FullLoadFromFile();
3860 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3861 if ( aSMESHDS_Mesh == NULL ) return -1;
3862 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3863 if(!elem) return -1;
3864 if( index>=elem->NbNodes() || index<0 ) return -1;
3865 return elem->GetNode(index)->GetID();
3868 //=============================================================================
3870 * Returns IDs of nodes of given element
3872 //=============================================================================
3874 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3877 _preMeshInfo->FullLoadFromFile();
3879 SMESH::long_array_var aResult = new SMESH::long_array();
3880 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3882 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3884 aResult->length( elem->NbNodes() );
3885 for ( int i = 0; i < elem->NbNodes(); ++i )
3886 aResult[ i ] = elem->GetNode( i )->GetID();
3889 return aResult._retn();
3892 //=============================================================================
3894 * Returns true if given node is medium node
3895 * in given quadratic element
3897 //=============================================================================
3899 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3902 _preMeshInfo->FullLoadFromFile();
3904 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3905 if ( aSMESHDS_Mesh == NULL ) return false;
3907 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3908 if(!aNode) return false;
3909 // try to find element
3910 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3911 if(!elem) return false;
3913 return elem->IsMediumNode(aNode);
3917 //=============================================================================
3919 * Returns true if given node is medium node
3920 * in one of quadratic elements
3922 //=============================================================================
3924 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3925 SMESH::ElementType theElemType)
3928 _preMeshInfo->FullLoadFromFile();
3930 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3931 if ( aSMESHDS_Mesh == NULL ) return false;
3934 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3935 if(!aNode) return false;
3937 SMESH_MesherHelper aHelper( *(_impl) );
3939 SMDSAbs_ElementType aType;
3940 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3941 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3942 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3943 else aType = SMDSAbs_All;
3945 return aHelper.IsMedium(aNode,aType);
3949 //=============================================================================
3951 * Returns number of edges for given element
3953 //=============================================================================
3955 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3958 _preMeshInfo->FullLoadFromFile();
3960 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3961 if ( aSMESHDS_Mesh == NULL ) return -1;
3962 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3963 if(!elem) return -1;
3964 return elem->NbEdges();
3968 //=============================================================================
3970 * Returns number of faces for given element
3972 //=============================================================================
3974 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3977 _preMeshInfo->FullLoadFromFile();
3979 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3980 if ( aSMESHDS_Mesh == NULL ) return -1;
3981 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3982 if(!elem) return -1;
3983 return elem->NbFaces();
3986 //=======================================================================
3987 //function : GetElemFaceNodes
3988 //purpose : Returns nodes of given face (counted from zero) for given element.
3989 //=======================================================================
3991 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3992 CORBA::Short faceIndex)
3995 _preMeshInfo->FullLoadFromFile();
3997 SMESH::long_array_var aResult = new SMESH::long_array();
3998 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4000 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4002 SMDS_VolumeTool vtool( elem );
4003 if ( faceIndex < vtool.NbFaces() )
4005 aResult->length( vtool.NbFaceNodes( faceIndex ));
4006 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4007 for ( int i = 0; i < aResult->length(); ++i )
4008 aResult[ i ] = nn[ i ]->GetID();
4012 return aResult._retn();
4015 //=======================================================================
4016 //function : FindElementByNodes
4017 //purpose : Returns an element based on all given nodes.
4018 //=======================================================================
4020 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4023 _preMeshInfo->FullLoadFromFile();
4025 CORBA::Long elemID(0);
4026 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4028 vector< const SMDS_MeshNode * > nn( nodes.length() );
4029 for ( int i = 0; i < nodes.length(); ++i )
4030 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4033 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4034 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4035 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4036 _impl->NbVolumes( ORDER_QUADRATIC )))
4037 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4039 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4044 //=============================================================================
4046 * Returns true if given element is polygon
4048 //=============================================================================
4050 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4053 _preMeshInfo->FullLoadFromFile();
4055 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4056 if ( aSMESHDS_Mesh == NULL ) return false;
4057 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4058 if(!elem) return false;
4059 return elem->IsPoly();
4063 //=============================================================================
4065 * Returns true if given element is quadratic
4067 //=============================================================================
4069 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4072 _preMeshInfo->FullLoadFromFile();
4074 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4075 if ( aSMESHDS_Mesh == NULL ) return false;
4076 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4077 if(!elem) return false;
4078 return elem->IsQuadratic();
4081 //=============================================================================
4083 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4085 //=============================================================================
4087 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4090 _preMeshInfo->FullLoadFromFile();
4092 if ( const SMDS_BallElement* ball =
4093 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4094 return ball->GetDiameter();
4099 //=============================================================================
4101 * Returns bary center for given element
4103 //=============================================================================
4105 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4108 _preMeshInfo->FullLoadFromFile();
4110 SMESH::double_array_var aResult = new SMESH::double_array();
4111 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4112 if ( aSMESHDS_Mesh == NULL )
4113 return aResult._retn();
4115 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4117 return aResult._retn();
4119 if(elem->GetType()==SMDSAbs_Volume) {
4120 SMDS_VolumeTool aTool;
4121 if(aTool.Set(elem)) {
4123 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4128 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4130 double x=0., y=0., z=0.;
4131 for(; anIt->more(); ) {
4133 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4147 return aResult._retn();
4150 //================================================================================
4152 * \brief Create a group of elements preventing computation of a sub-shape
4154 //================================================================================
4156 SMESH::ListOfGroups*
4157 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4158 const char* theGroupName )
4159 throw ( SALOME::SALOME_Exception )
4161 Unexpect aCatch(SALOME_SalomeException);
4163 if ( !theGroupName || strlen( theGroupName) == 0 )
4164 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4166 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4168 // submesh by subshape id
4169 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4170 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4173 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4174 if ( error && !error->myBadElements.empty())
4176 // sort bad elements by type
4177 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4178 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4179 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4180 for ( ; elemIt != elemEnd; ++elemIt )
4182 const SMDS_MeshElement* elem = *elemIt;
4183 if ( !elem ) continue;
4185 if ( elem->GetID() < 1 )
4187 // elem is a temporary element, make a real element
4188 vector< const SMDS_MeshNode* > nodes;
4189 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4190 while ( nIt->more() && elem )
4192 nodes.push_back( nIt->next() );
4193 if ( nodes.back()->GetID() < 1 )
4194 elem = 0; // a temporary element on temporary nodes
4198 ::SMESH_MeshEditor editor( _impl );
4199 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4203 elemsByType[ elem->GetType() ].push_back( elem );
4206 // how many groups to create?
4208 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4209 nbTypes += int( !elemsByType[ i ].empty() );
4210 groups->length( nbTypes );
4213 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4215 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4216 if ( elems.empty() ) continue;
4218 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4219 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4221 SALOMEDS::SObject_wrap aSO =
4222 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), groups[ iG ],
4223 GEOM::GEOM_Object::_nil(), theGroupName);
4224 aSO->_is_nil(); // avoid "unused variable" warning
4226 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4227 if ( !grp_i ) continue;
4229 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4230 for ( size_t iE = 0; iE < elems.size(); ++iE )
4231 grpDS->SMDSGroup().Add( elems[ iE ]);
4236 return groups._retn();
4239 //=============================================================================
4241 * Create and publish group servants if any groups were imported or created anyhow
4243 //=============================================================================
4245 void SMESH_Mesh_i::CreateGroupServants()
4247 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4250 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4251 while ( groupIt->more() )
4253 ::SMESH_Group* group = groupIt->next();
4254 int anId = group->GetGroupDS()->GetID();
4256 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4257 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4259 addedIDs.insert( anId );
4261 SMESH_GroupBase_i* aGroupImpl;
4263 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4264 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4266 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4267 shape = groupOnGeom->GetShape();
4270 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4273 SMESH::SMESH_GroupBase_var groupVar =
4274 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4275 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4277 // register CORBA object for persistence
4278 int nextId = _gen_i->RegisterObject( groupVar );
4279 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
4281 // publishing the groups in the study
4282 if ( !aStudy->_is_nil() ) {
4283 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4284 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4287 if ( !addedIDs.empty() )
4290 set<int>::iterator id = addedIDs.begin();
4291 for ( ; id != addedIDs.end(); ++id )
4293 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4294 int i = std::distance( _mapGroups.begin(), it );
4295 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4300 //=============================================================================
4302 * \brief Return groups cantained in _mapGroups by their IDs
4304 //=============================================================================
4306 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4308 int nbGroups = groupIDs.size();
4309 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4310 aList->length( nbGroups );
4312 list<int>::const_iterator ids = groupIDs.begin();
4313 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4315 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4316 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4317 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4319 aList->length( nbGroups );
4320 return aList._retn();
4323 //=============================================================================
4325 * \brief Return information about imported file
4327 //=============================================================================
4329 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4331 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4332 if ( !res.operator->() ) {
4333 res = new SALOME_MED::MedFileInfo;
4335 res->fileSize = res->major = res->minor = res->release = -1;
4340 //=============================================================================
4342 * \brief Pass names of mesh groups from study to mesh DS
4344 //=============================================================================
4346 void SMESH_Mesh_i::checkGroupNames()
4348 int nbGrp = NbGroups();
4352 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4353 if ( aStudy->_is_nil() )
4354 return; // nothing to do
4356 SMESH::ListOfGroups* grpList = 0;
4357 // avoid dump of "GetGroups"
4359 // store python dump into a local variable inside local scope
4360 SMESH::TPythonDump pDump; // do not delete this line of code
4361 grpList = GetGroups();
4364 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4365 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4368 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4369 if ( aGrpSO->_is_nil() )
4371 // correct name of the mesh group if necessary
4372 const char* guiName = aGrpSO->GetName();
4373 if ( strcmp(guiName, aGrp->GetName()) )
4374 aGrp->SetName( guiName );
4378 //=============================================================================
4380 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4382 //=============================================================================
4383 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4385 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4389 //=============================================================================
4391 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4393 //=============================================================================
4394 char* SMESH_Mesh_i::GetParameters()
4396 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4397 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4400 //=============================================================================
4402 * \brief Returns list of notebook variables used for last Mesh operation
4404 //=============================================================================
4405 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4407 SMESH::string_array_var aResult = new SMESH::string_array();
4408 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4410 char *aParameters = GetParameters();
4411 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4412 if(!aStudy->_is_nil()) {
4413 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4414 if(aSections->length() > 0) {
4415 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4416 aResult->length(aVars.length());
4417 for(int i = 0;i < aVars.length();i++)
4418 aResult[i] = CORBA::string_dup( aVars[i]);
4422 return aResult._retn();
4425 //=======================================================================
4426 //function : GetTypes
4427 //purpose : Returns types of elements it contains
4428 //=======================================================================
4430 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4433 return _preMeshInfo->GetTypes();
4435 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4439 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4440 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4441 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4442 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4443 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4444 types->length( nbTypes );
4446 return types._retn();
4449 //=======================================================================
4450 //function : GetMesh
4451 //purpose : Returns self
4452 //=======================================================================
4454 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4456 return SMESH::SMESH_Mesh::_duplicate( _this() );
4459 //=======================================================================
4460 //function : IsMeshInfoCorrect
4461 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4462 // * happen if mesh data is not yet fully loaded from the file of study.
4463 //=======================================================================
4465 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4467 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4470 //=============================================================================
4472 * \brief Returns statistic of mesh elements
4474 //=============================================================================
4476 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4479 return _preMeshInfo->GetMeshInfo();
4481 SMESH::long_array_var aRes = new SMESH::long_array();
4482 aRes->length(SMESH::Entity_Last);
4483 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4485 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4487 return aRes._retn();
4488 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4489 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4490 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4491 return aRes._retn();
4494 //=============================================================================
4496 * \brief Collect statistic of mesh elements given by iterator
4498 //=============================================================================
4500 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4501 SMESH::long_array& theInfo)
4503 if (!theItr) return;
4504 while (theItr->more())
4505 theInfo[ theItr->next()->GetEntityType() ]++;
4508 //=============================================================================
4509 namespace // Finding concurrent hypotheses
4510 //=============================================================================
4514 * \brief mapping of mesh dimension into shape type
4516 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4518 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4520 case 0: aType = TopAbs_VERTEX; break;
4521 case 1: aType = TopAbs_EDGE; break;
4522 case 2: aType = TopAbs_FACE; break;
4524 default:aType = TopAbs_SOLID; break;
4529 //-----------------------------------------------------------------------------
4531 * \brief Internal structure used to find concurent submeshes
4533 * It represents a pair < submesh, concurent dimension >, where
4534 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4535 * with another submesh. In other words, it is dimension of a hypothesis assigned
4542 int _dim; //!< a dimension the algo can build (concurrent dimension)
4543 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4544 TopTools_MapOfShape _shapeMap;
4545 SMESH_subMesh* _subMesh;
4546 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4548 //-----------------------------------------------------------------------------
4549 // Return the algorithm
4550 const SMESH_Algo* GetAlgo() const
4551 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4553 //-----------------------------------------------------------------------------
4555 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4557 const TopoDS_Shape& theShape)
4559 _subMesh = (SMESH_subMesh*)theSubMesh;
4560 SetShape( theDim, theShape );
4563 //-----------------------------------------------------------------------------
4565 void SetShape(const int theDim,
4566 const TopoDS_Shape& theShape)
4569 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4570 if (_dim >= _ownDim)
4571 _shapeMap.Add( theShape );
4573 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4574 for( ; anExp.More(); anExp.Next() )
4575 _shapeMap.Add( anExp.Current() );
4579 //-----------------------------------------------------------------------------
4580 //! Check sharing of sub-shapes
4581 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4582 const TopTools_MapOfShape& theToFind,
4583 const TopAbs_ShapeEnum theType)
4585 bool isShared = false;
4586 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4587 for (; !isShared && anItr.More(); anItr.Next() )
4589 const TopoDS_Shape aSubSh = anItr.Key();
4590 // check for case when concurrent dimensions are same
4591 isShared = theToFind.Contains( aSubSh );
4592 // check for sub-shape with concurrent dimension
4593 TopExp_Explorer anExp( aSubSh, theType );
4594 for ( ; !isShared && anExp.More(); anExp.Next() )
4595 isShared = theToFind.Contains( anExp.Current() );
4600 //-----------------------------------------------------------------------------
4601 //! check algorithms
4602 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4603 const SMESHDS_Hypothesis* theA2)
4605 if ( !theA1 || !theA2 ||
4606 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4607 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4608 return false; // one of the hypothesis is not algorithm
4609 // check algorithm names (should be equal)
4610 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4614 //-----------------------------------------------------------------------------
4615 //! Check if sub-shape hypotheses are concurrent
4616 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4618 if ( _subMesh == theOther->_subMesh )
4619 return false; // same sub-shape - should not be
4621 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4622 // any of the two submeshes is not on COMPOUND shape )
4623 // -> no concurrency
4624 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4625 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4626 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4627 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4628 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4631 // bool checkSubShape = ( _dim >= theOther->_dim )
4632 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4633 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4634 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4635 if ( !checkSubShape )
4638 // check algorithms to be same
4639 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4640 return true; // different algorithms -> concurrency !
4642 // check hypothesises for concurrence (skip first as algorithm)
4644 // pointers should be same, because it is referened from mesh hypothesis partition
4645 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4646 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4647 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4648 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4650 // the submeshes are concurrent if their algorithms has different parameters
4651 return nbSame != theOther->_hypotheses.size() - 1;
4654 // Return true if algorithm of this SMESH_DimHyp is used if no
4655 // sub-mesh order is imposed by the user
4656 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4658 // NeedDiscreteBoundary() algo has a higher priority
4659 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4660 theOther->GetAlgo()->NeedDiscreteBoundary() )
4661 return !this->GetAlgo()->NeedDiscreteBoundary();
4663 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4666 }; // end of SMESH_DimHyp
4667 //-----------------------------------------------------------------------------
4669 typedef list<const SMESH_DimHyp*> TDimHypList;
4671 //-----------------------------------------------------------------------------
4673 void addDimHypInstance(const int theDim,
4674 const TopoDS_Shape& theShape,
4675 const SMESH_Algo* theAlgo,
4676 const SMESH_subMesh* theSubMesh,
4677 const list <const SMESHDS_Hypothesis*>& theHypList,
4678 TDimHypList* theDimHypListArr )
4680 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4681 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4682 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4683 dimHyp->_hypotheses.push_front(theAlgo);
4684 listOfdimHyp.push_back( dimHyp );
4687 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4688 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4689 theHypList.begin(), theHypList.end() );
4692 //-----------------------------------------------------------------------------
4693 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4694 TDimHypList& theListOfConcurr)
4696 if ( theListOfConcurr.empty() )
4698 theListOfConcurr.push_back( theDimHyp );
4702 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4703 while ( hypIt != theListOfConcurr.end() &&
4704 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4706 theListOfConcurr.insert( hypIt, theDimHyp );
4710 //-----------------------------------------------------------------------------
4711 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4712 const TDimHypList& theListOfDimHyp,
4713 TDimHypList& theListOfConcurrHyp,
4714 set<int>& theSetOfConcurrId )
4716 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4717 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4719 const SMESH_DimHyp* curDimHyp = *rIt;
4720 if ( curDimHyp == theDimHyp )
4721 break; // meet own dimHyp pointer in same dimension
4723 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4724 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4726 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4731 //-----------------------------------------------------------------------------
4732 void unionLists(TListOfInt& theListOfId,
4733 TListOfListOfInt& theListOfListOfId,
4736 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4737 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4739 continue; //skip already treated lists
4740 // check if other list has any same submesh object
4741 TListOfInt& otherListOfId = *it;
4742 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4743 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4746 // union two lists (from source into target)
4747 TListOfInt::iterator it2 = otherListOfId.begin();
4748 for ( ; it2 != otherListOfId.end(); it2++ ) {
4749 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4750 theListOfId.push_back(*it2);
4752 // clear source list
4753 otherListOfId.clear();
4756 //-----------------------------------------------------------------------------
4758 //! free memory allocated for dimension-hypothesis objects
4759 void removeDimHyps( TDimHypList* theArrOfList )
4761 for (int i = 0; i < 4; i++ ) {
4762 TDimHypList& listOfdimHyp = theArrOfList[i];
4763 TDimHypList::const_iterator it = listOfdimHyp.begin();
4764 for ( ; it != listOfdimHyp.end(); it++ )
4769 //-----------------------------------------------------------------------------
4771 * \brief find common submeshes with given submesh
4772 * \param theSubMeshList list of already collected submesh to check
4773 * \param theSubMesh given submesh to intersect with other
4774 * \param theCommonSubMeshes collected common submeshes
4776 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4777 const SMESH_subMesh* theSubMesh,
4778 set<const SMESH_subMesh*>& theCommon )
4782 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4783 for ( ; it != theSubMeshList.end(); it++ )
4784 theSubMesh->FindIntersection( *it, theCommon );
4785 theSubMeshList.push_back( theSubMesh );
4786 //theCommon.insert( theSubMesh );
4791 //=============================================================================
4793 * \brief Return submesh objects list in meshing order
4795 //=============================================================================
4797 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4799 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4801 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4803 return aResult._retn();
4805 ::SMESH_Mesh& mesh = GetImpl();
4806 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4807 if ( !anOrder.size() ) {
4809 // collect submeshes and detect concurrent algorithms and hypothesises
4810 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4812 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4813 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4814 ::SMESH_subMesh* sm = (*i_sm).second;
4816 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4818 // list of assigned hypothesises
4819 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4820 // Find out dimensions where the submesh can be concurrent.
4821 // We define the dimensions by algo of each of hypotheses in hypList
4822 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4823 for( ; hypIt != hypList.end(); hypIt++ ) {
4824 SMESH_Algo* anAlgo = 0;
4825 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4826 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4827 // hyp it-self is algo
4828 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4830 // try to find algorithm with help of sub-shapes
4831 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4832 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4833 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4836 continue; // no algorithm assigned to a current submesh
4838 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4839 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4841 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4842 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4843 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4845 } // end iterations on submesh
4847 // iterate on created dimension-hypotheses and check for concurrents
4848 for ( int i = 0; i < 4; i++ ) {
4849 const TDimHypList& listOfDimHyp = dimHypListArr[i];
4850 // check for concurrents in own and other dimensions (step-by-step)
4851 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4852 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4853 const SMESH_DimHyp* dimHyp = *dhIt;
4854 TDimHypList listOfConcurr;
4855 set<int> setOfConcurrIds;
4856 // looking for concurrents and collect into own list
4857 for ( int j = i; j < 4; j++ )
4858 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
4859 // check if any concurrents found
4860 if ( listOfConcurr.size() > 0 ) {
4861 // add own submesh to list of concurrent
4862 addInOrderOfPriority( dimHyp, listOfConcurr );
4863 list<int> listOfConcurrIds;
4864 TDimHypList::iterator hypIt = listOfConcurr.begin();
4865 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
4866 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
4867 anOrder.push_back( listOfConcurrIds );
4872 removeDimHyps(dimHypListArr);
4874 // now, minimise the number of concurrent groups
4875 // Here we assume that lists of submeshes can have same submesh
4876 // in case of multi-dimension algorithms, as result
4877 // list with common submesh has to be united into one list
4879 TListOfListOfInt::iterator listIt = anOrder.begin();
4880 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4881 unionLists( *listIt, anOrder, listIndx + 1 );
4883 // convert submesh ids into interface instances
4884 // and dump command into python
4885 convertMeshOrder( anOrder, aResult, false );
4887 return aResult._retn();
4890 //=============================================================================
4892 * \brief Set submesh object order
4893 * \param theSubMeshArray submesh array order
4895 //=============================================================================
4897 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4900 _preMeshInfo->ForgetOrLoad();
4903 ::SMESH_Mesh& mesh = GetImpl();
4905 TPythonDump aPythonDump; // prevent dump of called methods
4906 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4908 TListOfListOfInt subMeshOrder;
4909 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4911 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4912 TListOfInt subMeshIds;
4913 aPythonDump << "[ ";
4914 // Collect subMeshes which should be clear
4915 // do it list-by-list, because modification of submesh order
4916 // take effect between concurrent submeshes only
4917 set<const SMESH_subMesh*> subMeshToClear;
4918 list<const SMESH_subMesh*> subMeshList;
4919 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4921 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4923 aPythonDump << ", ";
4924 aPythonDump << subMesh;
4925 subMeshIds.push_back( subMesh->GetId() );
4926 // detect common parts of submeshes
4927 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4928 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4930 aPythonDump << " ]";
4931 subMeshOrder.push_back( subMeshIds );
4933 // clear collected submeshes
4934 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4935 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
4936 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
4937 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4939 aPythonDump << " ])";
4941 mesh.SetMeshOrder( subMeshOrder );
4947 //=============================================================================
4949 * \brief Convert submesh ids into submesh interfaces
4951 //=============================================================================
4953 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4954 SMESH::submesh_array_array& theResOrder,
4955 const bool theIsDump)
4957 int nbSet = theIdsOrder.size();
4958 TPythonDump aPythonDump; // prevent dump of called methods
4960 aPythonDump << "[ ";
4961 theResOrder.length(nbSet);
4962 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4964 for( ; it != theIdsOrder.end(); it++ ) {
4965 // translate submesh identificators into submesh objects
4966 // takeing into account real number of concurrent lists
4967 const TListOfInt& aSubOrder = (*it);
4968 if (!aSubOrder.size())
4971 aPythonDump << "[ ";
4972 // convert shape indeces into interfaces
4973 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4974 aResSubSet->length(aSubOrder.size());
4975 TListOfInt::const_iterator subIt = aSubOrder.begin();
4976 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4977 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4979 SMESH::SMESH_subMesh_var subMesh =
4980 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4983 aPythonDump << ", ";
4984 aPythonDump << subMesh;
4986 aResSubSet[ j++ ] = subMesh;
4989 aPythonDump << " ]";
4990 theResOrder[ listIndx++ ] = aResSubSet;
4992 // correct number of lists
4993 theResOrder.length( listIndx );
4996 // finilise python dump
4997 aPythonDump << " ]";
4998 aPythonDump << " = " << _this() << ".GetMeshOrder()";
5002 //================================================================================
5004 // Implementation of SMESH_MeshPartDS
5006 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5007 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5009 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5010 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5012 _meshDS = mesh_i->GetImpl().GetMeshDS();
5014 SetPersistentId( _meshDS->GetPersistentId() );
5016 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5018 // <meshPart> is the whole mesh
5019 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5021 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5022 myGroupSet = _meshDS->GetGroups();
5027 SMESH::long_array_var anIDs = meshPart->GetIDs();
5028 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5029 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5031 for (int i=0; i < anIDs->length(); i++)
5032 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5033 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5038 for (int i=0; i < anIDs->length(); i++)
5039 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5040 if ( _elements[ e->GetType() ].insert( e ).second )
5043 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5044 while ( nIt->more() )
5046 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5047 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5054 _meshDS = 0; // to enforce iteration on _elements and _nodes
5057 // -------------------------------------------------------------------------------------
5058 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5059 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5062 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5063 for ( ; partIt != meshPart.end(); ++partIt )
5064 if ( const SMDS_MeshElement * e = *partIt )
5065 if ( _elements[ e->GetType() ].insert( e ).second )
5068 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5069 while ( nIt->more() )
5071 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5072 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5078 // -------------------------------------------------------------------------------------
5079 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5081 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5083 typedef SMDS_SetIterator
5084 <const SMDS_MeshElement*,
5085 TIDSortedElemSet::const_iterator,
5086 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5087 SMDS_MeshElement::GeomFilter
5090 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5092 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5093 _elements[type].end(),
5094 SMDS_MeshElement::GeomFilter( geomType )));
5096 // -------------------------------------------------------------------------------------
5097 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5099 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5101 typedef SMDS_SetIterator
5102 <const SMDS_MeshElement*,
5103 TIDSortedElemSet::const_iterator,
5104 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5105 SMDS_MeshElement::EntityFilter
5108 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5110 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5111 _elements[type].end(),
5112 SMDS_MeshElement::EntityFilter( entity )));
5114 // -------------------------------------------------------------------------------------
5115 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5117 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5118 if ( type == SMDSAbs_All && !_meshDS )
5120 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5122 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5123 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5125 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5127 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5128 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5130 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5131 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5133 // -------------------------------------------------------------------------------------
5134 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5135 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5137 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5138 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5139 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5141 // -------------------------------------------------------------------------------------
5142 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5143 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5144 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5145 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5146 #undef _GET_ITER_DEFINE
5148 // END Implementation of SMESH_MeshPartDS
5150 //================================================================================