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 <TColStd_MapIteratorOfMapOfInteger.hxx>
67 #include <TColStd_MapOfInteger.hxx>
68 #include <TColStd_SequenceOfInteger.hxx>
69 #include <TCollection_AsciiString.hxx>
71 #include <TopExp_Explorer.hxx>
72 #include <TopoDS_Compound.hxx>
73 #include <TopTools_MapOfShape.hxx>
74 #include <TopTools_MapIteratorOfMapOfShape.hxx>
84 static int MYDEBUG = 0;
86 static int MYDEBUG = 0;
90 using SMESH::TPythonDump;
92 int SMESH_Mesh_i::_idGenerator = 0;
94 //To disable automatic genericobj management, the following line should be commented.
95 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
96 #define WITHGENERICOBJ
98 //=============================================================================
102 //=============================================================================
104 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
106 CORBA::Long studyId )
107 : SALOME::GenericObj_i( thePOA )
109 MESSAGE("SMESH_Mesh_i");
112 _id = _idGenerator++;
117 //=============================================================================
121 //=============================================================================
123 SMESH_Mesh_i::~SMESH_Mesh_i()
125 MESSAGE("~SMESH_Mesh_i");
127 #ifdef WITHGENERICOBJ
129 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
130 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
131 if ( CORBA::is_nil( itGr->second ))
133 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
135 // this method is called from destructor of group (PAL6331)
136 //_impl->RemoveGroup( aGroup->GetLocalID() );
137 aGroup->myMeshServant = 0;
138 aGroup->UnRegister();
144 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
145 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
146 if ( CORBA::is_nil( itSM->second ))
148 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
150 aSubMesh->UnRegister();
153 _mapSubMeshIor.clear();
155 // destroy hypotheses
156 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
157 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
158 if ( CORBA::is_nil( itH->second ))
160 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
168 delete _impl; _impl = NULL;
170 if ( _preMeshInfo ) delete _preMeshInfo; _preMeshInfo = NULL;
173 //=============================================================================
177 * Associates <this> mesh with <theShape> and puts a reference
178 * to <theShape> into the current study;
179 * the previous shape is substituted by the new one.
181 //=============================================================================
183 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
184 throw (SALOME::SALOME_Exception)
186 Unexpect aCatch(SALOME_SalomeException);
188 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
190 catch(SALOME_Exception & S_ex) {
191 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
193 // to track changes of GEOM groups
194 addGeomGroupData( theShapeObject, _this() );
197 //================================================================================
199 * \brief return true if mesh has a shape to build a shape on
201 //================================================================================
203 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
204 throw (SALOME::SALOME_Exception)
206 Unexpect aCatch(SALOME_SalomeException);
209 res = _impl->HasShapeToMesh();
211 catch(SALOME_Exception & S_ex) {
212 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
217 //=======================================================================
218 //function : GetShapeToMesh
220 //=======================================================================
222 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
223 throw (SALOME::SALOME_Exception)
225 Unexpect aCatch(SALOME_SalomeException);
226 GEOM::GEOM_Object_var aShapeObj;
228 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
230 aShapeObj = _gen_i->ShapeToGeomObject( S );
232 catch(SALOME_Exception & S_ex) {
233 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
235 return aShapeObj._retn();
238 //================================================================================
240 * \brief Return false if the mesh is not yet fully loaded from the study file
242 //================================================================================
244 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
246 Unexpect aCatch(SALOME_SalomeException);
247 return !_preMeshInfo;
250 //================================================================================
252 * \brief Load full mesh data from the study file
254 //================================================================================
256 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
258 Unexpect aCatch(SALOME_SalomeException);
260 _preMeshInfo->FullLoadFromFile();
263 //================================================================================
265 * \brief Remove all nodes and elements
267 //================================================================================
269 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
271 Unexpect aCatch(SALOME_SalomeException);
273 _preMeshInfo->ForgetAllData();
277 CheckGeomGroupModif(); // issue 20145
279 catch(SALOME_Exception & S_ex) {
280 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
282 TPythonDump() << _this() << ".Clear()";
285 //================================================================================
287 * \brief Remove all nodes and elements for indicated shape
289 //================================================================================
291 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
292 throw (SALOME::SALOME_Exception)
294 Unexpect aCatch(SALOME_SalomeException);
296 _preMeshInfo->FullLoadFromFile();
299 _impl->ClearSubMesh( ShapeID );
301 catch(SALOME_Exception & S_ex) {
302 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
306 //=============================================================================
310 //=============================================================================
312 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
314 SMESH::DriverMED_ReadStatus res;
317 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
318 res = SMESH::DRS_OK; break;
319 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
320 res = SMESH::DRS_EMPTY; break;
321 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
322 res = SMESH::DRS_WARN_RENUMBER; break;
323 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
324 res = SMESH::DRS_WARN_SKIP_ELEM; break;
325 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
327 res = SMESH::DRS_FAIL; break;
332 //=============================================================================
336 * Imports mesh data from MED file
338 //=============================================================================
340 SMESH::DriverMED_ReadStatus
341 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
342 throw ( SALOME::SALOME_Exception )
344 Unexpect aCatch(SALOME_SalomeException);
347 status = _impl->MEDToMesh( theFileName, theMeshName );
349 catch( SALOME_Exception& S_ex ) {
350 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
353 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
356 CreateGroupServants();
358 int major, minor, release;
359 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
360 major = minor = release = -1;
361 _medFileInfo = new SALOME_MED::MedFileInfo();
362 _medFileInfo->fileName = theFileName;
363 _medFileInfo->fileSize = 0;
366 if ( ::_stati64( theFileName, &d ) != -1 )
369 if ( ::stat64( theFileName, &d ) != -1 )
371 _medFileInfo->fileSize = d.st_size;
372 _medFileInfo->major = major;
373 _medFileInfo->minor = minor;
374 _medFileInfo->release = release;
376 return ConvertDriverMEDReadStatus(status);
379 //================================================================================
381 * \brief Imports mesh data from the CGNS file
383 //================================================================================
385 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
386 const int theMeshIndex,
387 std::string& theMeshName )
388 throw ( SALOME::SALOME_Exception )
390 Unexpect aCatch(SALOME_SalomeException);
393 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
395 catch( SALOME_Exception& S_ex ) {
396 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
399 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
402 CreateGroupServants();
404 return ConvertDriverMEDReadStatus(status);
407 //================================================================================
409 * \brief Return string representation of a MED file version comprising nbDigits
411 //================================================================================
413 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
415 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
417 return CORBA::string_dup( ver.c_str() );
420 //=============================================================================
424 * Imports mesh data from MED file
426 //=============================================================================
428 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
429 throw ( SALOME::SALOME_Exception )
431 // Read mesh with name = <theMeshName> into SMESH_Mesh
432 _impl->UNVToMesh( theFileName );
434 CreateGroupServants();
439 //=============================================================================
443 * Imports mesh data from STL file
445 //=============================================================================
446 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
447 throw ( SALOME::SALOME_Exception )
449 // Read mesh with name = <theMeshName> into SMESH_Mesh
450 _impl->STLToMesh( theFileName );
455 //=============================================================================
459 //=============================================================================
461 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
463 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
464 (SMESH_Hypothesis::Hypothesis_Status theStatus)
467 RETURNCASE( HYP_OK );
468 RETURNCASE( HYP_MISSING );
469 RETURNCASE( HYP_CONCURENT );
470 RETURNCASE( HYP_BAD_PARAMETER );
471 RETURNCASE( HYP_HIDDEN_ALGO );
472 RETURNCASE( HYP_HIDING_ALGO );
473 RETURNCASE( HYP_UNKNOWN_FATAL );
474 RETURNCASE( HYP_INCOMPATIBLE );
475 RETURNCASE( HYP_NOTCONFORM );
476 RETURNCASE( HYP_ALREADY_EXIST );
477 RETURNCASE( HYP_BAD_DIM );
478 RETURNCASE( HYP_BAD_SUBSHAPE );
479 RETURNCASE( HYP_BAD_GEOMETRY );
480 RETURNCASE( HYP_NEED_SHAPE );
483 return SMESH::HYP_UNKNOWN_FATAL;
486 //=============================================================================
490 * calls internal addHypothesis() and then adds a reference to <anHyp> under
491 * the SObject actually having a reference to <aSubShape>.
492 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
494 //=============================================================================
496 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
497 SMESH::SMESH_Hypothesis_ptr anHyp)
498 throw(SALOME::SALOME_Exception)
500 Unexpect aCatch(SALOME_SalomeException);
502 _preMeshInfo->ForgetOrLoad();
504 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
506 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
507 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
508 aSubShapeObject, anHyp );
510 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
512 // Update Python script
513 if(_impl->HasShapeToMesh()) {
514 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
515 << aSubShapeObject << ", " << anHyp << " )";
518 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
521 return ConvertHypothesisStatus(status);
524 //=============================================================================
528 //=============================================================================
530 SMESH_Hypothesis::Hypothesis_Status
531 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
532 SMESH::SMESH_Hypothesis_ptr anHyp)
534 if(MYDEBUG) MESSAGE("addHypothesis");
536 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
537 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
540 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
541 if (CORBA::is_nil(myHyp))
542 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
545 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
548 TopoDS_Shape myLocSubShape;
549 //use PseudoShape in case if mesh has no shape
551 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
553 myLocSubShape = _impl->GetShapeToMesh();
555 int hypId = myHyp->GetId();
556 status = _impl->AddHypothesis(myLocSubShape, hypId);
557 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
558 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
559 #ifdef WITHGENERICOBJ
560 _mapHypo[hypId]->Register();
562 // assure there is a corresponding submesh
563 if ( !_impl->IsMainShape( myLocSubShape )) {
564 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
565 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
566 createSubMesh( aSubShapeObject );
570 catch(SALOME_Exception & S_ex)
572 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
577 //=============================================================================
581 //=============================================================================
583 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
584 SMESH::SMESH_Hypothesis_ptr anHyp)
585 throw(SALOME::SALOME_Exception)
587 Unexpect aCatch(SALOME_SalomeException);
589 _preMeshInfo->ForgetOrLoad();
591 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
593 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
594 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
595 aSubShapeObject, anHyp );
597 // Update Python script
598 // Update Python script
599 if(_impl->HasShapeToMesh()) {
600 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
601 << aSubShapeObject << ", " << anHyp << " )";
604 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
608 return ConvertHypothesisStatus(status);
611 //=============================================================================
615 //=============================================================================
617 SMESH_Hypothesis::Hypothesis_Status
618 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
619 SMESH::SMESH_Hypothesis_ptr anHyp)
621 if(MYDEBUG) MESSAGE("removeHypothesis()");
622 // **** proposer liste de sub-shape (selection multiple)
624 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
625 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
627 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
628 if (CORBA::is_nil(myHyp))
629 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
631 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
634 TopoDS_Shape myLocSubShape;
635 //use PseudoShape in case if mesh has no shape
637 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
639 myLocSubShape = _impl->GetShapeToMesh();
641 int hypId = myHyp->GetId();
642 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
643 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
644 // _mapHypo.erase( hypId );
646 catch(SALOME_Exception & S_ex)
648 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
653 //=============================================================================
657 //=============================================================================
659 SMESH::ListOfHypothesis *
660 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
661 throw(SALOME::SALOME_Exception)
663 Unexpect aCatch(SALOME_SalomeException);
664 if (MYDEBUG) MESSAGE("GetHypothesisList");
665 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
666 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
668 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
671 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
672 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
673 myLocSubShape = _impl->GetShapeToMesh();
674 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
675 int i = 0, n = aLocalList.size();
678 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
679 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
680 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
681 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
686 catch(SALOME_Exception & S_ex) {
687 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
690 return aList._retn();
693 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
695 Unexpect aCatch(SALOME_SalomeException);
696 if (MYDEBUG) MESSAGE("GetSubMeshes");
698 SMESH::submesh_array_var aList = new SMESH::submesh_array();
701 TPythonDump aPythonDump;
702 if ( !_mapSubMeshIor.empty() )
706 aList->length( _mapSubMeshIor.size() );
708 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
709 for ( ; it != _mapSubMeshIor.end(); it++ ) {
710 if ( CORBA::is_nil( it->second )) continue;
711 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
713 if (i > 1) aPythonDump << ", ";
714 aPythonDump << it->second;
718 catch(SALOME_Exception & S_ex) {
719 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
722 // Update Python script
723 if ( !_mapSubMeshIor.empty() )
724 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
726 return aList._retn();
729 //=============================================================================
733 //=============================================================================
734 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
735 const char* theName )
736 throw(SALOME::SALOME_Exception)
738 Unexpect aCatch(SALOME_SalomeException);
739 MESSAGE("SMESH_Mesh_i::GetSubMesh");
740 if (CORBA::is_nil(aSubShapeObject))
741 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
744 SMESH::SMESH_subMesh_var subMesh;
745 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
747 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
749 //Get or Create the SMESH_subMesh object implementation
751 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
753 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
755 TopoDS_Iterator it( myLocSubShape );
757 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
759 subMesh = getSubMesh( subMeshId );
761 // create a new subMesh object servant if there is none for the shape
762 if ( subMesh->_is_nil() )
763 subMesh = createSubMesh( aSubShapeObject );
764 if ( _gen_i->CanPublishInStudy( subMesh )) {
765 SALOMEDS::SObject_var aSO =
766 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
767 subMesh, aSubShapeObject, theName );
768 if ( !aSO->_is_nil()) {
769 // Update Python script
770 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
771 << aSubShapeObject << ", '" << theName << "' )";
775 catch(SALOME_Exception & S_ex) {
776 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
778 return subMesh._retn();
781 //=============================================================================
785 //=============================================================================
787 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
788 throw (SALOME::SALOME_Exception)
790 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
791 if ( theSubMesh->_is_nil() )
794 GEOM::GEOM_Object_var aSubShapeObject;
795 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
796 if ( !aStudy->_is_nil() ) {
797 // Remove submesh's SObject
798 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
799 if ( !anSO->_is_nil() ) {
800 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
801 SALOMEDS::SObject_var anObj, aRef;
802 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
803 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
805 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
806 // aSubShapeObject = theSubMesh->GetSubShape();
808 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
810 // Update Python script
811 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
815 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
817 _preMeshInfo->ForgetOrLoad();
820 //=============================================================================
824 //=============================================================================
826 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
827 const char* theName )
828 throw(SALOME::SALOME_Exception)
830 Unexpect aCatch(SALOME_SalomeException);
832 _preMeshInfo->FullLoadFromFile();
834 SMESH::SMESH_Group_var aNewGroup =
835 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
837 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
838 SALOMEDS::SObject_var aSO =
839 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
840 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
841 if ( !aSO->_is_nil()) {
842 // Update Python script
843 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
844 << theElemType << ", '" << theName << "' )";
847 return aNewGroup._retn();
851 //=============================================================================
855 //=============================================================================
856 SMESH::SMESH_GroupOnGeom_ptr
857 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
859 GEOM::GEOM_Object_ptr theGeomObj)
860 throw(SALOME::SALOME_Exception)
862 Unexpect aCatch(SALOME_SalomeException);
864 _preMeshInfo->FullLoadFromFile();
866 SMESH::SMESH_GroupOnGeom_var aNewGroup;
868 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
869 if ( !aShape.IsNull() )
871 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
872 ( createGroup( theElemType, theName, aShape ));
874 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
875 SALOMEDS::SObject_var aSO =
876 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
877 aNewGroup, theGeomObj, theName);
878 if ( !aSO->_is_nil()) {
879 // Update Python script
880 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
881 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
886 return aNewGroup._retn();
889 //================================================================================
891 * \brief Creates a group whose contents is defined by filter
892 * \param theElemType - group type
893 * \param theName - group name
894 * \param theFilter - the filter
895 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
897 //================================================================================
899 SMESH::SMESH_GroupOnFilter_ptr
900 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
902 SMESH::Filter_ptr theFilter )
903 throw (SALOME::SALOME_Exception)
905 Unexpect aCatch(SALOME_SalomeException);
907 _preMeshInfo->FullLoadFromFile();
909 if ( CORBA::is_nil( theFilter ))
910 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
912 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
914 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
916 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
917 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
920 if ( !aNewGroup->_is_nil() )
921 aNewGroup->SetFilter( theFilter );
923 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
925 SALOMEDS::SObject_var aSO =
926 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
927 GEOM::GEOM_Object::_nil(), theName);
928 if ( !aSO->_is_nil()) {
929 // Update Python script
930 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
931 << theElemType << ", '" << theName << "', " << theFilter << " )";
935 return aNewGroup._retn();
938 //=============================================================================
942 //=============================================================================
944 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
945 throw (SALOME::SALOME_Exception)
947 if ( theGroup->_is_nil() )
950 SMESH_GroupBase_i* aGroup =
951 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
955 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
956 if ( !aStudy->_is_nil() ) {
957 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
959 if ( !aGroupSO->_is_nil() ) {
960 // Update Python script
961 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
963 // Remove group's SObject
964 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
968 // Remove the group from SMESH data structures
969 removeGroup( aGroup->GetLocalID() );
972 //=============================================================================
974 * Remove group with its contents
976 //=============================================================================
978 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
979 throw (SALOME::SALOME_Exception)
982 _preMeshInfo->FullLoadFromFile();
984 if ( theGroup->_is_nil() )
987 SMESH_GroupBase_i* aGroup =
988 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
992 SMESH::long_array_var anIds = aGroup->GetListOfID();
993 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
995 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
998 if ( aGroup->GetType() == SMESH::NODE )
999 aMeshEditor->RemoveNodes( anIds );
1001 aMeshEditor->RemoveElements( anIds );
1004 RemoveGroup( theGroup );
1006 // Update Python script
1007 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
1010 //================================================================================
1012 * \brief Get the list of groups existing in the mesh
1013 * \retval SMESH::ListOfGroups * - list of groups
1015 //================================================================================
1017 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1019 Unexpect aCatch(SALOME_SalomeException);
1020 if (MYDEBUG) MESSAGE("GetGroups");
1022 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1025 TPythonDump aPythonDump;
1026 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1027 aPythonDump << "[ ";
1030 aList->length( _mapGroups.size() );
1032 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1033 for ( ; it != _mapGroups.end(); it++ ) {
1034 if ( CORBA::is_nil( it->second )) continue;
1035 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1037 if (i > 1) aPythonDump << ", ";
1038 aPythonDump << it->second;
1042 catch(SALOME_Exception & S_ex) {
1043 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1046 // Update Python script
1047 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1048 aPythonDump << " ] = " << _this() << ".GetGroups()";
1050 return aList._retn();
1053 //=============================================================================
1055 * Get number of groups existing in the mesh
1057 //=============================================================================
1059 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1061 Unexpect aCatch(SALOME_SalomeException);
1062 return _mapGroups.size();
1065 //=============================================================================
1067 * New group is created. All mesh elements that are
1068 * present in initial groups are added to the new one
1070 //=============================================================================
1071 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1072 SMESH::SMESH_GroupBase_ptr theGroup2,
1073 const char* theName )
1074 throw (SALOME::SALOME_Exception)
1077 _preMeshInfo->FullLoadFromFile();
1081 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1082 theGroup1->GetType() != theGroup2->GetType() )
1083 return SMESH::SMESH_Group::_nil();
1086 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1087 if ( aResGrp->_is_nil() )
1088 return SMESH::SMESH_Group::_nil();
1090 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1091 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1093 TColStd_MapOfInteger aResMap;
1095 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1096 aResMap.Add( anIds1[ i1 ] );
1098 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1099 aResMap.Add( anIds2[ i2 ] );
1101 SMESH::long_array_var aResIds = new SMESH::long_array;
1102 aResIds->length( aResMap.Extent() );
1105 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1106 for( ; anIter.More(); anIter.Next() )
1107 aResIds[ resI++ ] = anIter.Key();
1109 aResGrp->Add( aResIds );
1111 // Clear python lines, created by CreateGroup() and Add()
1112 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1113 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1114 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1116 // Update Python script
1117 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
1118 << theGroup1 << ", " << theGroup2 << ", '"
1119 << theName << "' )";
1121 return aResGrp._retn();
1125 return SMESH::SMESH_Group::_nil();
1129 //=============================================================================
1131 \brief Union list of groups. New group is created. All mesh elements that are
1132 present in initial groups are added to the new one.
1133 \param theGroups list of groups
1134 \param theName name of group to be created
1135 \return pointer on the group
1137 //=============================================================================
1138 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1139 const char* theName )
1140 throw (SALOME::SALOME_Exception)
1143 _preMeshInfo->FullLoadFromFile();
1146 return SMESH::SMESH_Group::_nil();
1150 vector< int > anIds;
1151 SMESH::ElementType aType = SMESH::ALL;
1152 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1154 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1155 if ( CORBA::is_nil( aGrp ) )
1159 SMESH::ElementType aCurrType = aGrp->GetType();
1160 if ( aType == SMESH::ALL )
1164 if ( aType != aCurrType )
1165 return SMESH::SMESH_Group::_nil();
1169 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1170 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1172 int aCurrId = aCurrIds[ i ];
1173 anIds.push_back( aCurrId );
1178 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1179 if ( aResGrp->_is_nil() )
1180 return SMESH::SMESH_Group::_nil();
1182 // Create array of identifiers
1183 SMESH::long_array_var aResIds = new SMESH::long_array;
1184 aResIds->length( anIds.size() );
1186 //NCollection_Map< int >::Iterator anIter( anIds );
1187 for ( int i = 0; i<anIds.size(); i++ )
1189 aResIds[ i ] = anIds[i];
1191 aResGrp->Add( aResIds );
1193 // Clear python lines, created by CreateGroup() and Add()
1194 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1195 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1196 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1198 // Update Python script
1200 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1201 << &theGroups << ", '" << theName << "' )";
1203 return aResGrp._retn();
1207 return SMESH::SMESH_Group::_nil();
1211 //=============================================================================
1213 * New group is created. All mesh elements that are
1214 * present in both initial groups are added to the new one.
1216 //=============================================================================
1217 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1218 SMESH::SMESH_GroupBase_ptr theGroup2,
1219 const char* theName )
1220 throw (SALOME::SALOME_Exception)
1223 _preMeshInfo->FullLoadFromFile();
1225 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1226 theGroup1->GetType() != theGroup2->GetType() )
1227 return SMESH::SMESH_Group::_nil();
1229 // Create Intersection
1230 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1231 if ( aResGrp->_is_nil() )
1234 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1235 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1237 TColStd_MapOfInteger aMap1;
1239 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1240 aMap1.Add( anIds1[ i1 ] );
1242 TColStd_SequenceOfInteger aSeq;
1244 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1245 if ( aMap1.Contains( anIds2[ i2 ] ) )
1246 aSeq.Append( anIds2[ i2 ] );
1248 SMESH::long_array_var aResIds = new SMESH::long_array;
1249 aResIds->length( aSeq.Length() );
1251 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1252 aResIds[ resI ] = aSeq( resI + 1 );
1254 aResGrp->Add( aResIds );
1256 // Clear python lines, created by CreateGroup() and Add()
1257 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1258 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1259 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1261 // Update Python script
1262 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1263 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1265 return aResGrp._retn();
1268 //=============================================================================
1270 \brief Intersect list of groups. New group is created. All mesh elements that
1271 are present in all initial groups simultaneously are added to the new one.
1272 \param theGroups list of groups
1273 \param theName name of group to be created
1274 \return pointer on the group
1276 //=============================================================================
1277 SMESH::SMESH_Group_ptr
1278 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1279 const char* theName )
1280 throw (SALOME::SALOME_Exception)
1283 _preMeshInfo->FullLoadFromFile();
1286 return SMESH::SMESH_Group::_nil();
1290 NCollection_DataMap< int, int > anIdToCount;
1291 SMESH::ElementType aType = SMESH::ALL;
1292 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1294 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1295 if ( CORBA::is_nil( aGrp ) )
1299 SMESH::ElementType aCurrType = aGrp->GetType();
1300 if ( aType == SMESH::ALL )
1304 if ( aType != aCurrType )
1305 return SMESH::SMESH_Group::_nil();
1308 // calculates number of occurance ids in groups
1309 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1310 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1312 int aCurrId = aCurrIds[ i ];
1313 if ( !anIdToCount.IsBound( aCurrId ) )
1314 anIdToCount.Bind( aCurrId, 1 );
1316 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1320 // create map of ids
1321 int nbGrp = theGroups.length();
1322 vector< int > anIds;
1323 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1324 for ( ; anIter.More(); anIter.Next() )
1326 int aCurrId = anIter.Key();
1327 int aCurrNb = anIter.Value();
1328 if ( aCurrNb == nbGrp )
1329 anIds.push_back( aCurrId );
1333 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1334 if ( aResGrp->_is_nil() )
1335 return SMESH::SMESH_Group::_nil();
1337 // Create array of identifiers
1338 SMESH::long_array_var aResIds = new SMESH::long_array;
1339 aResIds->length( anIds.size() );
1341 //NCollection_Map< int >::Iterator aListIter( anIds );
1342 for ( int i = 0; i<anIds.size(); i++ )
1344 aResIds[ i ] = anIds[i];
1346 aResGrp->Add( aResIds );
1348 // Clear python lines, created by CreateGroup() and Add()
1349 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1350 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1351 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1353 // Update Python script
1355 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1356 << &theGroups << ", '" << theName << "' )";
1358 return aResGrp._retn();
1362 return SMESH::SMESH_Group::_nil();
1366 //=============================================================================
1368 * New group is created. All mesh elements that are present in
1369 * main group but do not present in tool group are added to the new one
1371 //=============================================================================
1372 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1373 SMESH::SMESH_GroupBase_ptr theGroup2,
1374 const char* theName )
1375 throw (SALOME::SALOME_Exception)
1378 _preMeshInfo->FullLoadFromFile();
1380 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1381 theGroup1->GetType() != theGroup2->GetType() )
1382 return SMESH::SMESH_Group::_nil();
1385 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1386 if ( aResGrp->_is_nil() )
1389 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1390 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1392 TColStd_MapOfInteger aMap2;
1394 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1395 aMap2.Add( anIds2[ i2 ] );
1397 TColStd_SequenceOfInteger aSeq;
1398 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1399 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1400 aSeq.Append( anIds1[ i1 ] );
1402 SMESH::long_array_var aResIds = new SMESH::long_array;
1403 aResIds->length( aSeq.Length() );
1405 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1406 aResIds[ resI ] = aSeq( resI + 1 );
1408 aResGrp->Add( aResIds );
1410 // Clear python lines, created by CreateGroup() and Add()
1411 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1412 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1413 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1415 // Update Python script
1416 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1417 << theGroup1 << ", " << theGroup2 << ", '"
1418 << theName << "' )";
1420 return aResGrp._retn();
1423 //=============================================================================
1425 \brief Cut lists of groups. New group is created. All mesh elements that are
1426 present in main groups but do not present in tool groups are added to the new one
1427 \param theMainGroups list of main groups
1428 \param theToolGroups list of tool groups
1429 \param theName name of group to be created
1430 \return pointer on the group
1432 //=============================================================================
1433 SMESH::SMESH_Group_ptr
1434 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1435 const SMESH::ListOfGroups& theToolGroups,
1436 const char* theName )
1437 throw (SALOME::SALOME_Exception)
1440 _preMeshInfo->FullLoadFromFile();
1443 return SMESH::SMESH_Group::_nil();
1447 set< int > aToolIds;
1448 SMESH::ElementType aType = SMESH::ALL;
1450 // iterate through tool groups
1451 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1453 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1454 if ( CORBA::is_nil( aGrp ) )
1458 SMESH::ElementType aCurrType = aGrp->GetType();
1459 if ( aType == SMESH::ALL )
1463 if ( aType != aCurrType )
1464 return SMESH::SMESH_Group::_nil();
1468 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1469 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1471 int aCurrId = aCurrIds[ i ];
1472 aToolIds.insert( aCurrId );
1476 vector< int > anIds; // result
1478 // Iterate through main group
1479 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1481 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1482 if ( CORBA::is_nil( aGrp ) )
1486 SMESH::ElementType aCurrType = aGrp->GetType();
1487 if ( aType == SMESH::ALL )
1491 if ( aType != aCurrType )
1492 return SMESH::SMESH_Group::_nil();
1496 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1497 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1499 int aCurrId = aCurrIds[ i ];
1500 if ( !aToolIds.count( aCurrId ) )
1501 anIds.push_back( aCurrId );
1506 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1507 if ( aResGrp->_is_nil() )
1508 return SMESH::SMESH_Group::_nil();
1510 // Create array of identifiers
1511 SMESH::long_array_var aResIds = new SMESH::long_array;
1512 aResIds->length( anIds.size() );
1514 for (int i=0; i<anIds.size(); i++ )
1516 aResIds[ i ] = anIds[i];
1518 aResGrp->Add( aResIds );
1520 // Clear python lines, created by CreateGroup() and Add()
1521 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1522 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1523 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1525 // Update Python script
1527 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1528 << &theMainGroups << ", " << &theToolGroups << ", '"
1529 << theName << "' )";
1531 return aResGrp._retn();
1535 return SMESH::SMESH_Group::_nil();
1539 //=============================================================================
1541 \brief Create groups of entities from existing groups of superior dimensions
1543 1) extract all nodes from each group,
1544 2) combine all elements of specified dimension laying on these nodes.
1545 \param theGroups list of source groups
1546 \param theElemType dimension of elements
1547 \param theName name of new group
1548 \return pointer on new group
1550 //=============================================================================
1551 SMESH::SMESH_Group_ptr
1552 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1553 SMESH::ElementType theElemType,
1554 const char* theName )
1555 throw (SALOME::SALOME_Exception)
1558 _preMeshInfo->FullLoadFromFile();
1560 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1562 if ( !theName || !aMeshDS )
1563 return SMESH::SMESH_Group::_nil();
1565 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1569 // Create map of nodes from all groups
1571 set< int > aNodeMap;
1573 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1575 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1576 if ( CORBA::is_nil( aGrp ) )
1579 SMESH::ElementType aType = aGrp->GetType();
1580 if ( aType == SMESH::ALL )
1582 else if ( aType == SMESH::NODE )
1584 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1585 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1587 int aCurrId = aCurrIds[ i ];
1588 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1590 aNodeMap.insert( aNode->GetID() );
1595 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1596 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1598 int aCurrId = aCurrIds[ i ];
1599 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1602 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1603 while( aNodeIter->more() )
1605 const SMDS_MeshNode* aNode =
1606 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1608 aNodeMap.insert( aNode->GetID() );
1614 // Get result identifiers
1616 vector< int > aResultIds;
1617 if ( theElemType == SMESH::NODE )
1619 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1620 set<int>::iterator iter = aNodeMap.begin();
1621 for ( ; iter != aNodeMap.end(); iter++ )
1622 aResultIds.push_back( *iter);
1626 // Create list of elements of given dimension constructed on the nodes
1627 vector< int > anElemList;
1628 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1629 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1630 set<int>::iterator iter = aNodeMap.begin();
1631 for ( ; iter != aNodeMap.end(); iter++ )
1633 const SMDS_MeshElement* aNode =
1634 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1638 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1639 while( anElemIter->more() )
1641 const SMDS_MeshElement* anElem =
1642 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1643 if ( anElem && anElem->GetType() == anElemType )
1644 anElemList.push_back( anElem->GetID() );
1648 // check whether all nodes of elements are present in nodes map
1649 for (int i=0; i< anElemList.size(); i++)
1651 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1656 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1657 while( aNodeIter->more() )
1659 const SMDS_MeshNode* aNode =
1660 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1661 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1668 aResultIds.push_back( anElem->GetID() );
1674 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1675 if ( aResGrp->_is_nil() )
1676 return SMESH::SMESH_Group::_nil();
1678 // Create array of identifiers
1679 SMESH::long_array_var aResIds = new SMESH::long_array;
1680 aResIds->length( aResultIds.size() );
1682 for (int i=0; i< aResultIds.size(); i++)
1683 aResIds[ i ] = aResultIds[i];
1684 aResGrp->Add( aResIds );
1686 // Remove strings corresponding to group creation
1687 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1688 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1689 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1691 // Update Python script
1693 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1694 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1696 return aResGrp._retn();
1700 return SMESH::SMESH_Group::_nil();
1704 //================================================================================
1706 * \brief Remember GEOM group data
1708 //================================================================================
1710 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1711 CORBA::Object_ptr theSmeshObj)
1713 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1716 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1717 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1718 if ( groupSO->_is_nil() )
1721 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1722 GEOM::GEOM_IGroupOperations_var groupOp =
1723 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1724 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1727 _geomGroupData.push_back( TGeomGroupData() );
1728 TGeomGroupData & groupData = _geomGroupData.back();
1730 CORBA::String_var entry = groupSO->GetID();
1731 groupData._groupEntry = entry.in();
1733 for ( int i = 0; i < ids->length(); ++i )
1734 groupData._indices.insert( ids[i] );
1736 groupData._smeshObject = theSmeshObj;
1739 //================================================================================
1741 * Remove GEOM group data relating to removed smesh object
1743 //================================================================================
1745 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1747 list<TGeomGroupData>::iterator
1748 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1749 for ( ; data != dataEnd; ++data ) {
1750 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1751 _geomGroupData.erase( data );
1757 //================================================================================
1759 * \brief Return new group contents if it has been changed and update group data
1761 //================================================================================
1763 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1765 TopoDS_Shape newShape;
1768 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1769 if ( study->_is_nil() ) return newShape; // means "not changed"
1770 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1771 if ( !groupSO->_is_nil() )
1773 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1774 if ( CORBA::is_nil( groupObj )) return newShape;
1775 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1777 // get indices of group items
1778 set<int> curIndices;
1779 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1780 GEOM::GEOM_IGroupOperations_var groupOp =
1781 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1782 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1783 for ( int i = 0; i < ids->length(); ++i )
1784 curIndices.insert( ids[i] );
1786 if ( groupData._indices == curIndices )
1787 return newShape; // group not changed
1790 groupData._indices = curIndices;
1792 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1793 if ( !geomClient ) return newShape;
1794 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1795 geomClient->RemoveShapeFromBuffer( groupIOR );
1796 newShape = _gen_i->GeomObjectToShape( geomGroup );
1799 if ( newShape.IsNull() ) {
1800 // geom group becomes empty - return empty compound
1801 TopoDS_Compound compound;
1802 BRep_Builder().MakeCompound(compound);
1803 newShape = compound;
1810 //=============================================================================
1812 * \brief Storage of shape and index used in CheckGeomGroupModif()
1814 //=============================================================================
1815 struct TIndexedShape
1818 TopoDS_Shape _shape;
1819 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1822 //=============================================================================
1824 * \brief Update objects depending on changed geom groups
1826 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1827 * issue 0020210: Update of a smesh group after modification of the associated geom group
1829 //=============================================================================
1831 void SMESH_Mesh_i::CheckGeomGroupModif()
1833 if ( !_impl->HasShapeToMesh() ) return;
1835 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1836 if ( study->_is_nil() ) return;
1838 CORBA::Long nbEntities = NbNodes() + NbElements();
1840 // Check if group contents changed
1842 typedef map< string, TopoDS_Shape > TEntry2Geom;
1843 TEntry2Geom newGroupContents;
1845 list<TGeomGroupData>::iterator
1846 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1847 for ( ; data != dataEnd; ++data )
1849 pair< TEntry2Geom::iterator, bool > it_new =
1850 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1851 bool processedGroup = !it_new.second;
1852 TopoDS_Shape& newShape = it_new.first->second;
1853 if ( !processedGroup )
1854 newShape = newGroupShape( *data );
1855 if ( newShape.IsNull() )
1856 continue; // no changes
1859 _preMeshInfo->ForgetOrLoad();
1861 if ( processedGroup ) { // update group indices
1862 list<TGeomGroupData>::iterator data2 = data;
1863 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1864 data->_indices = data2->_indices;
1867 // Update SMESH objects according to new GEOM group contents
1869 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1870 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1872 int oldID = submesh->GetId();
1873 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1875 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1877 // update hypotheses
1878 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1879 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1880 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1882 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1883 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1885 // care of submeshes
1886 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1887 int newID = newSubmesh->GetId();
1888 if ( newID != oldID ) {
1889 _mapSubMesh [ newID ] = newSubmesh;
1890 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1891 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1892 _mapSubMesh. erase(oldID);
1893 _mapSubMesh_i. erase(oldID);
1894 _mapSubMeshIor.erase(oldID);
1895 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1900 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1901 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1902 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1904 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1906 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1907 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1908 ds->SetShape( newShape );
1913 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1914 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1916 // Remove groups and submeshes basing on removed sub-shapes
1918 TopTools_MapOfShape newShapeMap;
1919 TopoDS_Iterator shapeIt( newShape );
1920 for ( ; shapeIt.More(); shapeIt.Next() )
1921 newShapeMap.Add( shapeIt.Value() );
1923 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1924 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1926 if ( newShapeMap.Contains( shapeIt.Value() ))
1928 TopTools_IndexedMapOfShape oldShapeMap;
1929 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1930 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1932 const TopoDS_Shape& oldShape = oldShapeMap(i);
1933 int oldInd = meshDS->ShapeToIndex( oldShape );
1935 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1936 if ( i_smIor != _mapSubMeshIor.end() ) {
1937 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1940 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1941 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1943 // check if a group bases on oldInd shape
1944 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1945 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1946 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1947 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1949 RemoveGroup( i_grp->second ); // several groups can base on same shape
1950 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1955 // Reassign hypotheses and update groups after setting the new shape to mesh
1957 // collect anassigned hypotheses
1958 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1959 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1960 TShapeHypList assignedHyps;
1961 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1963 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1964 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1965 if ( !hyps.empty() ) {
1966 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1967 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1968 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1971 // collect shapes supporting groups
1972 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1973 TShapeTypeList groupData;
1974 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1975 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1976 for ( ; grIt != groups.end(); ++grIt )
1978 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1980 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1982 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1983 _impl->ShapeToMesh( newShape );
1985 // reassign hypotheses
1986 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1987 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1989 TIndexedShape& geom = indS_hyps->first;
1990 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1991 int oldID = geom._index;
1992 int newID = meshDS->ShapeToIndex( geom._shape );
1995 if ( oldID == 1 ) { // main shape
1997 geom._shape = newShape;
1999 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2000 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2001 // care of submeshes
2002 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2003 if ( newID != oldID ) {
2004 _mapSubMesh [ newID ] = newSubmesh;
2005 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2006 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2007 _mapSubMesh. erase(oldID);
2008 _mapSubMesh_i. erase(oldID);
2009 _mapSubMeshIor.erase(oldID);
2010 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2014 TShapeTypeList::iterator geomType = groupData.begin();
2015 for ( ; geomType != groupData.end(); ++geomType )
2017 const TIndexedShape& geom = geomType->first;
2018 int oldID = geom._index;
2019 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2022 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2023 CORBA::String_var name = groupSO->GetName();
2025 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2027 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2028 group_i->changeLocalId( newID );
2031 break; // everything has been updated
2034 } // loop on group data
2038 CORBA::Long newNbEntities = NbNodes() + NbElements();
2039 list< SALOMEDS::SObject_var > soToUpdateIcons;
2040 if ( newNbEntities != nbEntities )
2042 // Add all SObjects with icons to soToUpdateIcons
2043 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2045 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2046 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2047 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2049 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2050 i_gr != _mapGroups.end(); ++i_gr ) // groups
2051 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2054 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
2055 for ( ; so != soToUpdateIcons.end(); ++so )
2056 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2059 //=============================================================================
2061 * \brief Create standalone group from a group on geometry or filter
2063 //=============================================================================
2065 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2068 _preMeshInfo->FullLoadFromFile();
2070 SMESH::SMESH_Group_var aGroup;
2071 if ( theGroup->_is_nil() )
2072 return aGroup._retn();
2074 Unexpect aCatch(SALOME_SalomeException);
2076 SMESH_GroupBase_i* aGroupToRem =
2077 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2079 return aGroup._retn();
2081 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2083 int anId = aGroupToRem->GetLocalID();
2084 if ( !_impl->ConvertToStandalone( anId ) )
2085 return aGroup._retn();
2086 removeGeomGroupData( theGroup );
2088 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2090 // remove old instance of group from own map
2091 _mapGroups.erase( anId );
2093 SALOMEDS::StudyBuilder_var builder;
2094 SALOMEDS::SObject_var aGroupSO;
2095 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2096 if ( !aStudy->_is_nil() ) {
2097 builder = aStudy->NewBuilder();
2098 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2099 if ( !aGroupSO->_is_nil() ) {
2101 // remove reference to geometry
2102 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
2103 for ( ; chItr->More(); chItr->Next() )
2104 // Remove group's child SObject
2105 builder->RemoveObject( chItr->Value() );
2107 // Update Python script
2108 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2109 << aGroupSO << " )";
2111 // change icon of Group on Filter
2114 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2115 const int isEmpty = ( elemTypes->length() == 0 );
2118 SALOMEDS::GenericAttribute_var anAttr =
2119 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2120 SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
2121 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2127 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2128 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2129 aGroupImpl->Register();
2130 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2132 // remember new group in own map
2133 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2134 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2136 // register CORBA object for persistence
2137 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
2139 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
2141 return aGroup._retn();
2144 //=============================================================================
2148 //=============================================================================
2150 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2152 if(MYDEBUG) MESSAGE( "createSubMesh" );
2153 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2155 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2156 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2157 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2158 SMESH::SMESH_subMesh_var subMesh
2159 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2161 _mapSubMesh[subMeshId] = mySubMesh;
2162 _mapSubMesh_i[subMeshId] = subMeshServant;
2163 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2165 // register CORBA object for persistence
2166 int nextId = _gen_i->RegisterObject( subMesh );
2167 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2169 // to track changes of GEOM groups
2170 addGeomGroupData( theSubShapeObject, subMesh );
2172 return subMesh._retn();
2175 //=======================================================================
2176 //function : getSubMesh
2178 //=======================================================================
2180 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2182 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2183 if ( it == _mapSubMeshIor.end() )
2184 return SMESH::SMESH_subMesh::_nil();
2186 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2190 //=============================================================================
2194 //=============================================================================
2196 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2197 GEOM::GEOM_Object_ptr theSubShapeObject )
2199 bool isHypChanged = false;
2200 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2201 return isHypChanged;
2203 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2205 CORBA::Long shapeId = theSubMesh->GetId();
2206 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2208 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2211 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2212 isHypChanged = !hyps.empty();
2213 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2214 for ( ; hyp != hyps.end(); ++hyp )
2215 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2222 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2223 isHypChanged = ( aHypList->length() > 0 );
2224 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2225 removeHypothesis( theSubShapeObject, aHypList[i] );
2228 catch( const SALOME::SALOME_Exception& ) {
2229 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2231 removeGeomGroupData( theSubShapeObject );
2233 int subMeshId = theSubMesh->GetId();
2235 _mapSubMesh.erase(subMeshId);
2236 _mapSubMesh_i.erase(subMeshId);
2237 _mapSubMeshIor.erase(subMeshId);
2239 return isHypChanged;
2242 //=============================================================================
2246 //=============================================================================
2248 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2249 const char* theName,
2250 const TopoDS_Shape& theShape,
2251 const SMESH_PredicatePtr& thePredicate )
2253 std::string newName;
2254 if ( !theName || strlen( theName ) == 0 )
2256 std::set< std::string > presentNames;
2257 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2258 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2259 presentNames.insert( i_gr->second->GetName() );
2261 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2262 } while ( !presentNames.insert( newName ).second );
2263 theName = newName.c_str();
2266 SMESH::SMESH_GroupBase_var aGroup;
2267 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2269 SMESH_GroupBase_i* aGroupImpl;
2270 if ( !theShape.IsNull() )
2271 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2272 else if ( thePredicate )
2273 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2275 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2277 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2278 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2279 aGroupImpl->Register();
2280 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2282 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2283 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2285 // register CORBA object for persistence
2286 int nextId = _gen_i->RegisterObject( aGroup );
2287 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2289 // to track changes of GEOM groups
2290 if ( !theShape.IsNull() ) {
2291 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2292 addGeomGroupData( geom, aGroup );
2295 return aGroup._retn();
2298 //=============================================================================
2300 * SMESH_Mesh_i::removeGroup
2302 * Should be called by ~SMESH_Group_i()
2304 //=============================================================================
2306 void SMESH_Mesh_i::removeGroup( const int theId )
2308 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2309 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2310 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2311 _mapGroups.erase( theId );
2312 removeGeomGroupData( group );
2313 if (! _impl->RemoveGroup( theId ))
2315 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2316 RemoveGroup( group );
2321 //=============================================================================
2325 //=============================================================================
2327 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2328 throw(SALOME::SALOME_Exception)
2331 _preMeshInfo->FullLoadFromFile();
2333 SMESH::log_array_var aLog;
2335 list < SMESHDS_Command * >logDS = _impl->GetLog();
2336 aLog = new SMESH::log_array;
2338 int lg = logDS.size();
2341 list < SMESHDS_Command * >::iterator its = logDS.begin();
2342 while(its != logDS.end()){
2343 SMESHDS_Command *com = *its;
2344 int comType = com->GetType();
2346 int lgcom = com->GetNumber();
2348 const list < int >&intList = com->GetIndexes();
2349 int inum = intList.size();
2351 list < int >::const_iterator ii = intList.begin();
2352 const list < double >&coordList = com->GetCoords();
2353 int rnum = coordList.size();
2355 list < double >::const_iterator ir = coordList.begin();
2356 aLog[indexLog].commandType = comType;
2357 aLog[indexLog].number = lgcom;
2358 aLog[indexLog].coords.length(rnum);
2359 aLog[indexLog].indexes.length(inum);
2360 for(int i = 0; i < rnum; i++){
2361 aLog[indexLog].coords[i] = *ir;
2362 //MESSAGE(" "<<i<<" "<<ir.Value());
2365 for(int i = 0; i < inum; i++){
2366 aLog[indexLog].indexes[i] = *ii;
2367 //MESSAGE(" "<<i<<" "<<ii.Value());
2376 catch(SALOME_Exception & S_ex){
2377 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2379 return aLog._retn();
2383 //=============================================================================
2387 //=============================================================================
2389 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2391 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2395 //=============================================================================
2399 //=============================================================================
2401 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2403 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2407 //=============================================================================
2411 //=============================================================================
2413 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2418 //=============================================================================
2421 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2422 // issue 0020918: groups removal is caused by hyp modification
2423 // issue 0021208: to forget not loaded mesh data at hyp modification
2424 struct TCallUp_i : public SMESH_Mesh::TCallUp
2426 SMESH_Mesh_i* _mesh;
2427 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2428 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2429 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2430 virtual void Load () { _mesh->Load(); }
2434 //================================================================================
2436 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2438 //================================================================================
2440 void SMESH_Mesh_i::onHypothesisModified()
2443 _preMeshInfo->ForgetOrLoad();
2446 //=============================================================================
2450 //=============================================================================
2452 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2454 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2457 _impl->SetCallUp( new TCallUp_i(this));
2460 //=============================================================================
2464 //=============================================================================
2466 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2468 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2472 //=============================================================================
2474 * Return mesh editor
2476 //=============================================================================
2478 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2481 _preMeshInfo->FullLoadFromFile();
2483 // Create MeshEditor
2484 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2485 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2487 // Update Python script
2488 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2490 return aMesh._retn();
2493 //=============================================================================
2495 * Return mesh edition previewer
2497 //=============================================================================
2499 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2502 _preMeshInfo->FullLoadFromFile();
2504 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2505 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2506 return aMesh._retn();
2509 //================================================================================
2511 * \brief Return true if the mesh has been edited since a last total re-compute
2512 * and those modifications may prevent successful partial re-compute
2514 //================================================================================
2516 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2518 Unexpect aCatch(SALOME_SalomeException);
2519 return _impl->HasModificationsToDiscard();
2522 //================================================================================
2524 * \brief Returns a random unique color
2526 //================================================================================
2528 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2530 const int MAX_ATTEMPTS = 100;
2532 double tolerance = 0.5;
2533 SALOMEDS::Color col;
2537 // generate random color
2538 double red = (double)rand() / RAND_MAX;
2539 double green = (double)rand() / RAND_MAX;
2540 double blue = (double)rand() / RAND_MAX;
2541 // check existence in the list of the existing colors
2542 bool matched = false;
2543 std::list<SALOMEDS::Color>::const_iterator it;
2544 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2545 SALOMEDS::Color color = *it;
2546 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2547 matched = tol < tolerance;
2549 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2550 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2558 //=============================================================================
2560 * Sets auto-color mode. If it is on, groups get unique random colors
2562 //=============================================================================
2564 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2566 Unexpect aCatch(SALOME_SalomeException);
2567 _impl->SetAutoColor(theAutoColor);
2569 TPythonDump pyDump; // not to dump group->SetColor() from below code
2570 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2572 std::list<SALOMEDS::Color> aReservedColors;
2573 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2574 for ( ; it != _mapGroups.end(); it++ ) {
2575 if ( CORBA::is_nil( it->second )) continue;
2576 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2577 it->second->SetColor( aColor );
2578 aReservedColors.push_back( aColor );
2582 //=============================================================================
2584 * Returns true if auto-color mode is on
2586 //=============================================================================
2588 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2590 Unexpect aCatch(SALOME_SalomeException);
2591 return _impl->GetAutoColor();
2594 //=============================================================================
2596 * Checks if there are groups with equal names
2598 //=============================================================================
2600 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2602 return _impl->HasDuplicatedGroupNamesMED();
2605 //================================================================================
2607 * \brief Care of a file before exporting mesh into it
2609 //================================================================================
2611 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2613 TCollection_AsciiString aFullName ((char*)file);
2614 OSD_Path aPath (aFullName);
2615 OSD_File aFile (aPath);
2616 if (aFile.Exists()) {
2617 // existing filesystem node
2618 if (aFile.KindOfFile() == OSD_FILE) {
2619 if (aFile.IsWriteable()) {
2624 if (aFile.Failed()) {
2625 TCollection_AsciiString msg ("File ");
2626 msg += aFullName + " cannot be replaced.";
2627 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2630 TCollection_AsciiString msg ("File ");
2631 msg += aFullName + " cannot be overwritten.";
2632 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2635 TCollection_AsciiString msg ("Location ");
2636 msg += aFullName + " is not a file.";
2637 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2640 // nonexisting file; check if it can be created
2642 aFile.Build(OSD_WriteOnly, OSD_Protection());
2643 if (aFile.Failed()) {
2644 TCollection_AsciiString msg ("You cannot create the file ");
2645 msg += aFullName + ". Check the directory existance and access rights.";
2646 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2654 //================================================================================
2656 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2657 * \param file - file name
2658 * \param overwrite - to erase the file or not
2659 * \retval string - mesh name
2661 //================================================================================
2663 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2664 CORBA::Boolean overwrite)
2667 PrepareForWriting(file, overwrite);
2668 string aMeshName = "Mesh";
2669 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2670 if ( !aStudy->_is_nil() ) {
2671 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2672 if ( !aMeshSO->_is_nil() ) {
2673 CORBA::String_var name = aMeshSO->GetName();
2675 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2676 if ( !aStudy->GetProperties()->IsLocked() )
2678 SALOMEDS::GenericAttribute_var anAttr;
2679 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2680 SALOMEDS::AttributeExternalFileDef_var aFileName;
2681 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2682 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2683 ASSERT(!aFileName->_is_nil());
2684 aFileName->SetValue(file);
2685 SALOMEDS::AttributeFileType_var aFileType;
2686 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2687 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2688 ASSERT(!aFileType->_is_nil());
2689 aFileType->SetValue("FICHIERMED");
2693 // Update Python script
2694 // set name of mesh before export
2695 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2697 // check names of groups
2703 //================================================================================
2705 * \brief Export to med file
2707 //================================================================================
2709 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2710 CORBA::Boolean auto_groups,
2711 SMESH::MED_VERSION theVersion,
2712 CORBA::Boolean overwrite)
2713 throw(SALOME::SALOME_Exception)
2715 Unexpect aCatch(SALOME_SalomeException);
2717 _preMeshInfo->FullLoadFromFile();
2719 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2720 TPythonDump() << _this() << ".ExportToMEDX( r'"
2721 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2723 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2726 //================================================================================
2728 * \brief Export a mesh to a med file
2730 //================================================================================
2732 void SMESH_Mesh_i::ExportToMED (const char* file,
2733 CORBA::Boolean auto_groups,
2734 SMESH::MED_VERSION theVersion)
2735 throw(SALOME::SALOME_Exception)
2737 ExportToMEDX(file,auto_groups,theVersion,true);
2740 //================================================================================
2742 * \brief Export a mesh to a med file
2744 //================================================================================
2746 void SMESH_Mesh_i::ExportMED (const char* file,
2747 CORBA::Boolean auto_groups)
2748 throw(SALOME::SALOME_Exception)
2750 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2753 //================================================================================
2755 * \brief Export a mesh to a SAUV file
2757 //================================================================================
2759 void SMESH_Mesh_i::ExportSAUV (const char* file,
2760 CORBA::Boolean auto_groups)
2761 throw(SALOME::SALOME_Exception)
2763 Unexpect aCatch(SALOME_SalomeException);
2765 _preMeshInfo->FullLoadFromFile();
2767 string aMeshName = prepareMeshNameAndGroups(file, true);
2768 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2769 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2773 //================================================================================
2775 * \brief Export a mesh to a DAT file
2777 //================================================================================
2779 void SMESH_Mesh_i::ExportDAT (const char *file)
2780 throw(SALOME::SALOME_Exception)
2782 Unexpect aCatch(SALOME_SalomeException);
2784 _preMeshInfo->FullLoadFromFile();
2786 // Update Python script
2787 // check names of groups
2789 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2792 PrepareForWriting(file);
2793 _impl->ExportDAT(file);
2796 //================================================================================
2798 * \brief Export a mesh to an UNV file
2800 //================================================================================
2802 void SMESH_Mesh_i::ExportUNV (const char *file)
2803 throw(SALOME::SALOME_Exception)
2805 Unexpect aCatch(SALOME_SalomeException);
2807 _preMeshInfo->FullLoadFromFile();
2809 // Update Python script
2810 // check names of groups
2812 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2815 PrepareForWriting(file);
2816 _impl->ExportUNV(file);
2819 //================================================================================
2821 * \brief Export a mesh to an STL file
2823 //================================================================================
2825 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2826 throw(SALOME::SALOME_Exception)
2828 Unexpect aCatch(SALOME_SalomeException);
2830 _preMeshInfo->FullLoadFromFile();
2832 // Update Python script
2833 // check names of groups
2835 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2838 PrepareForWriting(file);
2839 _impl->ExportSTL(file, isascii);
2842 //================================================================================
2844 * \brief Export a part of mesh to a med file
2846 //================================================================================
2848 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2850 CORBA::Boolean auto_groups,
2851 ::SMESH::MED_VERSION version,
2852 ::CORBA::Boolean overwrite)
2853 throw (SALOME::SALOME_Exception)
2855 Unexpect aCatch(SALOME_SalomeException);
2857 _preMeshInfo->FullLoadFromFile();
2859 PrepareForWriting(file, overwrite);
2861 string aMeshName = "Mesh";
2862 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2863 if ( !aStudy->_is_nil() ) {
2864 SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2865 if ( !SO->_is_nil() ) {
2866 CORBA::String_var name = SO->GetName();
2870 SMESH_MeshPartDS partDS( meshPart );
2871 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2873 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2874 << auto_groups << ", " << version << ", " << overwrite << " )";
2877 //================================================================================
2879 * \brief Export a part of mesh to a DAT file
2881 //================================================================================
2883 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2885 throw (SALOME::SALOME_Exception)
2887 Unexpect aCatch(SALOME_SalomeException);
2889 _preMeshInfo->FullLoadFromFile();
2891 PrepareForWriting(file);
2893 SMESH_MeshPartDS partDS( meshPart );
2894 _impl->ExportDAT(file,&partDS);
2896 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2898 //================================================================================
2900 * \brief Export a part of mesh to an UNV file
2902 //================================================================================
2904 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2906 throw (SALOME::SALOME_Exception)
2908 Unexpect aCatch(SALOME_SalomeException);
2910 _preMeshInfo->FullLoadFromFile();
2912 PrepareForWriting(file);
2914 SMESH_MeshPartDS partDS( meshPart );
2915 _impl->ExportUNV(file, &partDS);
2917 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2919 //================================================================================
2921 * \brief Export a part of mesh to an STL file
2923 //================================================================================
2925 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2927 ::CORBA::Boolean isascii)
2928 throw (SALOME::SALOME_Exception)
2930 Unexpect aCatch(SALOME_SalomeException);
2932 _preMeshInfo->FullLoadFromFile();
2934 PrepareForWriting(file);
2936 SMESH_MeshPartDS partDS( meshPart );
2937 _impl->ExportSTL(file, isascii, &partDS);
2939 TPythonDump() << _this() << ".ExportPartToSTL( "
2940 << meshPart<< ", r'" << file << "', " << isascii << ")";
2943 //================================================================================
2945 * \brief Export a part of mesh to an STL file
2947 //================================================================================
2949 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2951 CORBA::Boolean overwrite)
2952 throw (SALOME::SALOME_Exception)
2955 Unexpect aCatch(SALOME_SalomeException);
2957 _preMeshInfo->FullLoadFromFile();
2959 PrepareForWriting(file,overwrite);
2961 SMESH_MeshPartDS partDS( meshPart );
2962 _impl->ExportCGNS(file, &partDS);
2964 TPythonDump() << _this() << ".ExportCGNS( "
2965 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2967 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2971 //=============================================================================
2973 * Return implementation of SALOME_MED::MESH interfaces
2975 //=============================================================================
2977 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2979 Unexpect aCatch(SALOME_SalomeException);
2981 _preMeshInfo->FullLoadFromFile();
2983 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2984 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2985 return aMesh._retn();
2988 //=============================================================================
2990 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2992 Unexpect aCatch(SALOME_SalomeException);
2994 return _preMeshInfo->NbNodes();
2996 return _impl->NbNodes();
2999 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3001 Unexpect aCatch(SALOME_SalomeException);
3003 return _preMeshInfo->NbElements();
3005 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3008 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3010 Unexpect aCatch(SALOME_SalomeException);
3012 return _preMeshInfo->Nb0DElements();
3014 return _impl->Nb0DElements();
3017 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3019 Unexpect aCatch(SALOME_SalomeException);
3021 return _preMeshInfo->NbBalls();
3023 return _impl->NbBalls();
3026 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3028 Unexpect aCatch(SALOME_SalomeException);
3030 return _preMeshInfo->NbEdges();
3032 return _impl->NbEdges();
3035 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3036 throw(SALOME::SALOME_Exception)
3038 Unexpect aCatch(SALOME_SalomeException);
3040 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3042 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3045 //=============================================================================
3047 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3049 Unexpect aCatch(SALOME_SalomeException);
3051 return _preMeshInfo->NbFaces();
3053 return _impl->NbFaces();
3056 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3058 Unexpect aCatch(SALOME_SalomeException);
3060 return _preMeshInfo->NbTriangles();
3062 return _impl->NbTriangles();
3065 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3067 Unexpect aCatch(SALOME_SalomeException);
3069 return _preMeshInfo->NbQuadrangles();
3071 return _impl->NbQuadrangles();
3074 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3076 Unexpect aCatch(SALOME_SalomeException);
3078 return _preMeshInfo->NbBiQuadQuadrangles();
3080 return _impl->NbBiQuadQuadrangles();
3083 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3085 Unexpect aCatch(SALOME_SalomeException);
3087 return _preMeshInfo->NbPolygons();
3089 return _impl->NbPolygons();
3092 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3093 throw(SALOME::SALOME_Exception)
3095 Unexpect aCatch(SALOME_SalomeException);
3097 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3099 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3102 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3103 throw(SALOME::SALOME_Exception)
3105 Unexpect aCatch(SALOME_SalomeException);
3107 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3109 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3112 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3113 throw(SALOME::SALOME_Exception)
3115 Unexpect aCatch(SALOME_SalomeException);
3117 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3119 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3122 //=============================================================================
3124 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3126 Unexpect aCatch(SALOME_SalomeException);
3128 return _preMeshInfo->NbVolumes();
3130 return _impl->NbVolumes();
3133 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3135 Unexpect aCatch(SALOME_SalomeException);
3137 return _preMeshInfo->NbTetras();
3139 return _impl->NbTetras();
3142 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3144 Unexpect aCatch(SALOME_SalomeException);
3146 return _preMeshInfo->NbHexas();
3148 return _impl->NbHexas();
3151 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3153 Unexpect aCatch(SALOME_SalomeException);
3155 return _preMeshInfo->NbTriQuadHexas();
3157 return _impl->NbTriQuadraticHexas();
3160 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3162 Unexpect aCatch(SALOME_SalomeException);
3164 return _preMeshInfo->NbPyramids();
3166 return _impl->NbPyramids();
3169 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3171 Unexpect aCatch(SALOME_SalomeException);
3173 return _preMeshInfo->NbPrisms();
3175 return _impl->NbPrisms();
3178 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3180 Unexpect aCatch(SALOME_SalomeException);
3182 return _preMeshInfo->NbHexPrisms();
3184 return _impl->NbHexagonalPrisms();
3187 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3189 Unexpect aCatch(SALOME_SalomeException);
3191 return _preMeshInfo->NbPolyhedrons();
3193 return _impl->NbPolyhedrons();
3196 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3197 throw(SALOME::SALOME_Exception)
3199 Unexpect aCatch(SALOME_SalomeException);
3201 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3203 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3206 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3207 throw(SALOME::SALOME_Exception)
3209 Unexpect aCatch(SALOME_SalomeException);
3211 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3213 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3216 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3217 throw(SALOME::SALOME_Exception)
3219 Unexpect aCatch(SALOME_SalomeException);
3221 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3223 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3226 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3227 throw(SALOME::SALOME_Exception)
3229 Unexpect aCatch(SALOME_SalomeException);
3231 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3233 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3236 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3237 throw(SALOME::SALOME_Exception)
3239 Unexpect aCatch(SALOME_SalomeException);
3241 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3243 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3246 //=============================================================================
3248 * Returns nb of published sub-meshes
3250 //=============================================================================
3252 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3254 Unexpect aCatch(SALOME_SalomeException);
3255 return _mapSubMesh_i.size();
3258 //=============================================================================
3260 * Dumps mesh into a string
3262 //=============================================================================
3264 char* SMESH_Mesh_i::Dump()
3268 return CORBA::string_dup( os.str().c_str() );
3271 //=============================================================================
3273 * Method of SMESH_IDSource interface
3275 //=============================================================================
3277 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3279 return GetElementsId();
3282 //=============================================================================
3284 * Returns ids of all elements
3286 //=============================================================================
3288 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3289 throw (SALOME::SALOME_Exception)
3291 Unexpect aCatch(SALOME_SalomeException);
3293 _preMeshInfo->FullLoadFromFile();
3295 SMESH::long_array_var aResult = new SMESH::long_array();
3296 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3298 if ( aSMESHDS_Mesh == NULL )
3299 return aResult._retn();
3301 long nbElements = NbElements();
3302 aResult->length( nbElements );
3303 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3304 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3305 aResult[i] = anIt->next()->GetID();
3307 return aResult._retn();
3311 //=============================================================================
3313 * Returns ids of all elements of given type
3315 //=============================================================================
3317 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3318 throw (SALOME::SALOME_Exception)
3320 Unexpect aCatch(SALOME_SalomeException);
3322 _preMeshInfo->FullLoadFromFile();
3324 SMESH::long_array_var aResult = new SMESH::long_array();
3325 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3327 if ( aSMESHDS_Mesh == NULL )
3328 return aResult._retn();
3330 long nbElements = NbElements();
3332 // No sense in returning ids of elements along with ids of nodes:
3333 // when theElemType == SMESH::ALL, return node ids only if
3334 // there are no elements
3335 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3336 return GetNodesId();
3338 aResult->length( nbElements );
3342 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3343 while ( i < nbElements && anIt->more() ) {
3344 const SMDS_MeshElement* anElem = anIt->next();
3345 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3346 aResult[i++] = anElem->GetID();
3349 aResult->length( i );
3351 return aResult._retn();
3354 //=============================================================================
3356 * Returns ids of all nodes
3358 //=============================================================================
3360 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3361 throw (SALOME::SALOME_Exception)
3363 Unexpect aCatch(SALOME_SalomeException);
3365 _preMeshInfo->FullLoadFromFile();
3367 SMESH::long_array_var aResult = new SMESH::long_array();
3368 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3370 if ( aSMESHDS_Mesh == NULL )
3371 return aResult._retn();
3373 long nbNodes = NbNodes();
3374 aResult->length( nbNodes );
3375 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3376 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3377 aResult[i] = anIt->next()->GetID();
3379 return aResult._retn();
3382 //=============================================================================
3386 //=============================================================================
3388 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3389 throw (SALOME::SALOME_Exception)
3392 _preMeshInfo->FullLoadFromFile();
3394 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3397 //=============================================================================
3401 //=============================================================================
3403 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3404 throw (SALOME::SALOME_Exception)
3407 _preMeshInfo->FullLoadFromFile();
3409 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3411 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3413 return ( SMESH::EntityType ) e->GetEntityType();
3416 //=============================================================================
3418 * Returns ID of elements for given submesh
3420 //=============================================================================
3421 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3422 throw (SALOME::SALOME_Exception)
3425 _preMeshInfo->FullLoadFromFile();
3427 SMESH::long_array_var aResult = new SMESH::long_array();
3429 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3430 if(!SM) return aResult._retn();
3432 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3433 if(!SDSM) return aResult._retn();
3435 aResult->length(SDSM->NbElements());
3437 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3439 while ( eIt->more() ) {
3440 aResult[i++] = eIt->next()->GetID();
3443 return aResult._retn();
3447 //=============================================================================
3449 * Returns ID of nodes for given submesh
3450 * If param all==true - returns all nodes, else -
3451 * returns only nodes on shapes.
3453 //=============================================================================
3454 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3456 throw (SALOME::SALOME_Exception)
3459 _preMeshInfo->FullLoadFromFile();
3461 SMESH::long_array_var aResult = new SMESH::long_array();
3463 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3464 if(!SM) return aResult._retn();
3466 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3467 if(!SDSM) return aResult._retn();
3470 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3471 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3472 while ( nIt->more() ) {
3473 const SMDS_MeshNode* elem = nIt->next();
3474 theElems.insert( elem->GetID() );
3477 else { // all nodes of submesh elements
3478 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3479 while ( eIt->more() ) {
3480 const SMDS_MeshElement* anElem = eIt->next();
3481 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3482 while ( nIt->more() ) {
3483 const SMDS_MeshElement* elem = nIt->next();
3484 theElems.insert( elem->GetID() );
3489 aResult->length(theElems.size());
3490 set<int>::iterator itElem;
3492 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3493 aResult[i++] = *itElem;
3495 return aResult._retn();
3498 //=============================================================================
3500 * Returns type of elements for given submesh
3502 //=============================================================================
3504 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3505 throw (SALOME::SALOME_Exception)
3508 _preMeshInfo->FullLoadFromFile();
3510 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3511 if(!SM) return SMESH::ALL;
3513 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3514 if(!SDSM) return SMESH::ALL;
3516 if(SDSM->NbElements()==0)
3517 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3519 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3520 const SMDS_MeshElement* anElem = eIt->next();
3521 return ( SMESH::ElementType ) anElem->GetType();
3525 //=============================================================================
3527 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3529 //=============================================================================
3531 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3534 _preMeshInfo->FullLoadFromFile();
3536 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3538 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3543 //=============================================================================
3545 * Get XYZ coordinates of node as list of double
3546 * If there is not node for given ID - returns empty list
3548 //=============================================================================
3550 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3553 _preMeshInfo->FullLoadFromFile();
3555 SMESH::double_array_var aResult = new SMESH::double_array();
3556 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3557 if ( aSMESHDS_Mesh == NULL )
3558 return aResult._retn();
3561 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3563 return aResult._retn();
3567 aResult[0] = aNode->X();
3568 aResult[1] = aNode->Y();
3569 aResult[2] = aNode->Z();
3570 return aResult._retn();
3574 //=============================================================================
3576 * For given node returns list of IDs of inverse elements
3577 * If there is not node for given ID - returns empty list
3579 //=============================================================================
3581 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3584 _preMeshInfo->FullLoadFromFile();
3586 SMESH::long_array_var aResult = new SMESH::long_array();
3587 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3588 if ( aSMESHDS_Mesh == NULL )
3589 return aResult._retn();
3592 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3594 return aResult._retn();
3596 // find inverse elements
3597 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3598 TColStd_SequenceOfInteger IDs;
3599 while(eIt->more()) {
3600 const SMDS_MeshElement* elem = eIt->next();
3601 IDs.Append(elem->GetID());
3603 if(IDs.Length()>0) {
3604 aResult->length(IDs.Length());
3606 for(; i<=IDs.Length(); i++) {
3607 aResult[i-1] = IDs.Value(i);
3610 return aResult._retn();
3613 //=============================================================================
3615 * \brief Return position of a node on shape
3617 //=============================================================================
3619 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3622 _preMeshInfo->FullLoadFromFile();
3624 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3625 aNodePosition->shapeID = 0;
3626 aNodePosition->shapeType = GEOM::SHAPE;
3628 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3629 if ( !mesh ) return aNodePosition;
3631 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3633 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3635 aNodePosition->shapeID = aNode->getshapeId();
3636 switch ( pos->GetTypeOfPosition() ) {
3638 aNodePosition->shapeType = GEOM::EDGE;
3639 aNodePosition->params.length(1);
3640 aNodePosition->params[0] =
3641 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3644 aNodePosition->shapeType = GEOM::FACE;
3645 aNodePosition->params.length(2);
3646 aNodePosition->params[0] =
3647 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3648 aNodePosition->params[1] =
3649 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3651 case SMDS_TOP_VERTEX:
3652 aNodePosition->shapeType = GEOM::VERTEX;
3654 case SMDS_TOP_3DSPACE:
3655 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3656 aNodePosition->shapeType = GEOM::SOLID;
3657 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3658 aNodePosition->shapeType = GEOM::SHELL;
3664 return aNodePosition;
3667 //=============================================================================
3669 * If given element is node returns IDs of shape from position
3670 * If there is not node for given ID - returns -1
3672 //=============================================================================
3674 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3677 _preMeshInfo->FullLoadFromFile();
3679 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3680 if ( aSMESHDS_Mesh == NULL )
3684 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3686 return aNode->getshapeId();
3693 //=============================================================================
3695 * For given element returns ID of result shape after
3696 * ::FindShape() from SMESH_MeshEditor
3697 * If there is not element for given ID - returns -1
3699 //=============================================================================
3701 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3704 _preMeshInfo->FullLoadFromFile();
3706 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3707 if ( aSMESHDS_Mesh == NULL )
3710 // try to find element
3711 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3715 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3716 ::SMESH_MeshEditor aMeshEditor(_impl);
3717 int index = aMeshEditor.FindShape( elem );
3725 //=============================================================================
3727 * Returns number of nodes for given element
3728 * If there is not element for given ID - returns -1
3730 //=============================================================================
3732 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3735 _preMeshInfo->FullLoadFromFile();
3737 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3738 if ( aSMESHDS_Mesh == NULL ) return -1;
3739 // try to find element
3740 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3741 if(!elem) return -1;
3742 return elem->NbNodes();
3746 //=============================================================================
3748 * Returns ID of node by given index for given element
3749 * If there is not element for given ID - returns -1
3750 * If there is not node for given index - returns -2
3752 //=============================================================================
3754 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3757 _preMeshInfo->FullLoadFromFile();
3759 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3760 if ( aSMESHDS_Mesh == NULL ) return -1;
3761 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3762 if(!elem) return -1;
3763 if( index>=elem->NbNodes() || index<0 ) return -1;
3764 return elem->GetNode(index)->GetID();
3767 //=============================================================================
3769 * Returns IDs of nodes of given element
3771 //=============================================================================
3773 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3776 _preMeshInfo->FullLoadFromFile();
3778 SMESH::long_array_var aResult = new SMESH::long_array();
3779 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3781 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3783 aResult->length( elem->NbNodes() );
3784 for ( int i = 0; i < elem->NbNodes(); ++i )
3785 aResult[ i ] = elem->GetNode( i )->GetID();
3788 return aResult._retn();
3791 //=============================================================================
3793 * Returns true if given node is medium node
3794 * in given quadratic element
3796 //=============================================================================
3798 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3801 _preMeshInfo->FullLoadFromFile();
3803 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3804 if ( aSMESHDS_Mesh == NULL ) return false;
3806 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3807 if(!aNode) return false;
3808 // try to find element
3809 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3810 if(!elem) return false;
3812 return elem->IsMediumNode(aNode);
3816 //=============================================================================
3818 * Returns true if given node is medium node
3819 * in one of quadratic elements
3821 //=============================================================================
3823 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3824 SMESH::ElementType theElemType)
3827 _preMeshInfo->FullLoadFromFile();
3829 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3830 if ( aSMESHDS_Mesh == NULL ) return false;
3833 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3834 if(!aNode) return false;
3836 SMESH_MesherHelper aHelper( *(_impl) );
3838 SMDSAbs_ElementType aType;
3839 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3840 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3841 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3842 else aType = SMDSAbs_All;
3844 return aHelper.IsMedium(aNode,aType);
3848 //=============================================================================
3850 * Returns number of edges for given element
3852 //=============================================================================
3854 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3857 _preMeshInfo->FullLoadFromFile();
3859 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3860 if ( aSMESHDS_Mesh == NULL ) return -1;
3861 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3862 if(!elem) return -1;
3863 return elem->NbEdges();
3867 //=============================================================================
3869 * Returns number of faces for given element
3871 //=============================================================================
3873 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3876 _preMeshInfo->FullLoadFromFile();
3878 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3879 if ( aSMESHDS_Mesh == NULL ) return -1;
3880 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3881 if(!elem) return -1;
3882 return elem->NbFaces();
3885 //=======================================================================
3886 //function : GetElemFaceNodes
3887 //purpose : Returns nodes of given face (counted from zero) for given element.
3888 //=======================================================================
3890 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3891 CORBA::Short faceIndex)
3894 _preMeshInfo->FullLoadFromFile();
3896 SMESH::long_array_var aResult = new SMESH::long_array();
3897 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3899 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3901 SMDS_VolumeTool vtool( elem );
3902 if ( faceIndex < vtool.NbFaces() )
3904 aResult->length( vtool.NbFaceNodes( faceIndex ));
3905 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3906 for ( int i = 0; i < aResult->length(); ++i )
3907 aResult[ i ] = nn[ i ]->GetID();
3911 return aResult._retn();
3914 //=======================================================================
3915 //function : FindElementByNodes
3916 //purpose : Returns an element based on all given nodes.
3917 //=======================================================================
3919 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3922 _preMeshInfo->FullLoadFromFile();
3924 CORBA::Long elemID(0);
3925 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3927 vector< const SMDS_MeshNode * > nn( nodes.length() );
3928 for ( int i = 0; i < nodes.length(); ++i )
3929 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3932 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3933 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
3934 _impl->NbFaces ( ORDER_QUADRATIC ) ||
3935 _impl->NbVolumes( ORDER_QUADRATIC )))
3936 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3938 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3943 //=============================================================================
3945 * Returns true if given element is polygon
3947 //=============================================================================
3949 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3952 _preMeshInfo->FullLoadFromFile();
3954 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3955 if ( aSMESHDS_Mesh == NULL ) return false;
3956 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3957 if(!elem) return false;
3958 return elem->IsPoly();
3962 //=============================================================================
3964 * Returns true if given element is quadratic
3966 //=============================================================================
3968 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3971 _preMeshInfo->FullLoadFromFile();
3973 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3974 if ( aSMESHDS_Mesh == NULL ) return false;
3975 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3976 if(!elem) return false;
3977 return elem->IsQuadratic();
3980 //=============================================================================
3982 * Returns diameter of ball discrete element or zero in case of an invalid \a id
3984 //=============================================================================
3986 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
3989 _preMeshInfo->FullLoadFromFile();
3991 if ( const SMDS_BallElement* ball =
3992 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
3993 return ball->GetDiameter();
3998 //=============================================================================
4000 * Returns bary center for given element
4002 //=============================================================================
4004 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4007 _preMeshInfo->FullLoadFromFile();
4009 SMESH::double_array_var aResult = new SMESH::double_array();
4010 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4011 if ( aSMESHDS_Mesh == NULL )
4012 return aResult._retn();
4014 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4016 return aResult._retn();
4018 if(elem->GetType()==SMDSAbs_Volume) {
4019 SMDS_VolumeTool aTool;
4020 if(aTool.Set(elem)) {
4022 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4027 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4029 double x=0., y=0., z=0.;
4030 for(; anIt->more(); ) {
4032 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4046 return aResult._retn();
4050 //=============================================================================
4052 * Create and publish group servants if any groups were imported or created anyhow
4054 //=============================================================================
4056 void SMESH_Mesh_i::CreateGroupServants()
4058 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
4061 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4062 while ( groupIt->more() )
4064 ::SMESH_Group* group = groupIt->next();
4065 int anId = group->GetGroupDS()->GetID();
4067 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4068 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4070 addedIDs.insert( anId );
4072 SMESH_GroupBase_i* aGroupImpl;
4074 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4075 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4077 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4078 shape = groupOnGeom->GetShape();
4081 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4084 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
4085 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
4086 aGroupImpl->Register();
4088 SMESH::SMESH_GroupBase_var groupVar =
4089 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4090 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4092 // register CORBA object for persistence
4093 int nextId = _gen_i->RegisterObject( groupVar );
4094 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
4096 // publishing the groups in the study
4097 if ( !aStudy->_is_nil() ) {
4098 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4099 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4102 if ( !addedIDs.empty() )
4105 set<int>::iterator id = addedIDs.begin();
4106 for ( ; id != addedIDs.end(); ++id )
4108 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4109 int i = std::distance( _mapGroups.begin(), it );
4110 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4115 //=============================================================================
4117 * \brief Return groups cantained in _mapGroups by their IDs
4119 //=============================================================================
4121 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4123 int nbGroups = groupIDs.size();
4124 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4125 aList->length( nbGroups );
4127 list<int>::const_iterator ids = groupIDs.begin();
4128 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4130 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4131 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4132 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4134 aList->length( nbGroups );
4135 return aList._retn();
4138 //=============================================================================
4140 * \brief Return information about imported file
4142 //=============================================================================
4144 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4146 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4147 if ( !res.operator->() ) {
4148 res = new SALOME_MED::MedFileInfo;
4150 res->fileSize = res->major = res->minor = res->release = -1;
4155 //=============================================================================
4157 * \brief Pass names of mesh groups from study to mesh DS
4159 //=============================================================================
4161 void SMESH_Mesh_i::checkGroupNames()
4163 int nbGrp = NbGroups();
4167 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
4168 if ( aStudy->_is_nil() )
4169 return; // nothing to do
4171 SMESH::ListOfGroups* grpList = 0;
4172 // avoid dump of "GetGroups"
4174 // store python dump into a local variable inside local scope
4175 SMESH::TPythonDump pDump; // do not delete this line of code
4176 grpList = GetGroups();
4179 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4180 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4183 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4184 if ( aGrpSO->_is_nil() )
4186 // correct name of the mesh group if necessary
4187 const char* guiName = aGrpSO->GetName();
4188 if ( strcmp(guiName, aGrp->GetName()) )
4189 aGrp->SetName( guiName );
4193 //=============================================================================
4195 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4197 //=============================================================================
4198 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4200 // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
4201 // CORBA::string_dup(theParameters));
4202 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters);
4205 //=============================================================================
4207 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4209 //=============================================================================
4210 char* SMESH_Mesh_i::GetParameters()
4212 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4213 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4216 //=============================================================================
4218 * \brief Returns list of notebook variables used for last Mesh operation
4220 //=============================================================================
4221 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4223 SMESH::string_array_var aResult = new SMESH::string_array();
4224 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4226 char *aParameters = GetParameters();
4227 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
4228 if(!aStudy->_is_nil()) {
4229 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4230 if(aSections->length() > 0) {
4231 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4232 aResult->length(aVars.length());
4233 for(int i = 0;i < aVars.length();i++)
4234 aResult[i] = CORBA::string_dup( aVars[i]);
4238 return aResult._retn();
4241 //=======================================================================
4242 //function : GetTypes
4243 //purpose : Returns types of elements it contains
4244 //=======================================================================
4246 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4249 return _preMeshInfo->GetTypes();
4251 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4255 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4256 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4257 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4258 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4259 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4260 types->length( nbTypes );
4262 return types._retn();
4265 //=======================================================================
4266 //function : GetMesh
4267 //purpose : Returns self
4268 //=======================================================================
4270 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4272 return SMESH::SMESH_Mesh::_duplicate( _this() );
4275 //=======================================================================
4276 //function : IsMeshInfoCorrect
4277 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4278 // * happen if mesh data is not yet fully loaded from the file of study.
4279 //=======================================================================
4281 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4283 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4286 //=============================================================================
4288 * \brief Returns statistic of mesh elements
4290 //=============================================================================
4292 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4295 return _preMeshInfo->GetMeshInfo();
4297 SMESH::long_array_var aRes = new SMESH::long_array();
4298 aRes->length(SMESH::Entity_Last);
4299 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4301 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4303 return aRes._retn();
4304 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4305 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4306 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4307 return aRes._retn();
4310 //=============================================================================
4312 * \brief Collect statistic of mesh elements given by iterator
4314 //=============================================================================
4316 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4317 SMESH::long_array& theInfo)
4319 if (!theItr) return;
4320 while (theItr->more())
4321 theInfo[ theItr->next()->GetEntityType() ]++;
4324 //=============================================================================
4325 namespace // Finding concurrent hypotheses
4326 //=============================================================================
4330 * \brief mapping of mesh dimension into shape type
4332 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4334 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4336 case 0: aType = TopAbs_VERTEX; break;
4337 case 1: aType = TopAbs_EDGE; break;
4338 case 2: aType = TopAbs_FACE; break;
4340 default:aType = TopAbs_SOLID; break;
4345 //-----------------------------------------------------------------------------
4347 * \brief Internal structure used to find concurent submeshes
4349 * It represents a pair < submesh, concurent dimension >, where
4350 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4351 * with another submesh. In other words, it is dimension of a hypothesis assigned
4358 int _dim; //!< a dimension the algo can build (concurrent dimension)
4359 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4360 TopTools_MapOfShape _shapeMap;
4361 SMESH_subMesh* _subMesh;
4362 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4364 //-----------------------------------------------------------------------------
4365 // Return the algorithm
4366 const SMESH_Algo* GetAlgo() const
4367 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4369 //-----------------------------------------------------------------------------
4371 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4373 const TopoDS_Shape& theShape)
4375 _subMesh = (SMESH_subMesh*)theSubMesh;
4376 SetShape( theDim, theShape );
4379 //-----------------------------------------------------------------------------
4381 void SetShape(const int theDim,
4382 const TopoDS_Shape& theShape)
4385 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4386 if (_dim >= _ownDim)
4387 _shapeMap.Add( theShape );
4389 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4390 for( ; anExp.More(); anExp.Next() )
4391 _shapeMap.Add( anExp.Current() );
4395 //-----------------------------------------------------------------------------
4396 //! Check sharing of sub-shapes
4397 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4398 const TopTools_MapOfShape& theToFind,
4399 const TopAbs_ShapeEnum theType)
4401 bool isShared = false;
4402 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4403 for (; !isShared && anItr.More(); anItr.Next() )
4405 const TopoDS_Shape aSubSh = anItr.Key();
4406 // check for case when concurrent dimensions are same
4407 isShared = theToFind.Contains( aSubSh );
4408 // check for sub-shape with concurrent dimension
4409 TopExp_Explorer anExp( aSubSh, theType );
4410 for ( ; !isShared && anExp.More(); anExp.Next() )
4411 isShared = theToFind.Contains( anExp.Current() );
4416 //-----------------------------------------------------------------------------
4417 //! check algorithms
4418 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4419 const SMESHDS_Hypothesis* theA2)
4421 if ( !theA1 || !theA2 ||
4422 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4423 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4424 return false; // one of the hypothesis is not algorithm
4425 // check algorithm names (should be equal)
4426 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4430 //-----------------------------------------------------------------------------
4431 //! Check if sub-shape hypotheses are concurrent
4432 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4434 if ( _subMesh == theOther->_subMesh )
4435 return false; // same sub-shape - should not be
4437 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4438 // any of the two submeshes is not on COMPOUND shape )
4439 // -> no concurrency
4440 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4441 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4442 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4443 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4444 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4447 // bool checkSubShape = ( _dim >= theOther->_dim )
4448 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4449 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4450 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4451 if ( !checkSubShape )
4454 // check algorithms to be same
4455 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4456 return true; // different algorithms -> concurrency !
4458 // check hypothesises for concurrence (skip first as algorithm)
4460 // pointers should be same, because it is referened from mesh hypothesis partition
4461 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4462 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4463 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4464 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4466 // the submeshes are concurrent if their algorithms has different parameters
4467 return nbSame != theOther->_hypotheses.size() - 1;
4470 // Return true if algorithm of this SMESH_DimHyp is used if no
4471 // sub-mesh order is imposed by the user
4472 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4474 // NeedDiscreteBoundary() algo has a higher priority
4475 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4476 theOther->GetAlgo()->NeedDiscreteBoundary() )
4477 return !this->GetAlgo()->NeedDiscreteBoundary();
4479 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4482 }; // end of SMESH_DimHyp
4483 //-----------------------------------------------------------------------------
4485 typedef list<const SMESH_DimHyp*> TDimHypList;
4487 //-----------------------------------------------------------------------------
4489 void addDimHypInstance(const int theDim,
4490 const TopoDS_Shape& theShape,
4491 const SMESH_Algo* theAlgo,
4492 const SMESH_subMesh* theSubMesh,
4493 const list <const SMESHDS_Hypothesis*>& theHypList,
4494 TDimHypList* theDimHypListArr )
4496 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4497 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4498 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4499 dimHyp->_hypotheses.push_front(theAlgo);
4500 listOfdimHyp.push_back( dimHyp );
4503 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4504 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4505 theHypList.begin(), theHypList.end() );
4508 //-----------------------------------------------------------------------------
4509 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4510 TDimHypList& theListOfConcurr)
4512 if ( theListOfConcurr.empty() )
4514 theListOfConcurr.push_back( theDimHyp );
4518 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4519 while ( hypIt != theListOfConcurr.end() &&
4520 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4522 theListOfConcurr.insert( hypIt, theDimHyp );
4526 //-----------------------------------------------------------------------------
4527 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4528 const TDimHypList& theListOfDimHyp,
4529 TDimHypList& theListOfConcurrHyp,
4530 set<int>& theSetOfConcurrId )
4532 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4533 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4535 const SMESH_DimHyp* curDimHyp = *rIt;
4536 if ( curDimHyp == theDimHyp )
4537 break; // meet own dimHyp pointer in same dimension
4539 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4540 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4542 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4547 //-----------------------------------------------------------------------------
4548 void unionLists(TListOfInt& theListOfId,
4549 TListOfListOfInt& theListOfListOfId,
4552 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4553 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4555 continue; //skip already treated lists
4556 // check if other list has any same submesh object
4557 TListOfInt& otherListOfId = *it;
4558 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4559 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4562 // union two lists (from source into target)
4563 TListOfInt::iterator it2 = otherListOfId.begin();
4564 for ( ; it2 != otherListOfId.end(); it2++ ) {
4565 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4566 theListOfId.push_back(*it2);
4568 // clear source list
4569 otherListOfId.clear();
4572 //-----------------------------------------------------------------------------
4574 //! free memory allocated for dimension-hypothesis objects
4575 void removeDimHyps( TDimHypList* theArrOfList )
4577 for (int i = 0; i < 4; i++ ) {
4578 TDimHypList& listOfdimHyp = theArrOfList[i];
4579 TDimHypList::const_iterator it = listOfdimHyp.begin();
4580 for ( ; it != listOfdimHyp.end(); it++ )
4585 //-----------------------------------------------------------------------------
4587 * \brief find common submeshes with given submesh
4588 * \param theSubMeshList list of already collected submesh to check
4589 * \param theSubMesh given submesh to intersect with other
4590 * \param theCommonSubMeshes collected common submeshes
4592 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4593 const SMESH_subMesh* theSubMesh,
4594 set<const SMESH_subMesh*>& theCommon )
4598 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4599 for ( ; it != theSubMeshList.end(); it++ )
4600 theSubMesh->FindIntersection( *it, theCommon );
4601 theSubMeshList.push_back( theSubMesh );
4602 //theCommon.insert( theSubMesh );
4607 //=============================================================================
4609 * \brief Return submesh objects list in meshing order
4611 //=============================================================================
4613 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4615 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4617 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4619 return aResult._retn();
4621 ::SMESH_Mesh& mesh = GetImpl();
4622 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4623 if ( !anOrder.size() ) {
4625 // collect submeshes and detect concurrent algorithms and hypothesises
4626 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4628 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4629 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4630 ::SMESH_subMesh* sm = (*i_sm).second;
4632 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4634 // list of assigned hypothesises
4635 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4636 // Find out dimensions where the submesh can be concurrent.
4637 // We define the dimensions by algo of each of hypotheses in hypList
4638 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4639 for( ; hypIt != hypList.end(); hypIt++ ) {
4640 SMESH_Algo* anAlgo = 0;
4641 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4642 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4643 // hyp it-self is algo
4644 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4646 // try to find algorithm with help of sub-shapes
4647 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4648 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4649 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4652 continue; // no algorithm assigned to a current submesh
4654 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4655 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4657 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4658 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4659 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4661 } // end iterations on submesh
4663 // iterate on created dimension-hypotheses and check for concurrents
4664 for ( int i = 0; i < 4; i++ ) {
4665 const TDimHypList& listOfDimHyp = dimHypListArr[i];
4666 // check for concurrents in own and other dimensions (step-by-step)
4667 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4668 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4669 const SMESH_DimHyp* dimHyp = *dhIt;
4670 TDimHypList listOfConcurr;
4671 set<int> setOfConcurrIds;
4672 // looking for concurrents and collect into own list
4673 for ( int j = i; j < 4; j++ )
4674 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
4675 // check if any concurrents found
4676 if ( listOfConcurr.size() > 0 ) {
4677 // add own submesh to list of concurrent
4678 addInOrderOfPriority( dimHyp, listOfConcurr );
4679 list<int> listOfConcurrIds;
4680 TDimHypList::iterator hypIt = listOfConcurr.begin();
4681 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
4682 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
4683 anOrder.push_back( listOfConcurrIds );
4688 removeDimHyps(dimHypListArr);
4690 // now, minimise the number of concurrent groups
4691 // Here we assume that lists of submeshes can have same submesh
4692 // in case of multi-dimension algorithms, as result
4693 // list with common submesh has to be united into one list
4695 TListOfListOfInt::iterator listIt = anOrder.begin();
4696 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4697 unionLists( *listIt, anOrder, listIndx + 1 );
4699 // convert submesh ids into interface instances
4700 // and dump command into python
4701 convertMeshOrder( anOrder, aResult, false );
4703 return aResult._retn();
4706 //=============================================================================
4708 * \brief Set submesh object order
4709 * \param theSubMeshArray submesh array order
4711 //=============================================================================
4713 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4716 _preMeshInfo->ForgetOrLoad();
4719 ::SMESH_Mesh& mesh = GetImpl();
4721 TPythonDump aPythonDump; // prevent dump of called methods
4722 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4724 TListOfListOfInt subMeshOrder;
4725 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4727 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4728 TListOfInt subMeshIds;
4729 aPythonDump << "[ ";
4730 // Collect subMeshes which should be clear
4731 // do it list-by-list, because modification of submesh order
4732 // take effect between concurrent submeshes only
4733 set<const SMESH_subMesh*> subMeshToClear;
4734 list<const SMESH_subMesh*> subMeshList;
4735 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4737 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4739 aPythonDump << ", ";
4740 aPythonDump << subMesh;
4741 subMeshIds.push_back( subMesh->GetId() );
4742 // detect common parts of submeshes
4743 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4744 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4746 aPythonDump << " ]";
4747 subMeshOrder.push_back( subMeshIds );
4749 // clear collected submeshes
4750 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4751 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
4752 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
4753 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4755 aPythonDump << " ])";
4757 mesh.SetMeshOrder( subMeshOrder );
4763 //=============================================================================
4765 * \brief Convert submesh ids into submesh interfaces
4767 //=============================================================================
4769 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4770 SMESH::submesh_array_array& theResOrder,
4771 const bool theIsDump)
4773 int nbSet = theIdsOrder.size();
4774 TPythonDump aPythonDump; // prevent dump of called methods
4776 aPythonDump << "[ ";
4777 theResOrder.length(nbSet);
4778 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4780 for( ; it != theIdsOrder.end(); it++ ) {
4781 // translate submesh identificators into submesh objects
4782 // takeing into account real number of concurrent lists
4783 const TListOfInt& aSubOrder = (*it);
4784 if (!aSubOrder.size())
4787 aPythonDump << "[ ";
4788 // convert shape indeces into interfaces
4789 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4790 aResSubSet->length(aSubOrder.size());
4791 TListOfInt::const_iterator subIt = aSubOrder.begin();
4792 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4793 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4795 SMESH::SMESH_subMesh_var subMesh =
4796 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4799 aPythonDump << ", ";
4800 aPythonDump << subMesh;
4802 aResSubSet[ j++ ] = subMesh;
4805 aPythonDump << " ]";
4806 theResOrder[ listIndx++ ] = aResSubSet;
4808 // correct number of lists
4809 theResOrder.length( listIndx );
4812 // finilise python dump
4813 aPythonDump << " ]";
4814 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4818 //================================================================================
4820 // Implementation of SMESH_MeshPartDS
4822 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4823 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
4825 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4826 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4828 _meshDS = mesh_i->GetImpl().GetMeshDS();
4830 SetPersistentId( _meshDS->GetPersistentId() );
4832 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4834 // <meshPart> is the whole mesh
4835 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4837 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4838 myGroupSet = _meshDS->GetGroups();
4843 SMESH::long_array_var anIDs = meshPart->GetIDs();
4844 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4845 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4847 for (int i=0; i < anIDs->length(); i++)
4848 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4849 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4854 for (int i=0; i < anIDs->length(); i++)
4855 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4856 if ( _elements[ e->GetType() ].insert( e ).second )
4859 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4860 while ( nIt->more() )
4862 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4863 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4870 _meshDS = 0; // to enforce iteration on _elements and _nodes
4873 // -------------------------------------------------------------------------------------
4874 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
4875 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
4878 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
4879 for ( ; partIt != meshPart.end(); ++partIt )
4880 if ( const SMDS_MeshElement * e = *partIt )
4881 if ( _elements[ e->GetType() ].insert( e ).second )
4884 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4885 while ( nIt->more() )
4887 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4888 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4894 // -------------------------------------------------------------------------------------
4895 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
4897 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
4899 typedef SMDS_SetIterator
4900 <const SMDS_MeshElement*,
4901 TIDSortedElemSet::const_iterator,
4902 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
4903 SMDS_MeshElement::GeomFilter
4906 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
4908 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
4909 _elements[type].end(),
4910 SMDS_MeshElement::GeomFilter( geomType )));
4912 // -------------------------------------------------------------------------------------
4913 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
4915 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
4917 typedef SMDS_SetIterator
4918 <const SMDS_MeshElement*,
4919 TIDSortedElemSet::const_iterator,
4920 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
4921 SMDS_MeshElement::EntityFilter
4924 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
4926 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
4927 _elements[type].end(),
4928 SMDS_MeshElement::EntityFilter( entity )));
4930 // -------------------------------------------------------------------------------------
4931 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4933 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4934 if ( type == SMDSAbs_All && !_meshDS )
4936 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
4938 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4939 if ( !_elements[i].empty() && i != SMDSAbs_Node )
4941 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
4943 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
4944 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
4946 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4947 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4949 // -------------------------------------------------------------------------------------
4950 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4951 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4953 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4954 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4955 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4957 // -------------------------------------------------------------------------------------
4958 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4959 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4960 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4961 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4962 #undef _GET_ITER_DEFINE
4964 // END Implementation of SMESH_MeshPartDS
4966 //================================================================================