1 // Copyright (C) 2007-2012 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_SetIterator.hxx"
35 #include "SMDS_VolumeTool.hxx"
36 #include "SMESHDS_Command.hxx"
37 #include "SMESHDS_CommandType.hxx"
38 #include "SMESHDS_GroupOnGeom.hxx"
39 #include "SMESH_Filter_i.hxx"
40 #include "SMESH_Gen_i.hxx"
41 #include "SMESH_Group.hxx"
42 #include "SMESH_Group_i.hxx"
43 #include "SMESH_MEDMesh_i.hxx"
44 #include "SMESH_MeshEditor.hxx"
45 #include "SMESH_MeshEditor_i.hxx"
46 #include "SMESH_MeshPartDS.hxx"
47 #include "SMESH_MesherHelper.hxx"
48 #include "SMESH_PreMeshInfo.hxx"
49 #include "SMESH_PythonDump.hxx"
50 #include "SMESH_subMesh_i.hxx"
53 #include <SALOME_NamingService.hxx>
54 #include <Utils_CorbaException.hxx>
55 #include <Utils_ExceptHandlers.hxx>
56 #include <Utils_SINGLETON.hxx>
57 #include <utilities.h>
58 #include <GEOMImpl_Types.hxx>
61 #include <BRep_Builder.hxx>
62 #include <OSD_Directory.hxx>
63 #include <OSD_File.hxx>
64 #include <OSD_Path.hxx>
65 #include <OSD_Protection.hxx>
66 #include <Standard_OutOfMemory.hxx>
67 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
68 #include <TColStd_MapOfInteger.hxx>
69 #include <TColStd_SequenceOfInteger.hxx>
70 #include <TCollection_AsciiString.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
85 static int MYDEBUG = 0;
87 static int MYDEBUG = 0;
91 using SMESH::TPythonDump;
93 int SMESH_Mesh_i::_idGenerator = 0;
95 //To disable automatic genericobj management, the following line should be commented.
96 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
97 #define WITHGENERICOBJ
99 //=============================================================================
103 //=============================================================================
105 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
107 CORBA::Long studyId )
108 : SALOME::GenericObj_i( thePOA )
110 MESSAGE("SMESH_Mesh_i");
113 _id = _idGenerator++;
118 //=============================================================================
122 //=============================================================================
124 SMESH_Mesh_i::~SMESH_Mesh_i()
126 MESSAGE("~SMESH_Mesh_i");
128 #ifdef WITHGENERICOBJ
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
132 if ( CORBA::is_nil( itGr->second ))
134 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
136 // this method is called from destructor of group (PAL6331)
137 //_impl->RemoveGroup( aGroup->GetLocalID() );
138 aGroup->myMeshServant = 0;
139 aGroup->UnRegister();
145 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
146 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
147 if ( CORBA::is_nil( itSM->second ))
149 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
151 aSubMesh->UnRegister();
154 _mapSubMeshIor.clear();
156 // destroy hypotheses
157 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
158 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
159 if ( CORBA::is_nil( itH->second ))
161 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
169 delete _impl; _impl = NULL;
171 if ( _preMeshInfo ) delete _preMeshInfo; _preMeshInfo = NULL;
174 //=============================================================================
178 * Associates <this> mesh with <theShape> and puts a reference
179 * to <theShape> into the current study;
180 * the previous shape is substituted by the new one.
182 //=============================================================================
184 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
185 throw (SALOME::SALOME_Exception)
187 Unexpect aCatch(SALOME_SalomeException);
189 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 // to track changes of GEOM groups
195 addGeomGroupData( theShapeObject, _this() );
198 //================================================================================
200 * \brief return true if mesh has a shape to build a shape on
202 //================================================================================
204 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
205 throw (SALOME::SALOME_Exception)
207 Unexpect aCatch(SALOME_SalomeException);
210 res = _impl->HasShapeToMesh();
212 catch(SALOME_Exception & S_ex) {
213 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
218 //=======================================================================
219 //function : GetShapeToMesh
221 //=======================================================================
223 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
224 throw (SALOME::SALOME_Exception)
226 Unexpect aCatch(SALOME_SalomeException);
227 GEOM::GEOM_Object_var aShapeObj;
229 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
231 aShapeObj = _gen_i->ShapeToGeomObject( S );
233 catch(SALOME_Exception & S_ex) {
234 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
236 return aShapeObj._retn();
239 //================================================================================
241 * \brief Return false if the mesh is not yet fully loaded from the study file
243 //================================================================================
245 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
247 Unexpect aCatch(SALOME_SalomeException);
248 return !_preMeshInfo;
251 //================================================================================
253 * \brief Load full mesh data from the study file
255 //================================================================================
257 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
259 Unexpect aCatch(SALOME_SalomeException);
261 _preMeshInfo->FullLoadFromFile();
264 //================================================================================
266 * \brief Remove all nodes and elements
268 //================================================================================
270 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
272 Unexpect aCatch(SALOME_SalomeException);
274 _preMeshInfo->ForgetAllData();
278 CheckGeomGroupModif(); // issue 20145
280 catch(SALOME_Exception & S_ex) {
281 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
283 TPythonDump() << _this() << ".Clear()";
286 //================================================================================
288 * \brief Remove all nodes and elements for indicated shape
290 //================================================================================
292 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
293 throw (SALOME::SALOME_Exception)
295 Unexpect aCatch(SALOME_SalomeException);
297 _preMeshInfo->FullLoadFromFile();
300 _impl->ClearSubMesh( ShapeID );
302 catch(SALOME_Exception & S_ex) {
303 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
307 //=============================================================================
309 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
311 //=============================================================================
313 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
315 SMESH::DriverMED_ReadStatus res;
318 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
319 res = SMESH::DRS_OK; break;
320 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
321 res = SMESH::DRS_EMPTY; break;
322 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
323 res = SMESH::DRS_WARN_RENUMBER; break;
324 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
325 res = SMESH::DRS_WARN_SKIP_ELEM; break;
326 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
328 res = SMESH::DRS_FAIL; break;
333 //=============================================================================
335 * Convert ::SMESH_ComputeError to SMESH::ComputeError
337 //=============================================================================
339 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
341 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
342 errVar->subShapeID = -1;
343 errVar->hasBadMesh = false;
345 if ( !errorPtr || errorPtr->IsOK() )
347 errVar->code = SMESH::COMPERR_OK;
351 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
352 errVar->comment = errorPtr->myComment.c_str();
354 return errVar._retn();
357 //=============================================================================
361 * Imports mesh data from MED file
363 //=============================================================================
365 SMESH::DriverMED_ReadStatus
366 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
367 throw ( SALOME::SALOME_Exception )
369 Unexpect aCatch(SALOME_SalomeException);
372 status = _impl->MEDToMesh( theFileName, theMeshName );
374 catch( SALOME_Exception& S_ex ) {
375 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
378 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
381 CreateGroupServants();
383 int major, minor, release;
384 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
385 major = minor = release = -1;
386 _medFileInfo = new SALOME_MED::MedFileInfo();
387 _medFileInfo->fileName = theFileName;
388 _medFileInfo->fileSize = 0;
391 if ( ::_stati64( theFileName, &d ) != -1 )
394 if ( ::stat64( theFileName, &d ) != -1 )
396 _medFileInfo->fileSize = d.st_size;
397 _medFileInfo->major = major;
398 _medFileInfo->minor = minor;
399 _medFileInfo->release = release;
401 return ConvertDriverMEDReadStatus(status);
404 //================================================================================
406 * \brief Imports mesh data from the CGNS file
408 //================================================================================
410 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
411 const int theMeshIndex,
412 std::string& theMeshName )
413 throw ( SALOME::SALOME_Exception )
415 Unexpect aCatch(SALOME_SalomeException);
418 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
420 catch( SALOME_Exception& S_ex ) {
421 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
424 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
427 CreateGroupServants();
429 return ConvertDriverMEDReadStatus(status);
432 //================================================================================
434 * \brief Return string representation of a MED file version comprising nbDigits
436 //================================================================================
438 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
440 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
442 return CORBA::string_dup( ver.c_str() );
445 //=============================================================================
449 * Imports mesh data from MED file
451 //=============================================================================
453 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
454 throw ( SALOME::SALOME_Exception )
456 // Read mesh with name = <theMeshName> into SMESH_Mesh
457 _impl->UNVToMesh( theFileName );
459 CreateGroupServants();
464 //=============================================================================
468 * Imports mesh data from STL file
470 //=============================================================================
471 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
472 throw ( SALOME::SALOME_Exception )
474 // Read mesh with name = <theMeshName> into SMESH_Mesh
475 _impl->STLToMesh( theFileName );
480 //================================================================================
482 * \brief Imports data from a GMF file and returns an error description
484 //================================================================================
486 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
487 bool theMakeRequiredGroups )
488 throw (SALOME::SALOME_Exception)
490 SMESH_ComputeErrorPtr error;
492 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
494 catch ( std::bad_alloc& exc ) {
495 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "std::bad_alloc raised" );
497 catch ( Standard_OutOfMemory& exc ) {
498 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "Standard_OutOfMemory raised" );
500 catch (Standard_Failure& ex) {
501 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, ex.DynamicType()->Name() );
502 if ( ex.GetMessageString() && strlen( ex.GetMessageString() ))
503 error->myComment += string(": ") + ex.GetMessageString();
505 catch ( SALOME_Exception& S_ex ) {
506 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, S_ex.what() );
508 catch ( std::exception& exc ) {
509 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, exc.what() );
512 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "Unknown exception" );
515 CreateGroupServants();
517 return ConvertComputeError( error );
520 //=============================================================================
524 //=============================================================================
526 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
528 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
529 (SMESH_Hypothesis::Hypothesis_Status theStatus)
532 RETURNCASE( HYP_OK );
533 RETURNCASE( HYP_MISSING );
534 RETURNCASE( HYP_CONCURENT );
535 RETURNCASE( HYP_BAD_PARAMETER );
536 RETURNCASE( HYP_HIDDEN_ALGO );
537 RETURNCASE( HYP_HIDING_ALGO );
538 RETURNCASE( HYP_UNKNOWN_FATAL );
539 RETURNCASE( HYP_INCOMPATIBLE );
540 RETURNCASE( HYP_NOTCONFORM );
541 RETURNCASE( HYP_ALREADY_EXIST );
542 RETURNCASE( HYP_BAD_DIM );
543 RETURNCASE( HYP_BAD_SUBSHAPE );
544 RETURNCASE( HYP_BAD_GEOMETRY );
545 RETURNCASE( HYP_NEED_SHAPE );
548 return SMESH::HYP_UNKNOWN_FATAL;
551 //=============================================================================
555 * calls internal addHypothesis() and then adds a reference to <anHyp> under
556 * the SObject actually having a reference to <aSubShape>.
557 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
559 //=============================================================================
561 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
562 SMESH::SMESH_Hypothesis_ptr anHyp)
563 throw(SALOME::SALOME_Exception)
565 Unexpect aCatch(SALOME_SalomeException);
567 _preMeshInfo->ForgetOrLoad();
569 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
571 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
572 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
573 aSubShapeObject, anHyp );
575 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
577 // Update Python script
578 if(_impl->HasShapeToMesh()) {
579 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
580 << aSubShapeObject << ", " << anHyp << " )";
583 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
586 return ConvertHypothesisStatus(status);
589 //=============================================================================
593 //=============================================================================
595 SMESH_Hypothesis::Hypothesis_Status
596 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
597 SMESH::SMESH_Hypothesis_ptr anHyp)
599 if(MYDEBUG) MESSAGE("addHypothesis");
601 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
602 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
605 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
606 if (CORBA::is_nil(myHyp))
607 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
610 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
613 TopoDS_Shape myLocSubShape;
614 //use PseudoShape in case if mesh has no shape
616 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
618 myLocSubShape = _impl->GetShapeToMesh();
620 int hypId = myHyp->GetId();
621 status = _impl->AddHypothesis(myLocSubShape, hypId);
622 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
623 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
624 #ifdef WITHGENERICOBJ
625 _mapHypo[hypId]->Register();
627 // assure there is a corresponding submesh
628 if ( !_impl->IsMainShape( myLocSubShape )) {
629 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
630 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
631 createSubMesh( aSubShapeObject );
635 catch(SALOME_Exception & S_ex)
637 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
642 //=============================================================================
646 //=============================================================================
648 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
649 SMESH::SMESH_Hypothesis_ptr anHyp)
650 throw(SALOME::SALOME_Exception)
652 Unexpect aCatch(SALOME_SalomeException);
654 _preMeshInfo->ForgetOrLoad();
656 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
658 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
659 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
660 aSubShapeObject, anHyp );
662 // Update Python script
663 // Update Python script
664 if(_impl->HasShapeToMesh()) {
665 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
666 << aSubShapeObject << ", " << anHyp << " )";
669 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
673 return ConvertHypothesisStatus(status);
676 //=============================================================================
680 //=============================================================================
682 SMESH_Hypothesis::Hypothesis_Status
683 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
684 SMESH::SMESH_Hypothesis_ptr anHyp)
686 if(MYDEBUG) MESSAGE("removeHypothesis()");
687 // **** proposer liste de sub-shape (selection multiple)
689 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
690 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
692 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
693 if (CORBA::is_nil(myHyp))
694 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
696 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
699 TopoDS_Shape myLocSubShape;
700 //use PseudoShape in case if mesh has no shape
702 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
704 myLocSubShape = _impl->GetShapeToMesh();
706 int hypId = myHyp->GetId();
707 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
708 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
709 // _mapHypo.erase( hypId );
711 catch(SALOME_Exception & S_ex)
713 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
718 //=============================================================================
722 //=============================================================================
724 SMESH::ListOfHypothesis *
725 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
726 throw(SALOME::SALOME_Exception)
728 Unexpect aCatch(SALOME_SalomeException);
729 if (MYDEBUG) MESSAGE("GetHypothesisList");
730 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
731 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
733 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
736 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
737 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
738 myLocSubShape = _impl->GetShapeToMesh();
739 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
740 int i = 0, n = aLocalList.size();
743 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
744 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
745 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
746 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
751 catch(SALOME_Exception & S_ex) {
752 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
755 return aList._retn();
758 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
760 Unexpect aCatch(SALOME_SalomeException);
761 if (MYDEBUG) MESSAGE("GetSubMeshes");
763 SMESH::submesh_array_var aList = new SMESH::submesh_array();
766 TPythonDump aPythonDump;
767 if ( !_mapSubMeshIor.empty() )
771 aList->length( _mapSubMeshIor.size() );
773 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
774 for ( ; it != _mapSubMeshIor.end(); it++ ) {
775 if ( CORBA::is_nil( it->second )) continue;
776 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
778 if (i > 1) aPythonDump << ", ";
779 aPythonDump << it->second;
783 catch(SALOME_Exception & S_ex) {
784 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
787 // Update Python script
788 if ( !_mapSubMeshIor.empty() )
789 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
791 return aList._retn();
794 //=============================================================================
798 //=============================================================================
799 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
800 const char* theName )
801 throw(SALOME::SALOME_Exception)
803 Unexpect aCatch(SALOME_SalomeException);
804 MESSAGE("SMESH_Mesh_i::GetSubMesh");
805 if (CORBA::is_nil(aSubShapeObject))
806 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
809 SMESH::SMESH_subMesh_var subMesh;
810 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
812 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
814 //Get or Create the SMESH_subMesh object implementation
816 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
818 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
820 TopoDS_Iterator it( myLocSubShape );
822 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
824 subMesh = getSubMesh( subMeshId );
826 // create a new subMesh object servant if there is none for the shape
827 if ( subMesh->_is_nil() )
828 subMesh = createSubMesh( aSubShapeObject );
829 if ( _gen_i->CanPublishInStudy( subMesh )) {
830 SALOMEDS::SObject_var aSO =
831 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
832 subMesh, aSubShapeObject, theName );
833 if ( !aSO->_is_nil()) {
834 // Update Python script
835 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
836 << aSubShapeObject << ", '" << theName << "' )";
840 catch(SALOME_Exception & S_ex) {
841 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
843 return subMesh._retn();
846 //=============================================================================
850 //=============================================================================
852 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
853 throw (SALOME::SALOME_Exception)
855 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
856 if ( theSubMesh->_is_nil() )
859 GEOM::GEOM_Object_var aSubShapeObject;
860 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
861 if ( !aStudy->_is_nil() ) {
862 // Remove submesh's SObject
863 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
864 if ( !anSO->_is_nil() ) {
865 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
866 SALOMEDS::SObject_var anObj, aRef;
867 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
868 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
870 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
871 // aSubShapeObject = theSubMesh->GetSubShape();
873 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
875 // Update Python script
876 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
880 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
882 _preMeshInfo->ForgetOrLoad();
885 //=============================================================================
889 //=============================================================================
891 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
892 const char* theName )
893 throw(SALOME::SALOME_Exception)
895 Unexpect aCatch(SALOME_SalomeException);
897 _preMeshInfo->FullLoadFromFile();
899 SMESH::SMESH_Group_var aNewGroup =
900 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
902 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
903 SALOMEDS::SObject_var aSO =
904 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
905 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
906 if ( !aSO->_is_nil()) {
907 // Update Python script
908 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
909 << theElemType << ", '" << theName << "' )";
912 return aNewGroup._retn();
916 //=============================================================================
920 //=============================================================================
921 SMESH::SMESH_GroupOnGeom_ptr
922 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
924 GEOM::GEOM_Object_ptr theGeomObj)
925 throw(SALOME::SALOME_Exception)
927 Unexpect aCatch(SALOME_SalomeException);
929 _preMeshInfo->FullLoadFromFile();
931 SMESH::SMESH_GroupOnGeom_var aNewGroup;
933 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
934 if ( !aShape.IsNull() )
936 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
937 ( createGroup( theElemType, theName, aShape ));
939 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
940 SALOMEDS::SObject_var aSO =
941 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
942 aNewGroup, theGeomObj, theName);
943 if ( !aSO->_is_nil()) {
944 // Update Python script
945 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
946 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
951 return aNewGroup._retn();
954 //================================================================================
956 * \brief Creates a group whose contents is defined by filter
957 * \param theElemType - group type
958 * \param theName - group name
959 * \param theFilter - the filter
960 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
962 //================================================================================
964 SMESH::SMESH_GroupOnFilter_ptr
965 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
967 SMESH::Filter_ptr theFilter )
968 throw (SALOME::SALOME_Exception)
970 Unexpect aCatch(SALOME_SalomeException);
972 _preMeshInfo->FullLoadFromFile();
974 if ( CORBA::is_nil( theFilter ))
975 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
977 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
979 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
981 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
982 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
985 if ( !aNewGroup->_is_nil() )
986 aNewGroup->SetFilter( theFilter );
988 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
990 SALOMEDS::SObject_var aSO =
991 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
992 GEOM::GEOM_Object::_nil(), theName);
993 if ( !aSO->_is_nil()) {
994 // Update Python script
995 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
996 << theElemType << ", '" << theName << "', " << theFilter << " )";
1000 return aNewGroup._retn();
1003 //=============================================================================
1007 //=============================================================================
1009 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1010 throw (SALOME::SALOME_Exception)
1012 if ( theGroup->_is_nil() )
1015 SMESH_GroupBase_i* aGroup =
1016 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1020 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1021 if ( !aStudy->_is_nil() ) {
1022 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1024 if ( !aGroupSO->_is_nil() ) {
1025 // Update Python script
1026 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
1028 // Remove group's SObject
1029 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
1033 // Remove the group from SMESH data structures
1034 removeGroup( aGroup->GetLocalID() );
1037 //=============================================================================
1039 * Remove group with its contents
1041 //=============================================================================
1043 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1044 throw (SALOME::SALOME_Exception)
1047 _preMeshInfo->FullLoadFromFile();
1049 if ( theGroup->_is_nil() )
1052 SMESH_GroupBase_i* aGroup =
1053 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1057 SMESH::long_array_var anIds = aGroup->GetListOfID();
1058 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
1060 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
1063 if ( aGroup->GetType() == SMESH::NODE )
1064 aMeshEditor->RemoveNodes( anIds );
1066 aMeshEditor->RemoveElements( anIds );
1068 // Update Python script (theGroup must be alive for this)
1069 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
1072 RemoveGroup( theGroup );
1075 //================================================================================
1077 * \brief Get the list of groups existing in the mesh
1078 * \retval SMESH::ListOfGroups * - list of groups
1080 //================================================================================
1082 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1084 Unexpect aCatch(SALOME_SalomeException);
1085 if (MYDEBUG) MESSAGE("GetGroups");
1087 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1090 TPythonDump aPythonDump;
1091 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1092 aPythonDump << "[ ";
1095 aList->length( _mapGroups.size() );
1097 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1098 for ( ; it != _mapGroups.end(); it++ ) {
1099 if ( CORBA::is_nil( it->second )) continue;
1100 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1102 if (i > 1) aPythonDump << ", ";
1103 aPythonDump << it->second;
1107 catch(SALOME_Exception & S_ex) {
1108 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1111 // Update Python script
1112 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1113 aPythonDump << " ] = " << _this() << ".GetGroups()";
1115 return aList._retn();
1118 //=============================================================================
1120 * Get number of groups existing in the mesh
1122 //=============================================================================
1124 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1126 Unexpect aCatch(SALOME_SalomeException);
1127 return _mapGroups.size();
1130 //=============================================================================
1132 * New group is created. All mesh elements that are
1133 * present in initial groups are added to the new one
1135 //=============================================================================
1136 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1137 SMESH::SMESH_GroupBase_ptr theGroup2,
1138 const char* theName )
1139 throw (SALOME::SALOME_Exception)
1142 _preMeshInfo->FullLoadFromFile();
1146 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1147 theGroup1->GetType() != theGroup2->GetType() )
1148 return SMESH::SMESH_Group::_nil();
1151 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1152 if ( aResGrp->_is_nil() )
1153 return SMESH::SMESH_Group::_nil();
1155 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1156 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1158 TColStd_MapOfInteger aResMap;
1160 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1161 aResMap.Add( anIds1[ i1 ] );
1163 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1164 aResMap.Add( anIds2[ i2 ] );
1166 SMESH::long_array_var aResIds = new SMESH::long_array;
1167 aResIds->length( aResMap.Extent() );
1170 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1171 for( ; anIter.More(); anIter.Next() )
1172 aResIds[ resI++ ] = anIter.Key();
1174 aResGrp->Add( aResIds );
1176 // Clear python lines, created by CreateGroup() and Add()
1177 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1178 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1179 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1181 // Update Python script
1182 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
1183 << theGroup1 << ", " << theGroup2 << ", '"
1184 << theName << "' )";
1186 return aResGrp._retn();
1190 return SMESH::SMESH_Group::_nil();
1194 //=============================================================================
1196 \brief Union list of groups. New group is created. All mesh elements that are
1197 present in initial groups are added to the new one.
1198 \param theGroups list of groups
1199 \param theName name of group to be created
1200 \return pointer on the group
1202 //=============================================================================
1203 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1204 const char* theName )
1205 throw (SALOME::SALOME_Exception)
1208 _preMeshInfo->FullLoadFromFile();
1211 return SMESH::SMESH_Group::_nil();
1215 vector< int > anIds;
1216 SMESH::ElementType aType = SMESH::ALL;
1217 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1219 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1220 if ( CORBA::is_nil( aGrp ) )
1224 SMESH::ElementType aCurrType = aGrp->GetType();
1225 if ( aType == SMESH::ALL )
1229 if ( aType != aCurrType )
1230 return SMESH::SMESH_Group::_nil();
1234 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1235 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1237 int aCurrId = aCurrIds[ i ];
1238 anIds.push_back( aCurrId );
1243 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1244 if ( aResGrp->_is_nil() )
1245 return SMESH::SMESH_Group::_nil();
1247 // Create array of identifiers
1248 SMESH::long_array_var aResIds = new SMESH::long_array;
1249 aResIds->length( anIds.size() );
1251 //NCollection_Map< int >::Iterator anIter( anIds );
1252 for ( int i = 0; i<anIds.size(); i++ )
1254 aResIds[ i ] = anIds[i];
1256 aResGrp->Add( aResIds );
1258 // Clear python lines, created by CreateGroup() and Add()
1259 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1260 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1261 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1263 // Update Python script
1265 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1266 << &theGroups << ", '" << theName << "' )";
1268 return aResGrp._retn();
1272 return SMESH::SMESH_Group::_nil();
1276 //=============================================================================
1278 * New group is created. All mesh elements that are
1279 * present in both initial groups are added to the new one.
1281 //=============================================================================
1282 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1283 SMESH::SMESH_GroupBase_ptr theGroup2,
1284 const char* theName )
1285 throw (SALOME::SALOME_Exception)
1288 _preMeshInfo->FullLoadFromFile();
1290 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1291 theGroup1->GetType() != theGroup2->GetType() )
1292 return SMESH::SMESH_Group::_nil();
1294 // Create Intersection
1295 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1296 if ( aResGrp->_is_nil() )
1299 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1300 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1302 TColStd_MapOfInteger aMap1;
1304 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1305 aMap1.Add( anIds1[ i1 ] );
1307 TColStd_SequenceOfInteger aSeq;
1309 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1310 if ( aMap1.Contains( anIds2[ i2 ] ) )
1311 aSeq.Append( anIds2[ i2 ] );
1313 SMESH::long_array_var aResIds = new SMESH::long_array;
1314 aResIds->length( aSeq.Length() );
1316 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1317 aResIds[ resI ] = aSeq( resI + 1 );
1319 aResGrp->Add( aResIds );
1321 // Clear python lines, created by CreateGroup() and Add()
1322 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1323 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1324 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1326 // Update Python script
1327 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1328 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1330 return aResGrp._retn();
1333 //=============================================================================
1335 \brief Intersect list of groups. New group is created. All mesh elements that
1336 are present in all initial groups simultaneously are added to the new one.
1337 \param theGroups list of groups
1338 \param theName name of group to be created
1339 \return pointer on the group
1341 //=============================================================================
1342 SMESH::SMESH_Group_ptr
1343 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1344 const char* theName )
1345 throw (SALOME::SALOME_Exception)
1348 _preMeshInfo->FullLoadFromFile();
1351 return SMESH::SMESH_Group::_nil();
1355 NCollection_DataMap< int, int > anIdToCount;
1356 SMESH::ElementType aType = SMESH::ALL;
1357 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1359 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1360 if ( CORBA::is_nil( aGrp ) )
1364 SMESH::ElementType aCurrType = aGrp->GetType();
1365 if ( aType == SMESH::ALL )
1369 if ( aType != aCurrType )
1370 return SMESH::SMESH_Group::_nil();
1373 // calculates number of occurance ids in groups
1374 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1375 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1377 int aCurrId = aCurrIds[ i ];
1378 if ( !anIdToCount.IsBound( aCurrId ) )
1379 anIdToCount.Bind( aCurrId, 1 );
1381 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1385 // create map of ids
1386 int nbGrp = theGroups.length();
1387 vector< int > anIds;
1388 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1389 for ( ; anIter.More(); anIter.Next() )
1391 int aCurrId = anIter.Key();
1392 int aCurrNb = anIter.Value();
1393 if ( aCurrNb == nbGrp )
1394 anIds.push_back( aCurrId );
1398 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1399 if ( aResGrp->_is_nil() )
1400 return SMESH::SMESH_Group::_nil();
1402 // Create array of identifiers
1403 SMESH::long_array_var aResIds = new SMESH::long_array;
1404 aResIds->length( anIds.size() );
1406 //NCollection_Map< int >::Iterator aListIter( anIds );
1407 for ( int i = 0; i<anIds.size(); i++ )
1409 aResIds[ i ] = anIds[i];
1411 aResGrp->Add( aResIds );
1413 // Clear python lines, created by CreateGroup() and Add()
1414 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1415 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1416 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1418 // Update Python script
1420 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1421 << &theGroups << ", '" << theName << "' )";
1423 return aResGrp._retn();
1427 return SMESH::SMESH_Group::_nil();
1431 //=============================================================================
1433 * New group is created. All mesh elements that are present in
1434 * main group but do not present in tool group are added to the new one
1436 //=============================================================================
1437 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1438 SMESH::SMESH_GroupBase_ptr theGroup2,
1439 const char* theName )
1440 throw (SALOME::SALOME_Exception)
1443 _preMeshInfo->FullLoadFromFile();
1445 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1446 theGroup1->GetType() != theGroup2->GetType() )
1447 return SMESH::SMESH_Group::_nil();
1450 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1451 if ( aResGrp->_is_nil() )
1454 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1455 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1457 TColStd_MapOfInteger aMap2;
1459 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1460 aMap2.Add( anIds2[ i2 ] );
1462 TColStd_SequenceOfInteger aSeq;
1463 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1464 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1465 aSeq.Append( anIds1[ i1 ] );
1467 SMESH::long_array_var aResIds = new SMESH::long_array;
1468 aResIds->length( aSeq.Length() );
1470 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1471 aResIds[ resI ] = aSeq( resI + 1 );
1473 aResGrp->Add( aResIds );
1475 // Clear python lines, created by CreateGroup() and Add()
1476 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1477 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1478 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1480 // Update Python script
1481 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1482 << theGroup1 << ", " << theGroup2 << ", '"
1483 << theName << "' )";
1485 return aResGrp._retn();
1488 //=============================================================================
1490 \brief Cut lists of groups. New group is created. All mesh elements that are
1491 present in main groups but do not present in tool groups are added to the new one
1492 \param theMainGroups list of main groups
1493 \param theToolGroups list of tool groups
1494 \param theName name of group to be created
1495 \return pointer on the group
1497 //=============================================================================
1498 SMESH::SMESH_Group_ptr
1499 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1500 const SMESH::ListOfGroups& theToolGroups,
1501 const char* theName )
1502 throw (SALOME::SALOME_Exception)
1505 _preMeshInfo->FullLoadFromFile();
1508 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 );
1571 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1572 if ( aResGrp->_is_nil() )
1573 return SMESH::SMESH_Group::_nil();
1575 // Create array of identifiers
1576 SMESH::long_array_var aResIds = new SMESH::long_array;
1577 aResIds->length( anIds.size() );
1579 for (int i=0; i<anIds.size(); i++ )
1581 aResIds[ i ] = anIds[i];
1583 aResGrp->Add( aResIds );
1585 // Clear python lines, created by CreateGroup() and Add()
1586 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1587 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1588 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1590 // Update Python script
1592 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1593 << &theMainGroups << ", " << &theToolGroups << ", '"
1594 << theName << "' )";
1596 return aResGrp._retn();
1600 return SMESH::SMESH_Group::_nil();
1604 //=============================================================================
1606 \brief Create groups of entities from existing groups of superior dimensions
1608 1) extract all nodes from each group,
1609 2) combine all elements of specified dimension laying on these nodes.
1610 \param theGroups list of source groups
1611 \param theElemType dimension of elements
1612 \param theName name of new group
1613 \return pointer on new group
1615 //=============================================================================
1616 SMESH::SMESH_Group_ptr
1617 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1618 SMESH::ElementType theElemType,
1619 const char* theName )
1620 throw (SALOME::SALOME_Exception)
1623 _preMeshInfo->FullLoadFromFile();
1625 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1627 if ( !theName || !aMeshDS )
1628 return SMESH::SMESH_Group::_nil();
1630 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1634 // Create map of nodes from all groups
1636 set< int > aNodeMap;
1638 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1640 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1641 if ( CORBA::is_nil( aGrp ) )
1644 SMESH::ElementType aType = aGrp->GetType();
1645 if ( aType == SMESH::ALL )
1647 else if ( aType == SMESH::NODE )
1649 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1650 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1652 int aCurrId = aCurrIds[ i ];
1653 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1655 aNodeMap.insert( aNode->GetID() );
1660 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1661 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1663 int aCurrId = aCurrIds[ i ];
1664 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1667 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1668 while( aNodeIter->more() )
1670 const SMDS_MeshNode* aNode =
1671 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1673 aNodeMap.insert( aNode->GetID() );
1679 // Get result identifiers
1681 vector< int > aResultIds;
1682 if ( theElemType == SMESH::NODE )
1684 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1685 set<int>::iterator iter = aNodeMap.begin();
1686 for ( ; iter != aNodeMap.end(); iter++ )
1687 aResultIds.push_back( *iter);
1691 // Create list of elements of given dimension constructed on the nodes
1692 vector< int > anElemList;
1693 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1694 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1695 set<int>::iterator iter = aNodeMap.begin();
1696 for ( ; iter != aNodeMap.end(); iter++ )
1698 const SMDS_MeshElement* aNode =
1699 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1703 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1704 while( anElemIter->more() )
1706 const SMDS_MeshElement* anElem =
1707 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1708 if ( anElem && anElem->GetType() == anElemType )
1709 anElemList.push_back( anElem->GetID() );
1713 // check whether all nodes of elements are present in nodes map
1714 for (int i=0; i< anElemList.size(); i++)
1716 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1721 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1722 while( aNodeIter->more() )
1724 const SMDS_MeshNode* aNode =
1725 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1726 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1733 aResultIds.push_back( anElem->GetID() );
1739 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1740 if ( aResGrp->_is_nil() )
1741 return SMESH::SMESH_Group::_nil();
1743 // Create array of identifiers
1744 SMESH::long_array_var aResIds = new SMESH::long_array;
1745 aResIds->length( aResultIds.size() );
1747 for (int i=0; i< aResultIds.size(); i++)
1748 aResIds[ i ] = aResultIds[i];
1749 aResGrp->Add( aResIds );
1751 // Remove strings corresponding to group creation
1752 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1753 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1754 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1756 // Update Python script
1758 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1759 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1761 return aResGrp._retn();
1765 return SMESH::SMESH_Group::_nil();
1769 //================================================================================
1771 * \brief Remember GEOM group data
1773 //================================================================================
1775 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1776 CORBA::Object_ptr theSmeshObj)
1778 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1781 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1782 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1783 if ( groupSO->_is_nil() )
1786 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1787 GEOM::GEOM_IGroupOperations_var groupOp =
1788 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1789 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1792 _geomGroupData.push_back( TGeomGroupData() );
1793 TGeomGroupData & groupData = _geomGroupData.back();
1795 CORBA::String_var entry = groupSO->GetID();
1796 groupData._groupEntry = entry.in();
1798 for ( int i = 0; i < ids->length(); ++i )
1799 groupData._indices.insert( ids[i] );
1801 groupData._smeshObject = theSmeshObj;
1804 //================================================================================
1806 * Remove GEOM group data relating to removed smesh object
1808 //================================================================================
1810 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1812 list<TGeomGroupData>::iterator
1813 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1814 for ( ; data != dataEnd; ++data ) {
1815 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1816 _geomGroupData.erase( data );
1822 //================================================================================
1824 * \brief Return new group contents if it has been changed and update group data
1826 //================================================================================
1828 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1830 TopoDS_Shape newShape;
1833 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1834 if ( study->_is_nil() ) return newShape; // means "not changed"
1835 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1836 if ( !groupSO->_is_nil() )
1838 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1839 if ( CORBA::is_nil( groupObj )) return newShape;
1840 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1842 // get indices of group items
1843 set<int> curIndices;
1844 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1845 GEOM::GEOM_IGroupOperations_var groupOp =
1846 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1847 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1848 for ( int i = 0; i < ids->length(); ++i )
1849 curIndices.insert( ids[i] );
1851 if ( groupData._indices == curIndices )
1852 return newShape; // group not changed
1855 groupData._indices = curIndices;
1857 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1858 if ( !geomClient ) return newShape;
1859 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1860 geomClient->RemoveShapeFromBuffer( groupIOR );
1861 newShape = _gen_i->GeomObjectToShape( geomGroup );
1864 if ( newShape.IsNull() ) {
1865 // geom group becomes empty - return empty compound
1866 TopoDS_Compound compound;
1867 BRep_Builder().MakeCompound(compound);
1868 newShape = compound;
1875 //=============================================================================
1877 * \brief Storage of shape and index used in CheckGeomGroupModif()
1879 //=============================================================================
1880 struct TIndexedShape
1883 TopoDS_Shape _shape;
1884 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1887 //=============================================================================
1889 * \brief Update objects depending on changed geom groups
1891 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1892 * issue 0020210: Update of a smesh group after modification of the associated geom group
1894 //=============================================================================
1896 void SMESH_Mesh_i::CheckGeomGroupModif()
1898 if ( !_impl->HasShapeToMesh() ) return;
1900 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1901 if ( study->_is_nil() ) return;
1903 CORBA::Long nbEntities = NbNodes() + NbElements();
1905 // Check if group contents changed
1907 typedef map< string, TopoDS_Shape > TEntry2Geom;
1908 TEntry2Geom newGroupContents;
1910 list<TGeomGroupData>::iterator
1911 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1912 for ( ; data != dataEnd; ++data )
1914 pair< TEntry2Geom::iterator, bool > it_new =
1915 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1916 bool processedGroup = !it_new.second;
1917 TopoDS_Shape& newShape = it_new.first->second;
1918 if ( !processedGroup )
1919 newShape = newGroupShape( *data );
1920 if ( newShape.IsNull() )
1921 continue; // no changes
1924 _preMeshInfo->ForgetOrLoad();
1926 if ( processedGroup ) { // update group indices
1927 list<TGeomGroupData>::iterator data2 = data;
1928 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1929 data->_indices = data2->_indices;
1932 // Update SMESH objects according to new GEOM group contents
1934 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1935 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1937 int oldID = submesh->GetId();
1938 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1940 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1942 // update hypotheses
1943 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1944 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1945 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1947 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1948 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1950 // care of submeshes
1951 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1952 int newID = newSubmesh->GetId();
1953 if ( newID != oldID ) {
1954 _mapSubMesh [ newID ] = newSubmesh;
1955 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1956 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1957 _mapSubMesh. erase(oldID);
1958 _mapSubMesh_i. erase(oldID);
1959 _mapSubMeshIor.erase(oldID);
1960 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1965 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1966 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1967 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1969 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1971 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1972 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1973 ds->SetShape( newShape );
1978 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1979 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1981 // Remove groups and submeshes basing on removed sub-shapes
1983 TopTools_MapOfShape newShapeMap;
1984 TopoDS_Iterator shapeIt( newShape );
1985 for ( ; shapeIt.More(); shapeIt.Next() )
1986 newShapeMap.Add( shapeIt.Value() );
1988 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1989 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1991 if ( newShapeMap.Contains( shapeIt.Value() ))
1993 TopTools_IndexedMapOfShape oldShapeMap;
1994 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1995 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1997 const TopoDS_Shape& oldShape = oldShapeMap(i);
1998 int oldInd = meshDS->ShapeToIndex( oldShape );
2000 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2001 if ( i_smIor != _mapSubMeshIor.end() ) {
2002 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2005 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2006 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2008 // check if a group bases on oldInd shape
2009 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2010 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2011 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2012 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2014 RemoveGroup( i_grp->second ); // several groups can base on same shape
2015 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2020 // Reassign hypotheses and update groups after setting the new shape to mesh
2022 // collect anassigned hypotheses
2023 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2024 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2025 TShapeHypList assignedHyps;
2026 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2028 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2029 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2030 if ( !hyps.empty() ) {
2031 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2032 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2033 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2036 // collect shapes supporting groups
2037 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2038 TShapeTypeList groupData;
2039 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2040 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2041 for ( ; grIt != groups.end(); ++grIt )
2043 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2045 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2047 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2048 _impl->ShapeToMesh( newShape );
2050 // reassign hypotheses
2051 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2052 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2054 TIndexedShape& geom = indS_hyps->first;
2055 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2056 int oldID = geom._index;
2057 int newID = meshDS->ShapeToIndex( geom._shape );
2060 if ( oldID == 1 ) { // main shape
2062 geom._shape = newShape;
2064 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2065 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2066 // care of submeshes
2067 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2068 if ( newID != oldID ) {
2069 _mapSubMesh [ newID ] = newSubmesh;
2070 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2071 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2072 _mapSubMesh. erase(oldID);
2073 _mapSubMesh_i. erase(oldID);
2074 _mapSubMeshIor.erase(oldID);
2075 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2079 TShapeTypeList::iterator geomType = groupData.begin();
2080 for ( ; geomType != groupData.end(); ++geomType )
2082 const TIndexedShape& geom = geomType->first;
2083 int oldID = geom._index;
2084 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2087 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2088 CORBA::String_var name = groupSO->GetName();
2090 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2092 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2093 group_i->changeLocalId( newID );
2096 break; // everything has been updated
2099 } // loop on group data
2103 CORBA::Long newNbEntities = NbNodes() + NbElements();
2104 list< SALOMEDS::SObject_var > soToUpdateIcons;
2105 if ( newNbEntities != nbEntities )
2107 // Add all SObjects with icons to soToUpdateIcons
2108 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2110 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2111 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2112 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2114 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2115 i_gr != _mapGroups.end(); ++i_gr ) // groups
2116 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2119 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
2120 for ( ; so != soToUpdateIcons.end(); ++so )
2121 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2124 //=============================================================================
2126 * \brief Create standalone group from a group on geometry or filter
2128 //=============================================================================
2130 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2133 _preMeshInfo->FullLoadFromFile();
2135 SMESH::SMESH_Group_var aGroup;
2136 if ( theGroup->_is_nil() )
2137 return aGroup._retn();
2139 Unexpect aCatch(SALOME_SalomeException);
2141 SMESH_GroupBase_i* aGroupToRem =
2142 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2144 return aGroup._retn();
2146 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2148 int anId = aGroupToRem->GetLocalID();
2149 if ( !_impl->ConvertToStandalone( anId ) )
2150 return aGroup._retn();
2151 removeGeomGroupData( theGroup );
2153 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2155 // remove old instance of group from own map
2156 _mapGroups.erase( anId );
2158 SALOMEDS::StudyBuilder_var builder;
2159 SALOMEDS::SObject_var aGroupSO;
2160 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2161 if ( !aStudy->_is_nil() ) {
2162 builder = aStudy->NewBuilder();
2163 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2164 if ( !aGroupSO->_is_nil() ) {
2166 // remove reference to geometry
2167 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
2168 for ( ; chItr->More(); chItr->Next() )
2169 // Remove group's child SObject
2170 builder->RemoveObject( chItr->Value() );
2172 // Update Python script
2173 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2174 << aGroupSO << " )";
2176 // change icon of Group on Filter
2179 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2180 const int isEmpty = ( elemTypes->length() == 0 );
2183 SALOMEDS::GenericAttribute_var anAttr =
2184 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2185 SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
2186 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2192 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2193 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2194 aGroupImpl->Register();
2195 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2197 // remember new group in own map
2198 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2199 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2201 // register CORBA object for persistence
2202 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
2204 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
2206 return aGroup._retn();
2209 //=============================================================================
2213 //=============================================================================
2215 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2217 if(MYDEBUG) MESSAGE( "createSubMesh" );
2218 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2220 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2221 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2222 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2223 SMESH::SMESH_subMesh_var subMesh
2224 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2226 _mapSubMesh[subMeshId] = mySubMesh;
2227 _mapSubMesh_i[subMeshId] = subMeshServant;
2228 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2230 // register CORBA object for persistence
2231 int nextId = _gen_i->RegisterObject( subMesh );
2232 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2234 // to track changes of GEOM groups
2235 addGeomGroupData( theSubShapeObject, subMesh );
2237 return subMesh._retn();
2240 //=======================================================================
2241 //function : getSubMesh
2243 //=======================================================================
2245 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2247 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2248 if ( it == _mapSubMeshIor.end() )
2249 return SMESH::SMESH_subMesh::_nil();
2251 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2255 //=============================================================================
2259 //=============================================================================
2261 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2262 GEOM::GEOM_Object_ptr theSubShapeObject )
2264 bool isHypChanged = false;
2265 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2266 return isHypChanged;
2268 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2270 CORBA::Long shapeId = theSubMesh->GetId();
2271 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2273 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2276 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2277 isHypChanged = !hyps.empty();
2278 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2279 for ( ; hyp != hyps.end(); ++hyp )
2280 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2287 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2288 isHypChanged = ( aHypList->length() > 0 );
2289 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2290 removeHypothesis( theSubShapeObject, aHypList[i] );
2293 catch( const SALOME::SALOME_Exception& ) {
2294 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2296 removeGeomGroupData( theSubShapeObject );
2298 int subMeshId = theSubMesh->GetId();
2300 _mapSubMesh.erase(subMeshId);
2301 _mapSubMesh_i.erase(subMeshId);
2302 _mapSubMeshIor.erase(subMeshId);
2304 return isHypChanged;
2307 //=============================================================================
2311 //=============================================================================
2313 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2314 const char* theName,
2315 const TopoDS_Shape& theShape,
2316 const SMESH_PredicatePtr& thePredicate )
2318 std::string newName;
2319 if ( !theName || strlen( theName ) == 0 )
2321 std::set< std::string > presentNames;
2322 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2323 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2324 presentNames.insert( i_gr->second->GetName() );
2326 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2327 } while ( !presentNames.insert( newName ).second );
2328 theName = newName.c_str();
2331 SMESH::SMESH_GroupBase_var aGroup;
2332 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2334 SMESH_GroupBase_i* aGroupImpl;
2335 if ( !theShape.IsNull() )
2336 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2337 else if ( thePredicate )
2338 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2340 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2342 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2343 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2344 aGroupImpl->Register();
2345 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2347 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2348 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2350 // register CORBA object for persistence
2351 int nextId = _gen_i->RegisterObject( aGroup );
2352 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2354 // to track changes of GEOM groups
2355 if ( !theShape.IsNull() ) {
2356 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2357 addGeomGroupData( geom, aGroup );
2360 return aGroup._retn();
2363 //=============================================================================
2365 * SMESH_Mesh_i::removeGroup
2367 * Should be called by ~SMESH_Group_i()
2369 //=============================================================================
2371 void SMESH_Mesh_i::removeGroup( const int theId )
2373 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2374 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2375 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2376 _mapGroups.erase( theId );
2377 removeGeomGroupData( group );
2378 if (! _impl->RemoveGroup( theId ))
2380 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2381 RemoveGroup( group );
2386 //=============================================================================
2390 //=============================================================================
2392 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2393 throw(SALOME::SALOME_Exception)
2396 _preMeshInfo->FullLoadFromFile();
2398 SMESH::log_array_var aLog;
2400 list < SMESHDS_Command * >logDS = _impl->GetLog();
2401 aLog = new SMESH::log_array;
2403 int lg = logDS.size();
2406 list < SMESHDS_Command * >::iterator its = logDS.begin();
2407 while(its != logDS.end()){
2408 SMESHDS_Command *com = *its;
2409 int comType = com->GetType();
2411 int lgcom = com->GetNumber();
2413 const list < int >&intList = com->GetIndexes();
2414 int inum = intList.size();
2416 list < int >::const_iterator ii = intList.begin();
2417 const list < double >&coordList = com->GetCoords();
2418 int rnum = coordList.size();
2420 list < double >::const_iterator ir = coordList.begin();
2421 aLog[indexLog].commandType = comType;
2422 aLog[indexLog].number = lgcom;
2423 aLog[indexLog].coords.length(rnum);
2424 aLog[indexLog].indexes.length(inum);
2425 for(int i = 0; i < rnum; i++){
2426 aLog[indexLog].coords[i] = *ir;
2427 //MESSAGE(" "<<i<<" "<<ir.Value());
2430 for(int i = 0; i < inum; i++){
2431 aLog[indexLog].indexes[i] = *ii;
2432 //MESSAGE(" "<<i<<" "<<ii.Value());
2441 catch(SALOME_Exception & S_ex){
2442 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2444 return aLog._retn();
2448 //=============================================================================
2452 //=============================================================================
2454 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2456 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2460 //=============================================================================
2464 //=============================================================================
2466 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2468 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2472 //=============================================================================
2476 //=============================================================================
2478 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2483 //=============================================================================
2486 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2487 // issue 0020918: groups removal is caused by hyp modification
2488 // issue 0021208: to forget not loaded mesh data at hyp modification
2489 struct TCallUp_i : public SMESH_Mesh::TCallUp
2491 SMESH_Mesh_i* _mesh;
2492 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2493 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2494 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2495 virtual void Load () { _mesh->Load(); }
2499 //================================================================================
2501 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2503 //================================================================================
2505 void SMESH_Mesh_i::onHypothesisModified()
2508 _preMeshInfo->ForgetOrLoad();
2511 //=============================================================================
2515 //=============================================================================
2517 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2519 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2522 _impl->SetCallUp( new TCallUp_i(this));
2525 //=============================================================================
2529 //=============================================================================
2531 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2533 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2537 //=============================================================================
2539 * Return mesh editor
2541 //=============================================================================
2543 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2546 _preMeshInfo->FullLoadFromFile();
2548 // Create MeshEditor
2549 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2550 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2552 // Update Python script
2553 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2555 return aMesh._retn();
2558 //=============================================================================
2560 * Return mesh edition previewer
2562 //=============================================================================
2564 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2567 _preMeshInfo->FullLoadFromFile();
2569 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2570 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2571 return aMesh._retn();
2574 //================================================================================
2576 * \brief Return true if the mesh has been edited since a last total re-compute
2577 * and those modifications may prevent successful partial re-compute
2579 //================================================================================
2581 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2583 Unexpect aCatch(SALOME_SalomeException);
2584 return _impl->HasModificationsToDiscard();
2587 //================================================================================
2589 * \brief Returns a random unique color
2591 //================================================================================
2593 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2595 const int MAX_ATTEMPTS = 100;
2597 double tolerance = 0.5;
2598 SALOMEDS::Color col;
2602 // generate random color
2603 double red = (double)rand() / RAND_MAX;
2604 double green = (double)rand() / RAND_MAX;
2605 double blue = (double)rand() / RAND_MAX;
2606 // check existence in the list of the existing colors
2607 bool matched = false;
2608 std::list<SALOMEDS::Color>::const_iterator it;
2609 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2610 SALOMEDS::Color color = *it;
2611 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2612 matched = tol < tolerance;
2614 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2615 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2623 //=============================================================================
2625 * Sets auto-color mode. If it is on, groups get unique random colors
2627 //=============================================================================
2629 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2631 Unexpect aCatch(SALOME_SalomeException);
2632 _impl->SetAutoColor(theAutoColor);
2634 TPythonDump pyDump; // not to dump group->SetColor() from below code
2635 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2637 std::list<SALOMEDS::Color> aReservedColors;
2638 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2639 for ( ; it != _mapGroups.end(); it++ ) {
2640 if ( CORBA::is_nil( it->second )) continue;
2641 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2642 it->second->SetColor( aColor );
2643 aReservedColors.push_back( aColor );
2647 //=============================================================================
2649 * Returns true if auto-color mode is on
2651 //=============================================================================
2653 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2655 Unexpect aCatch(SALOME_SalomeException);
2656 return _impl->GetAutoColor();
2659 //=============================================================================
2661 * Checks if there are groups with equal names
2663 //=============================================================================
2665 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2667 return _impl->HasDuplicatedGroupNamesMED();
2670 //================================================================================
2672 * \brief Care of a file before exporting mesh into it
2674 //================================================================================
2676 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2678 TCollection_AsciiString aFullName ((char*)file);
2679 OSD_Path aPath (aFullName);
2680 OSD_File aFile (aPath);
2681 if (aFile.Exists()) {
2682 // existing filesystem node
2683 if (aFile.KindOfFile() == OSD_FILE) {
2684 if (aFile.IsWriteable()) {
2689 if (aFile.Failed()) {
2690 TCollection_AsciiString msg ("File ");
2691 msg += aFullName + " cannot be replaced.";
2692 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2695 TCollection_AsciiString msg ("File ");
2696 msg += aFullName + " cannot be overwritten.";
2697 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2700 TCollection_AsciiString msg ("Location ");
2701 msg += aFullName + " is not a file.";
2702 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2705 // nonexisting file; check if it can be created
2707 aFile.Build(OSD_WriteOnly, OSD_Protection());
2708 if (aFile.Failed()) {
2709 TCollection_AsciiString msg ("You cannot create the file ");
2710 msg += aFullName + ". Check the directory existance and access rights.";
2711 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2719 //================================================================================
2721 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2722 * \param file - file name
2723 * \param overwrite - to erase the file or not
2724 * \retval string - mesh name
2726 //================================================================================
2728 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2729 CORBA::Boolean overwrite)
2732 PrepareForWriting(file, overwrite);
2733 string aMeshName = "Mesh";
2734 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2735 if ( !aStudy->_is_nil() ) {
2736 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2737 if ( !aMeshSO->_is_nil() ) {
2738 CORBA::String_var name = aMeshSO->GetName();
2740 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2741 if ( !aStudy->GetProperties()->IsLocked() )
2743 SALOMEDS::GenericAttribute_var anAttr;
2744 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2745 SALOMEDS::AttributeExternalFileDef_var aFileName;
2746 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2747 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2748 ASSERT(!aFileName->_is_nil());
2749 aFileName->SetValue(file);
2750 SALOMEDS::AttributeFileType_var aFileType;
2751 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2752 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2753 ASSERT(!aFileType->_is_nil());
2754 aFileType->SetValue("FICHIERMED");
2758 // Update Python script
2759 // set name of mesh before export
2760 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2762 // check names of groups
2768 //================================================================================
2770 * \brief Export to med file
2772 //================================================================================
2774 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2775 CORBA::Boolean auto_groups,
2776 SMESH::MED_VERSION theVersion,
2777 CORBA::Boolean overwrite)
2778 throw(SALOME::SALOME_Exception)
2780 Unexpect aCatch(SALOME_SalomeException);
2782 _preMeshInfo->FullLoadFromFile();
2784 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2785 TPythonDump() << _this() << ".ExportToMEDX( r'"
2786 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2788 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2791 //================================================================================
2793 * \brief Export a mesh to a med file
2795 //================================================================================
2797 void SMESH_Mesh_i::ExportToMED (const char* file,
2798 CORBA::Boolean auto_groups,
2799 SMESH::MED_VERSION theVersion)
2800 throw(SALOME::SALOME_Exception)
2802 ExportToMEDX(file,auto_groups,theVersion,true);
2805 //================================================================================
2807 * \brief Export a mesh to a med file
2809 //================================================================================
2811 void SMESH_Mesh_i::ExportMED (const char* file,
2812 CORBA::Boolean auto_groups)
2813 throw(SALOME::SALOME_Exception)
2815 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2818 //================================================================================
2820 * \brief Export a mesh to a SAUV file
2822 //================================================================================
2824 void SMESH_Mesh_i::ExportSAUV (const char* file,
2825 CORBA::Boolean auto_groups)
2826 throw(SALOME::SALOME_Exception)
2828 Unexpect aCatch(SALOME_SalomeException);
2830 _preMeshInfo->FullLoadFromFile();
2832 string aMeshName = prepareMeshNameAndGroups(file, true);
2833 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2834 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2838 //================================================================================
2840 * \brief Export a mesh to a DAT file
2842 //================================================================================
2844 void SMESH_Mesh_i::ExportDAT (const char *file)
2845 throw(SALOME::SALOME_Exception)
2847 Unexpect aCatch(SALOME_SalomeException);
2849 _preMeshInfo->FullLoadFromFile();
2851 // Update Python script
2852 // check names of groups
2854 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2857 PrepareForWriting(file);
2858 _impl->ExportDAT(file);
2861 //================================================================================
2863 * \brief Export a mesh to an UNV file
2865 //================================================================================
2867 void SMESH_Mesh_i::ExportUNV (const char *file)
2868 throw(SALOME::SALOME_Exception)
2870 Unexpect aCatch(SALOME_SalomeException);
2872 _preMeshInfo->FullLoadFromFile();
2874 // Update Python script
2875 // check names of groups
2877 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2880 PrepareForWriting(file);
2881 _impl->ExportUNV(file);
2884 //================================================================================
2886 * \brief Export a mesh to an STL file
2888 //================================================================================
2890 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2891 throw(SALOME::SALOME_Exception)
2893 Unexpect aCatch(SALOME_SalomeException);
2895 _preMeshInfo->FullLoadFromFile();
2897 // Update Python script
2898 // check names of groups
2900 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2903 PrepareForWriting(file);
2904 _impl->ExportSTL(file, isascii);
2907 //================================================================================
2909 * \brief Export a part of mesh to a med file
2911 //================================================================================
2913 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2915 CORBA::Boolean auto_groups,
2916 ::SMESH::MED_VERSION version,
2917 ::CORBA::Boolean overwrite)
2918 throw (SALOME::SALOME_Exception)
2920 Unexpect aCatch(SALOME_SalomeException);
2922 _preMeshInfo->FullLoadFromFile();
2924 PrepareForWriting(file, overwrite);
2926 string aMeshName = "Mesh";
2927 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2928 if ( !aStudy->_is_nil() ) {
2929 SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2930 if ( !SO->_is_nil() ) {
2931 CORBA::String_var name = SO->GetName();
2935 SMESH_MeshPartDS partDS( meshPart );
2936 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2938 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2939 << auto_groups << ", " << version << ", " << overwrite << " )";
2942 //================================================================================
2944 * \brief Export a part of mesh to a DAT file
2946 //================================================================================
2948 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2950 throw (SALOME::SALOME_Exception)
2952 Unexpect aCatch(SALOME_SalomeException);
2954 _preMeshInfo->FullLoadFromFile();
2956 PrepareForWriting(file);
2958 SMESH_MeshPartDS partDS( meshPart );
2959 _impl->ExportDAT(file,&partDS);
2961 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2963 //================================================================================
2965 * \brief Export a part of mesh to an UNV file
2967 //================================================================================
2969 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2971 throw (SALOME::SALOME_Exception)
2973 Unexpect aCatch(SALOME_SalomeException);
2975 _preMeshInfo->FullLoadFromFile();
2977 PrepareForWriting(file);
2979 SMESH_MeshPartDS partDS( meshPart );
2980 _impl->ExportUNV(file, &partDS);
2982 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2984 //================================================================================
2986 * \brief Export a part of mesh to an STL file
2988 //================================================================================
2990 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2992 ::CORBA::Boolean isascii)
2993 throw (SALOME::SALOME_Exception)
2995 Unexpect aCatch(SALOME_SalomeException);
2997 _preMeshInfo->FullLoadFromFile();
2999 PrepareForWriting(file);
3001 SMESH_MeshPartDS partDS( meshPart );
3002 _impl->ExportSTL(file, isascii, &partDS);
3004 TPythonDump() << _this() << ".ExportPartToSTL( "
3005 << meshPart<< ", r'" << file << "', " << isascii << ")";
3008 //================================================================================
3010 * \brief Export a part of mesh to an STL file
3012 //================================================================================
3014 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3016 CORBA::Boolean overwrite)
3017 throw (SALOME::SALOME_Exception)
3020 Unexpect aCatch(SALOME_SalomeException);
3022 _preMeshInfo->FullLoadFromFile();
3024 PrepareForWriting(file,overwrite);
3026 SMESH_MeshPartDS partDS( meshPart );
3027 _impl->ExportCGNS(file, &partDS);
3029 TPythonDump() << _this() << ".ExportCGNS( "
3030 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3032 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3036 //================================================================================
3038 * \brief Export a part of mesh to a GMF file
3040 //================================================================================
3042 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3044 bool withRequiredGroups)
3045 throw (SALOME::SALOME_Exception)
3047 Unexpect aCatch(SALOME_SalomeException);
3049 _preMeshInfo->FullLoadFromFile();
3051 PrepareForWriting(file,/*overwrite=*/true);
3053 SMESH_MeshPartDS partDS( meshPart );
3054 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3056 TPythonDump() << _this() << ".ExportGMF( "
3057 << meshPart<< ", r'"
3059 << withRequiredGroups << ")";
3062 //=============================================================================
3064 * Return implementation of SALOME_MED::MESH interfaces
3066 //=============================================================================
3068 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
3070 Unexpect aCatch(SALOME_SalomeException);
3072 _preMeshInfo->FullLoadFromFile();
3074 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
3075 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
3076 return aMesh._retn();
3079 //=============================================================================
3081 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3083 Unexpect aCatch(SALOME_SalomeException);
3085 return _preMeshInfo->NbNodes();
3087 return _impl->NbNodes();
3090 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3092 Unexpect aCatch(SALOME_SalomeException);
3094 return _preMeshInfo->NbElements();
3096 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3099 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3101 Unexpect aCatch(SALOME_SalomeException);
3103 return _preMeshInfo->Nb0DElements();
3105 return _impl->Nb0DElements();
3108 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3110 Unexpect aCatch(SALOME_SalomeException);
3112 return _preMeshInfo->NbBalls();
3114 return _impl->NbBalls();
3117 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3119 Unexpect aCatch(SALOME_SalomeException);
3121 return _preMeshInfo->NbEdges();
3123 return _impl->NbEdges();
3126 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3127 throw(SALOME::SALOME_Exception)
3129 Unexpect aCatch(SALOME_SalomeException);
3131 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3133 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3136 //=============================================================================
3138 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3140 Unexpect aCatch(SALOME_SalomeException);
3142 return _preMeshInfo->NbFaces();
3144 return _impl->NbFaces();
3147 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3149 Unexpect aCatch(SALOME_SalomeException);
3151 return _preMeshInfo->NbTriangles();
3153 return _impl->NbTriangles();
3156 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3158 Unexpect aCatch(SALOME_SalomeException);
3160 return _preMeshInfo->NbQuadrangles();
3162 return _impl->NbQuadrangles();
3165 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3167 Unexpect aCatch(SALOME_SalomeException);
3169 return _preMeshInfo->NbBiQuadQuadrangles();
3171 return _impl->NbBiQuadQuadrangles();
3174 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3176 Unexpect aCatch(SALOME_SalomeException);
3178 return _preMeshInfo->NbPolygons();
3180 return _impl->NbPolygons();
3183 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3184 throw(SALOME::SALOME_Exception)
3186 Unexpect aCatch(SALOME_SalomeException);
3188 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3190 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3193 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3194 throw(SALOME::SALOME_Exception)
3196 Unexpect aCatch(SALOME_SalomeException);
3198 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3200 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3203 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3204 throw(SALOME::SALOME_Exception)
3206 Unexpect aCatch(SALOME_SalomeException);
3208 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3210 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3213 //=============================================================================
3215 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3217 Unexpect aCatch(SALOME_SalomeException);
3219 return _preMeshInfo->NbVolumes();
3221 return _impl->NbVolumes();
3224 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3226 Unexpect aCatch(SALOME_SalomeException);
3228 return _preMeshInfo->NbTetras();
3230 return _impl->NbTetras();
3233 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3235 Unexpect aCatch(SALOME_SalomeException);
3237 return _preMeshInfo->NbHexas();
3239 return _impl->NbHexas();
3242 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3244 Unexpect aCatch(SALOME_SalomeException);
3246 return _preMeshInfo->NbTriQuadHexas();
3248 return _impl->NbTriQuadraticHexas();
3251 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3253 Unexpect aCatch(SALOME_SalomeException);
3255 return _preMeshInfo->NbPyramids();
3257 return _impl->NbPyramids();
3260 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3262 Unexpect aCatch(SALOME_SalomeException);
3264 return _preMeshInfo->NbPrisms();
3266 return _impl->NbPrisms();
3269 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3271 Unexpect aCatch(SALOME_SalomeException);
3273 return _preMeshInfo->NbHexPrisms();
3275 return _impl->NbHexagonalPrisms();
3278 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3280 Unexpect aCatch(SALOME_SalomeException);
3282 return _preMeshInfo->NbPolyhedrons();
3284 return _impl->NbPolyhedrons();
3287 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3288 throw(SALOME::SALOME_Exception)
3290 Unexpect aCatch(SALOME_SalomeException);
3292 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3294 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3297 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3298 throw(SALOME::SALOME_Exception)
3300 Unexpect aCatch(SALOME_SalomeException);
3302 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3304 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3307 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3308 throw(SALOME::SALOME_Exception)
3310 Unexpect aCatch(SALOME_SalomeException);
3312 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3314 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3317 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3318 throw(SALOME::SALOME_Exception)
3320 Unexpect aCatch(SALOME_SalomeException);
3322 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3324 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3327 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3328 throw(SALOME::SALOME_Exception)
3330 Unexpect aCatch(SALOME_SalomeException);
3332 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3334 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3337 //=============================================================================
3339 * Returns nb of published sub-meshes
3341 //=============================================================================
3343 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3345 Unexpect aCatch(SALOME_SalomeException);
3346 return _mapSubMesh_i.size();
3349 //=============================================================================
3351 * Dumps mesh into a string
3353 //=============================================================================
3355 char* SMESH_Mesh_i::Dump()
3359 return CORBA::string_dup( os.str().c_str() );
3362 //=============================================================================
3364 * Method of SMESH_IDSource interface
3366 //=============================================================================
3368 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3370 return GetElementsId();
3373 //=============================================================================
3375 * Returns ids of all elements
3377 //=============================================================================
3379 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3380 throw (SALOME::SALOME_Exception)
3382 Unexpect aCatch(SALOME_SalomeException);
3384 _preMeshInfo->FullLoadFromFile();
3386 SMESH::long_array_var aResult = new SMESH::long_array();
3387 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3389 if ( aSMESHDS_Mesh == NULL )
3390 return aResult._retn();
3392 long nbElements = NbElements();
3393 aResult->length( nbElements );
3394 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3395 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3396 aResult[i] = anIt->next()->GetID();
3398 return aResult._retn();
3402 //=============================================================================
3404 * Returns ids of all elements of given type
3406 //=============================================================================
3408 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3409 throw (SALOME::SALOME_Exception)
3411 Unexpect aCatch(SALOME_SalomeException);
3413 _preMeshInfo->FullLoadFromFile();
3415 SMESH::long_array_var aResult = new SMESH::long_array();
3416 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3418 if ( aSMESHDS_Mesh == NULL )
3419 return aResult._retn();
3421 long nbElements = NbElements();
3423 // No sense in returning ids of elements along with ids of nodes:
3424 // when theElemType == SMESH::ALL, return node ids only if
3425 // there are no elements
3426 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3427 return GetNodesId();
3429 aResult->length( nbElements );
3433 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3434 while ( i < nbElements && anIt->more() ) {
3435 const SMDS_MeshElement* anElem = anIt->next();
3436 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3437 aResult[i++] = anElem->GetID();
3440 aResult->length( i );
3442 return aResult._retn();
3445 //=============================================================================
3447 * Returns ids of all nodes
3449 //=============================================================================
3451 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3452 throw (SALOME::SALOME_Exception)
3454 Unexpect aCatch(SALOME_SalomeException);
3456 _preMeshInfo->FullLoadFromFile();
3458 SMESH::long_array_var aResult = new SMESH::long_array();
3459 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3461 if ( aSMESHDS_Mesh == NULL )
3462 return aResult._retn();
3464 long nbNodes = NbNodes();
3465 aResult->length( nbNodes );
3466 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3467 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3468 aResult[i] = anIt->next()->GetID();
3470 return aResult._retn();
3473 //=============================================================================
3477 //=============================================================================
3479 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3480 throw (SALOME::SALOME_Exception)
3483 _preMeshInfo->FullLoadFromFile();
3485 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3488 //=============================================================================
3492 //=============================================================================
3494 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3495 throw (SALOME::SALOME_Exception)
3498 _preMeshInfo->FullLoadFromFile();
3500 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3502 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3504 return ( SMESH::EntityType ) e->GetEntityType();
3507 //=============================================================================
3509 * Returns ID of elements for given submesh
3511 //=============================================================================
3512 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3513 throw (SALOME::SALOME_Exception)
3516 _preMeshInfo->FullLoadFromFile();
3518 SMESH::long_array_var aResult = new SMESH::long_array();
3520 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3521 if(!SM) return aResult._retn();
3523 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3524 if(!SDSM) return aResult._retn();
3526 aResult->length(SDSM->NbElements());
3528 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3530 while ( eIt->more() ) {
3531 aResult[i++] = eIt->next()->GetID();
3534 return aResult._retn();
3538 //=============================================================================
3540 * Returns ID of nodes for given submesh
3541 * If param all==true - returns all nodes, else -
3542 * returns only nodes on shapes.
3544 //=============================================================================
3545 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3547 throw (SALOME::SALOME_Exception)
3550 _preMeshInfo->FullLoadFromFile();
3552 SMESH::long_array_var aResult = new SMESH::long_array();
3554 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3555 if(!SM) return aResult._retn();
3557 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3558 if(!SDSM) return aResult._retn();
3561 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3562 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3563 while ( nIt->more() ) {
3564 const SMDS_MeshNode* elem = nIt->next();
3565 theElems.insert( elem->GetID() );
3568 else { // all nodes of submesh elements
3569 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3570 while ( eIt->more() ) {
3571 const SMDS_MeshElement* anElem = eIt->next();
3572 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3573 while ( nIt->more() ) {
3574 const SMDS_MeshElement* elem = nIt->next();
3575 theElems.insert( elem->GetID() );
3580 aResult->length(theElems.size());
3581 set<int>::iterator itElem;
3583 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3584 aResult[i++] = *itElem;
3586 return aResult._retn();
3589 //=============================================================================
3591 * Returns type of elements for given submesh
3593 //=============================================================================
3595 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3596 throw (SALOME::SALOME_Exception)
3599 _preMeshInfo->FullLoadFromFile();
3601 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3602 if(!SM) return SMESH::ALL;
3604 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3605 if(!SDSM) return SMESH::ALL;
3607 if(SDSM->NbElements()==0)
3608 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3610 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3611 const SMDS_MeshElement* anElem = eIt->next();
3612 return ( SMESH::ElementType ) anElem->GetType();
3616 //=============================================================================
3618 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3620 //=============================================================================
3622 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3625 _preMeshInfo->FullLoadFromFile();
3627 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3629 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3634 //=============================================================================
3636 * Get XYZ coordinates of node as list of double
3637 * If there is not node for given ID - returns empty list
3639 //=============================================================================
3641 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3644 _preMeshInfo->FullLoadFromFile();
3646 SMESH::double_array_var aResult = new SMESH::double_array();
3647 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3648 if ( aSMESHDS_Mesh == NULL )
3649 return aResult._retn();
3652 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3654 return aResult._retn();
3658 aResult[0] = aNode->X();
3659 aResult[1] = aNode->Y();
3660 aResult[2] = aNode->Z();
3661 return aResult._retn();
3665 //=============================================================================
3667 * For given node returns list of IDs of inverse elements
3668 * If there is not node for given ID - returns empty list
3670 //=============================================================================
3672 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3675 _preMeshInfo->FullLoadFromFile();
3677 SMESH::long_array_var aResult = new SMESH::long_array();
3678 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3679 if ( aSMESHDS_Mesh == NULL )
3680 return aResult._retn();
3683 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3685 return aResult._retn();
3687 // find inverse elements
3688 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3689 TColStd_SequenceOfInteger IDs;
3690 while(eIt->more()) {
3691 const SMDS_MeshElement* elem = eIt->next();
3692 IDs.Append(elem->GetID());
3694 if(IDs.Length()>0) {
3695 aResult->length(IDs.Length());
3697 for(; i<=IDs.Length(); i++) {
3698 aResult[i-1] = IDs.Value(i);
3701 return aResult._retn();
3704 //=============================================================================
3706 * \brief Return position of a node on shape
3708 //=============================================================================
3710 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3713 _preMeshInfo->FullLoadFromFile();
3715 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3716 aNodePosition->shapeID = 0;
3717 aNodePosition->shapeType = GEOM::SHAPE;
3719 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3720 if ( !mesh ) return aNodePosition;
3722 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3724 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3726 aNodePosition->shapeID = aNode->getshapeId();
3727 switch ( pos->GetTypeOfPosition() ) {
3729 aNodePosition->shapeType = GEOM::EDGE;
3730 aNodePosition->params.length(1);
3731 aNodePosition->params[0] =
3732 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3735 aNodePosition->shapeType = GEOM::FACE;
3736 aNodePosition->params.length(2);
3737 aNodePosition->params[0] =
3738 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3739 aNodePosition->params[1] =
3740 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3742 case SMDS_TOP_VERTEX:
3743 aNodePosition->shapeType = GEOM::VERTEX;
3745 case SMDS_TOP_3DSPACE:
3746 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3747 aNodePosition->shapeType = GEOM::SOLID;
3748 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3749 aNodePosition->shapeType = GEOM::SHELL;
3755 return aNodePosition;
3758 //=============================================================================
3760 * If given element is node returns IDs of shape from position
3761 * If there is not node for given ID - returns -1
3763 //=============================================================================
3765 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3768 _preMeshInfo->FullLoadFromFile();
3770 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3771 if ( aSMESHDS_Mesh == NULL )
3775 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3777 return aNode->getshapeId();
3784 //=============================================================================
3786 * For given element returns ID of result shape after
3787 * ::FindShape() from SMESH_MeshEditor
3788 * If there is not element for given ID - returns -1
3790 //=============================================================================
3792 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3795 _preMeshInfo->FullLoadFromFile();
3797 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3798 if ( aSMESHDS_Mesh == NULL )
3801 // try to find element
3802 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3806 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3807 ::SMESH_MeshEditor aMeshEditor(_impl);
3808 int index = aMeshEditor.FindShape( elem );
3816 //=============================================================================
3818 * Returns number of nodes for given element
3819 * If there is not element for given ID - returns -1
3821 //=============================================================================
3823 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3826 _preMeshInfo->FullLoadFromFile();
3828 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3829 if ( aSMESHDS_Mesh == NULL ) return -1;
3830 // try to find element
3831 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3832 if(!elem) return -1;
3833 return elem->NbNodes();
3837 //=============================================================================
3839 * Returns ID of node by given index for given element
3840 * If there is not element for given ID - returns -1
3841 * If there is not node for given index - returns -2
3843 //=============================================================================
3845 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3848 _preMeshInfo->FullLoadFromFile();
3850 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3851 if ( aSMESHDS_Mesh == NULL ) return -1;
3852 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3853 if(!elem) return -1;
3854 if( index>=elem->NbNodes() || index<0 ) return -1;
3855 return elem->GetNode(index)->GetID();
3858 //=============================================================================
3860 * Returns IDs of nodes of given element
3862 //=============================================================================
3864 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3867 _preMeshInfo->FullLoadFromFile();
3869 SMESH::long_array_var aResult = new SMESH::long_array();
3870 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3872 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3874 aResult->length( elem->NbNodes() );
3875 for ( int i = 0; i < elem->NbNodes(); ++i )
3876 aResult[ i ] = elem->GetNode( i )->GetID();
3879 return aResult._retn();
3882 //=============================================================================
3884 * Returns true if given node is medium node
3885 * in given quadratic element
3887 //=============================================================================
3889 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3892 _preMeshInfo->FullLoadFromFile();
3894 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3895 if ( aSMESHDS_Mesh == NULL ) return false;
3897 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3898 if(!aNode) return false;
3899 // try to find element
3900 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3901 if(!elem) return false;
3903 return elem->IsMediumNode(aNode);
3907 //=============================================================================
3909 * Returns true if given node is medium node
3910 * in one of quadratic elements
3912 //=============================================================================
3914 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3915 SMESH::ElementType theElemType)
3918 _preMeshInfo->FullLoadFromFile();
3920 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3921 if ( aSMESHDS_Mesh == NULL ) return false;
3924 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3925 if(!aNode) return false;
3927 SMESH_MesherHelper aHelper( *(_impl) );
3929 SMDSAbs_ElementType aType;
3930 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3931 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3932 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3933 else aType = SMDSAbs_All;
3935 return aHelper.IsMedium(aNode,aType);
3939 //=============================================================================
3941 * Returns number of edges for given element
3943 //=============================================================================
3945 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3948 _preMeshInfo->FullLoadFromFile();
3950 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3951 if ( aSMESHDS_Mesh == NULL ) return -1;
3952 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3953 if(!elem) return -1;
3954 return elem->NbEdges();
3958 //=============================================================================
3960 * Returns number of faces for given element
3962 //=============================================================================
3964 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3967 _preMeshInfo->FullLoadFromFile();
3969 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3970 if ( aSMESHDS_Mesh == NULL ) return -1;
3971 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3972 if(!elem) return -1;
3973 return elem->NbFaces();
3976 //=======================================================================
3977 //function : GetElemFaceNodes
3978 //purpose : Returns nodes of given face (counted from zero) for given element.
3979 //=======================================================================
3981 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3982 CORBA::Short faceIndex)
3985 _preMeshInfo->FullLoadFromFile();
3987 SMESH::long_array_var aResult = new SMESH::long_array();
3988 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3990 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3992 SMDS_VolumeTool vtool( elem );
3993 if ( faceIndex < vtool.NbFaces() )
3995 aResult->length( vtool.NbFaceNodes( faceIndex ));
3996 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3997 for ( int i = 0; i < aResult->length(); ++i )
3998 aResult[ i ] = nn[ i ]->GetID();
4002 return aResult._retn();
4005 //=======================================================================
4006 //function : FindElementByNodes
4007 //purpose : Returns an element based on all given nodes.
4008 //=======================================================================
4010 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4013 _preMeshInfo->FullLoadFromFile();
4015 CORBA::Long elemID(0);
4016 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4018 vector< const SMDS_MeshNode * > nn( nodes.length() );
4019 for ( int i = 0; i < nodes.length(); ++i )
4020 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4023 const SMDS_MeshElement* elem = mesh->FindElement( nn );
4024 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4025 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4026 _impl->NbVolumes( ORDER_QUADRATIC )))
4027 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4029 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4034 //=============================================================================
4036 * Returns true if given element is polygon
4038 //=============================================================================
4040 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4043 _preMeshInfo->FullLoadFromFile();
4045 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4046 if ( aSMESHDS_Mesh == NULL ) return false;
4047 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4048 if(!elem) return false;
4049 return elem->IsPoly();
4053 //=============================================================================
4055 * Returns true if given element is quadratic
4057 //=============================================================================
4059 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4062 _preMeshInfo->FullLoadFromFile();
4064 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4065 if ( aSMESHDS_Mesh == NULL ) return false;
4066 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4067 if(!elem) return false;
4068 return elem->IsQuadratic();
4071 //=============================================================================
4073 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4075 //=============================================================================
4077 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4080 _preMeshInfo->FullLoadFromFile();
4082 if ( const SMDS_BallElement* ball =
4083 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4084 return ball->GetDiameter();
4089 //=============================================================================
4091 * Returns bary center for given element
4093 //=============================================================================
4095 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4098 _preMeshInfo->FullLoadFromFile();
4100 SMESH::double_array_var aResult = new SMESH::double_array();
4101 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4102 if ( aSMESHDS_Mesh == NULL )
4103 return aResult._retn();
4105 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4107 return aResult._retn();
4109 if(elem->GetType()==SMDSAbs_Volume) {
4110 SMDS_VolumeTool aTool;
4111 if(aTool.Set(elem)) {
4113 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4118 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4120 double x=0., y=0., z=0.;
4121 for(; anIt->more(); ) {
4123 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4137 return aResult._retn();
4141 //=============================================================================
4143 * Create and publish group servants if any groups were imported or created anyhow
4145 //=============================================================================
4147 void SMESH_Mesh_i::CreateGroupServants()
4149 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
4152 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4153 while ( groupIt->more() )
4155 ::SMESH_Group* group = groupIt->next();
4156 int anId = group->GetGroupDS()->GetID();
4158 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4159 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4161 addedIDs.insert( anId );
4163 SMESH_GroupBase_i* aGroupImpl;
4165 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4166 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4168 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4169 shape = groupOnGeom->GetShape();
4172 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4175 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
4176 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
4177 aGroupImpl->Register();
4179 SMESH::SMESH_GroupBase_var groupVar =
4180 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4181 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4183 // register CORBA object for persistence
4184 int nextId = _gen_i->RegisterObject( groupVar );
4185 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
4187 // publishing the groups in the study
4188 if ( !aStudy->_is_nil() ) {
4189 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4190 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4193 if ( !addedIDs.empty() )
4196 set<int>::iterator id = addedIDs.begin();
4197 for ( ; id != addedIDs.end(); ++id )
4199 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4200 int i = std::distance( _mapGroups.begin(), it );
4201 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4206 //=============================================================================
4208 * \brief Return groups cantained in _mapGroups by their IDs
4210 //=============================================================================
4212 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4214 int nbGroups = groupIDs.size();
4215 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4216 aList->length( nbGroups );
4218 list<int>::const_iterator ids = groupIDs.begin();
4219 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4221 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4222 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4223 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4225 aList->length( nbGroups );
4226 return aList._retn();
4229 //=============================================================================
4231 * \brief Return information about imported file
4233 //=============================================================================
4235 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4237 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4238 if ( !res.operator->() ) {
4239 res = new SALOME_MED::MedFileInfo;
4241 res->fileSize = res->major = res->minor = res->release = -1;
4246 //=============================================================================
4248 * \brief Pass names of mesh groups from study to mesh DS
4250 //=============================================================================
4252 void SMESH_Mesh_i::checkGroupNames()
4254 int nbGrp = NbGroups();
4258 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
4259 if ( aStudy->_is_nil() )
4260 return; // nothing to do
4262 SMESH::ListOfGroups* grpList = 0;
4263 // avoid dump of "GetGroups"
4265 // store python dump into a local variable inside local scope
4266 SMESH::TPythonDump pDump; // do not delete this line of code
4267 grpList = GetGroups();
4270 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4271 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4274 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4275 if ( aGrpSO->_is_nil() )
4277 // correct name of the mesh group if necessary
4278 const char* guiName = aGrpSO->GetName();
4279 if ( strcmp(guiName, aGrp->GetName()) )
4280 aGrp->SetName( guiName );
4284 //=============================================================================
4286 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4288 //=============================================================================
4289 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4291 // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
4292 // CORBA::string_dup(theParameters));
4293 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters);
4296 //=============================================================================
4298 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4300 //=============================================================================
4301 char* SMESH_Mesh_i::GetParameters()
4303 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4304 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4307 //=============================================================================
4309 * \brief Returns list of notebook variables used for last Mesh operation
4311 //=============================================================================
4312 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4314 SMESH::string_array_var aResult = new SMESH::string_array();
4315 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4317 char *aParameters = GetParameters();
4318 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
4319 if(!aStudy->_is_nil()) {
4320 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4321 if(aSections->length() > 0) {
4322 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4323 aResult->length(aVars.length());
4324 for(int i = 0;i < aVars.length();i++)
4325 aResult[i] = CORBA::string_dup( aVars[i]);
4329 return aResult._retn();
4332 //=======================================================================
4333 //function : GetTypes
4334 //purpose : Returns types of elements it contains
4335 //=======================================================================
4337 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4340 return _preMeshInfo->GetTypes();
4342 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4346 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4347 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4348 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4349 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4350 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4351 types->length( nbTypes );
4353 return types._retn();
4356 //=======================================================================
4357 //function : GetMesh
4358 //purpose : Returns self
4359 //=======================================================================
4361 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4363 return SMESH::SMESH_Mesh::_duplicate( _this() );
4366 //=======================================================================
4367 //function : IsMeshInfoCorrect
4368 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4369 // * happen if mesh data is not yet fully loaded from the file of study.
4370 //=======================================================================
4372 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4374 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4377 //=============================================================================
4379 * \brief Returns statistic of mesh elements
4381 //=============================================================================
4383 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4386 return _preMeshInfo->GetMeshInfo();
4388 SMESH::long_array_var aRes = new SMESH::long_array();
4389 aRes->length(SMESH::Entity_Last);
4390 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4392 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4394 return aRes._retn();
4395 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4396 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4397 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4398 return aRes._retn();
4401 //=============================================================================
4403 * \brief Collect statistic of mesh elements given by iterator
4405 //=============================================================================
4407 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4408 SMESH::long_array& theInfo)
4410 if (!theItr) return;
4411 while (theItr->more())
4412 theInfo[ theItr->next()->GetEntityType() ]++;
4415 //=============================================================================
4416 namespace // Finding concurrent hypotheses
4417 //=============================================================================
4421 * \brief mapping of mesh dimension into shape type
4423 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4425 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4427 case 0: aType = TopAbs_VERTEX; break;
4428 case 1: aType = TopAbs_EDGE; break;
4429 case 2: aType = TopAbs_FACE; break;
4431 default:aType = TopAbs_SOLID; break;
4436 //-----------------------------------------------------------------------------
4438 * \brief Internal structure used to find concurent submeshes
4440 * It represents a pair < submesh, concurent dimension >, where
4441 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4442 * with another submesh. In other words, it is dimension of a hypothesis assigned
4449 int _dim; //!< a dimension the algo can build (concurrent dimension)
4450 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4451 TopTools_MapOfShape _shapeMap;
4452 SMESH_subMesh* _subMesh;
4453 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4455 //-----------------------------------------------------------------------------
4456 // Return the algorithm
4457 const SMESH_Algo* GetAlgo() const
4458 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4460 //-----------------------------------------------------------------------------
4462 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4464 const TopoDS_Shape& theShape)
4466 _subMesh = (SMESH_subMesh*)theSubMesh;
4467 SetShape( theDim, theShape );
4470 //-----------------------------------------------------------------------------
4472 void SetShape(const int theDim,
4473 const TopoDS_Shape& theShape)
4476 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4477 if (_dim >= _ownDim)
4478 _shapeMap.Add( theShape );
4480 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4481 for( ; anExp.More(); anExp.Next() )
4482 _shapeMap.Add( anExp.Current() );
4486 //-----------------------------------------------------------------------------
4487 //! Check sharing of sub-shapes
4488 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4489 const TopTools_MapOfShape& theToFind,
4490 const TopAbs_ShapeEnum theType)
4492 bool isShared = false;
4493 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4494 for (; !isShared && anItr.More(); anItr.Next() )
4496 const TopoDS_Shape aSubSh = anItr.Key();
4497 // check for case when concurrent dimensions are same
4498 isShared = theToFind.Contains( aSubSh );
4499 // check for sub-shape with concurrent dimension
4500 TopExp_Explorer anExp( aSubSh, theType );
4501 for ( ; !isShared && anExp.More(); anExp.Next() )
4502 isShared = theToFind.Contains( anExp.Current() );
4507 //-----------------------------------------------------------------------------
4508 //! check algorithms
4509 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4510 const SMESHDS_Hypothesis* theA2)
4512 if ( !theA1 || !theA2 ||
4513 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4514 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4515 return false; // one of the hypothesis is not algorithm
4516 // check algorithm names (should be equal)
4517 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4521 //-----------------------------------------------------------------------------
4522 //! Check if sub-shape hypotheses are concurrent
4523 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4525 if ( _subMesh == theOther->_subMesh )
4526 return false; // same sub-shape - should not be
4528 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4529 // any of the two submeshes is not on COMPOUND shape )
4530 // -> no concurrency
4531 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4532 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4533 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4534 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4535 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4538 // bool checkSubShape = ( _dim >= theOther->_dim )
4539 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4540 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4541 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4542 if ( !checkSubShape )
4545 // check algorithms to be same
4546 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4547 return true; // different algorithms -> concurrency !
4549 // check hypothesises for concurrence (skip first as algorithm)
4551 // pointers should be same, because it is referened from mesh hypothesis partition
4552 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4553 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4554 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4555 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4557 // the submeshes are concurrent if their algorithms has different parameters
4558 return nbSame != theOther->_hypotheses.size() - 1;
4561 // Return true if algorithm of this SMESH_DimHyp is used if no
4562 // sub-mesh order is imposed by the user
4563 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4565 // NeedDiscreteBoundary() algo has a higher priority
4566 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4567 theOther->GetAlgo()->NeedDiscreteBoundary() )
4568 return !this->GetAlgo()->NeedDiscreteBoundary();
4570 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4573 }; // end of SMESH_DimHyp
4574 //-----------------------------------------------------------------------------
4576 typedef list<const SMESH_DimHyp*> TDimHypList;
4578 //-----------------------------------------------------------------------------
4580 void addDimHypInstance(const int theDim,
4581 const TopoDS_Shape& theShape,
4582 const SMESH_Algo* theAlgo,
4583 const SMESH_subMesh* theSubMesh,
4584 const list <const SMESHDS_Hypothesis*>& theHypList,
4585 TDimHypList* theDimHypListArr )
4587 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4588 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4589 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4590 dimHyp->_hypotheses.push_front(theAlgo);
4591 listOfdimHyp.push_back( dimHyp );
4594 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4595 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4596 theHypList.begin(), theHypList.end() );
4599 //-----------------------------------------------------------------------------
4600 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4601 TDimHypList& theListOfConcurr)
4603 if ( theListOfConcurr.empty() )
4605 theListOfConcurr.push_back( theDimHyp );
4609 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4610 while ( hypIt != theListOfConcurr.end() &&
4611 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4613 theListOfConcurr.insert( hypIt, theDimHyp );
4617 //-----------------------------------------------------------------------------
4618 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4619 const TDimHypList& theListOfDimHyp,
4620 TDimHypList& theListOfConcurrHyp,
4621 set<int>& theSetOfConcurrId )
4623 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4624 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4626 const SMESH_DimHyp* curDimHyp = *rIt;
4627 if ( curDimHyp == theDimHyp )
4628 break; // meet own dimHyp pointer in same dimension
4630 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4631 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4633 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4638 //-----------------------------------------------------------------------------
4639 void unionLists(TListOfInt& theListOfId,
4640 TListOfListOfInt& theListOfListOfId,
4643 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4644 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4646 continue; //skip already treated lists
4647 // check if other list has any same submesh object
4648 TListOfInt& otherListOfId = *it;
4649 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4650 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4653 // union two lists (from source into target)
4654 TListOfInt::iterator it2 = otherListOfId.begin();
4655 for ( ; it2 != otherListOfId.end(); it2++ ) {
4656 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4657 theListOfId.push_back(*it2);
4659 // clear source list
4660 otherListOfId.clear();
4663 //-----------------------------------------------------------------------------
4665 //! free memory allocated for dimension-hypothesis objects
4666 void removeDimHyps( TDimHypList* theArrOfList )
4668 for (int i = 0; i < 4; i++ ) {
4669 TDimHypList& listOfdimHyp = theArrOfList[i];
4670 TDimHypList::const_iterator it = listOfdimHyp.begin();
4671 for ( ; it != listOfdimHyp.end(); it++ )
4676 //-----------------------------------------------------------------------------
4678 * \brief find common submeshes with given submesh
4679 * \param theSubMeshList list of already collected submesh to check
4680 * \param theSubMesh given submesh to intersect with other
4681 * \param theCommonSubMeshes collected common submeshes
4683 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4684 const SMESH_subMesh* theSubMesh,
4685 set<const SMESH_subMesh*>& theCommon )
4689 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4690 for ( ; it != theSubMeshList.end(); it++ )
4691 theSubMesh->FindIntersection( *it, theCommon );
4692 theSubMeshList.push_back( theSubMesh );
4693 //theCommon.insert( theSubMesh );
4698 //=============================================================================
4700 * \brief Return submesh objects list in meshing order
4702 //=============================================================================
4704 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4706 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4708 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4710 return aResult._retn();
4712 ::SMESH_Mesh& mesh = GetImpl();
4713 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4714 if ( !anOrder.size() ) {
4716 // collect submeshes and detect concurrent algorithms and hypothesises
4717 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4719 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4720 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4721 ::SMESH_subMesh* sm = (*i_sm).second;
4723 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4725 // list of assigned hypothesises
4726 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4727 // Find out dimensions where the submesh can be concurrent.
4728 // We define the dimensions by algo of each of hypotheses in hypList
4729 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4730 for( ; hypIt != hypList.end(); hypIt++ ) {
4731 SMESH_Algo* anAlgo = 0;
4732 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4733 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4734 // hyp it-self is algo
4735 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4737 // try to find algorithm with help of sub-shapes
4738 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4739 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4740 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4743 continue; // no algorithm assigned to a current submesh
4745 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4746 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4748 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4749 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4750 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4752 } // end iterations on submesh
4754 // iterate on created dimension-hypotheses and check for concurrents
4755 for ( int i = 0; i < 4; i++ ) {
4756 const TDimHypList& listOfDimHyp = dimHypListArr[i];
4757 // check for concurrents in own and other dimensions (step-by-step)
4758 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4759 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4760 const SMESH_DimHyp* dimHyp = *dhIt;
4761 TDimHypList listOfConcurr;
4762 set<int> setOfConcurrIds;
4763 // looking for concurrents and collect into own list
4764 for ( int j = i; j < 4; j++ )
4765 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
4766 // check if any concurrents found
4767 if ( listOfConcurr.size() > 0 ) {
4768 // add own submesh to list of concurrent
4769 addInOrderOfPriority( dimHyp, listOfConcurr );
4770 list<int> listOfConcurrIds;
4771 TDimHypList::iterator hypIt = listOfConcurr.begin();
4772 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
4773 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
4774 anOrder.push_back( listOfConcurrIds );
4779 removeDimHyps(dimHypListArr);
4781 // now, minimise the number of concurrent groups
4782 // Here we assume that lists of submeshes can have same submesh
4783 // in case of multi-dimension algorithms, as result
4784 // list with common submesh has to be united into one list
4786 TListOfListOfInt::iterator listIt = anOrder.begin();
4787 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4788 unionLists( *listIt, anOrder, listIndx + 1 );
4790 // convert submesh ids into interface instances
4791 // and dump command into python
4792 convertMeshOrder( anOrder, aResult, false );
4794 return aResult._retn();
4797 //=============================================================================
4799 * \brief Set submesh object order
4800 * \param theSubMeshArray submesh array order
4802 //=============================================================================
4804 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4807 _preMeshInfo->ForgetOrLoad();
4810 ::SMESH_Mesh& mesh = GetImpl();
4812 TPythonDump aPythonDump; // prevent dump of called methods
4813 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4815 TListOfListOfInt subMeshOrder;
4816 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4818 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4819 TListOfInt subMeshIds;
4820 aPythonDump << "[ ";
4821 // Collect subMeshes which should be clear
4822 // do it list-by-list, because modification of submesh order
4823 // take effect between concurrent submeshes only
4824 set<const SMESH_subMesh*> subMeshToClear;
4825 list<const SMESH_subMesh*> subMeshList;
4826 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4828 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4830 aPythonDump << ", ";
4831 aPythonDump << subMesh;
4832 subMeshIds.push_back( subMesh->GetId() );
4833 // detect common parts of submeshes
4834 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4835 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4837 aPythonDump << " ]";
4838 subMeshOrder.push_back( subMeshIds );
4840 // clear collected submeshes
4841 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4842 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
4843 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
4844 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4846 aPythonDump << " ])";
4848 mesh.SetMeshOrder( subMeshOrder );
4854 //=============================================================================
4856 * \brief Convert submesh ids into submesh interfaces
4858 //=============================================================================
4860 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4861 SMESH::submesh_array_array& theResOrder,
4862 const bool theIsDump)
4864 int nbSet = theIdsOrder.size();
4865 TPythonDump aPythonDump; // prevent dump of called methods
4867 aPythonDump << "[ ";
4868 theResOrder.length(nbSet);
4869 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4871 for( ; it != theIdsOrder.end(); it++ ) {
4872 // translate submesh identificators into submesh objects
4873 // takeing into account real number of concurrent lists
4874 const TListOfInt& aSubOrder = (*it);
4875 if (!aSubOrder.size())
4878 aPythonDump << "[ ";
4879 // convert shape indeces into interfaces
4880 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4881 aResSubSet->length(aSubOrder.size());
4882 TListOfInt::const_iterator subIt = aSubOrder.begin();
4883 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4884 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4886 SMESH::SMESH_subMesh_var subMesh =
4887 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4890 aPythonDump << ", ";
4891 aPythonDump << subMesh;
4893 aResSubSet[ j++ ] = subMesh;
4896 aPythonDump << " ]";
4897 theResOrder[ listIndx++ ] = aResSubSet;
4899 // correct number of lists
4900 theResOrder.length( listIndx );
4903 // finilise python dump
4904 aPythonDump << " ]";
4905 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4909 //================================================================================
4911 // Implementation of SMESH_MeshPartDS
4913 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4914 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
4916 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4917 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4919 _meshDS = mesh_i->GetImpl().GetMeshDS();
4921 SetPersistentId( _meshDS->GetPersistentId() );
4923 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4925 // <meshPart> is the whole mesh
4926 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4928 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4929 myGroupSet = _meshDS->GetGroups();
4934 SMESH::long_array_var anIDs = meshPart->GetIDs();
4935 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4936 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4938 for (int i=0; i < anIDs->length(); i++)
4939 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4940 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4945 for (int i=0; i < anIDs->length(); i++)
4946 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4947 if ( _elements[ e->GetType() ].insert( e ).second )
4950 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4951 while ( nIt->more() )
4953 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4954 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4961 _meshDS = 0; // to enforce iteration on _elements and _nodes
4964 // -------------------------------------------------------------------------------------
4965 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
4966 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
4969 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
4970 for ( ; partIt != meshPart.end(); ++partIt )
4971 if ( const SMDS_MeshElement * e = *partIt )
4972 if ( _elements[ e->GetType() ].insert( e ).second )
4975 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4976 while ( nIt->more() )
4978 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4979 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4985 // -------------------------------------------------------------------------------------
4986 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
4988 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
4990 typedef SMDS_SetIterator
4991 <const SMDS_MeshElement*,
4992 TIDSortedElemSet::const_iterator,
4993 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
4994 SMDS_MeshElement::GeomFilter
4997 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
4999 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5000 _elements[type].end(),
5001 SMDS_MeshElement::GeomFilter( geomType )));
5003 // -------------------------------------------------------------------------------------
5004 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5006 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5008 typedef SMDS_SetIterator
5009 <const SMDS_MeshElement*,
5010 TIDSortedElemSet::const_iterator,
5011 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5012 SMDS_MeshElement::EntityFilter
5015 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5017 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5018 _elements[type].end(),
5019 SMDS_MeshElement::EntityFilter( entity )));
5021 // -------------------------------------------------------------------------------------
5022 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5024 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5025 if ( type == SMDSAbs_All && !_meshDS )
5027 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5029 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5030 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5032 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5034 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5035 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5037 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5038 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5040 // -------------------------------------------------------------------------------------
5041 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5042 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5044 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5045 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5046 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5048 // -------------------------------------------------------------------------------------
5049 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5050 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5051 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5052 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5053 #undef _GET_ITER_DEFINE
5055 // END Implementation of SMESH_MeshPartDS
5057 //================================================================================