1 // Copyright (C) 2007-2011 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 "SMESH_Filter_i.hxx"
29 #include "SMESH_Gen_i.hxx"
30 #include "SMESH_Group_i.hxx"
31 #include "SMESH_MEDMesh_i.hxx"
32 #include "SMESH_MeshEditor_i.hxx"
33 #include "SMESH_PythonDump.hxx"
34 #include "SMESH_subMesh_i.hxx"
36 #include "DriverMED_R_SMESHDS_Mesh.h"
37 #include "DriverMED_W_SMESHDS_Mesh.h"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMDS_ElemIterator.hxx"
40 #include "SMESHDS_Command.hxx"
41 #include "SMESHDS_CommandType.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Group.hxx"
44 #include "SMESH_MeshEditor.hxx"
45 #include "SMESH_MesherHelper.hxx"
46 #include "SMDS_EdgePosition.hxx"
47 #include "SMDS_FacePosition.hxx"
50 #include "SALOME_NamingService.hxx"
51 #include "Utils_CorbaException.hxx"
52 #include "Utils_ExceptHandlers.hxx"
53 #include "Utils_SINGLETON.hxx"
54 #include "utilities.h"
55 #include "GEOMImpl_Types.hxx"
58 #include <BRep_Builder.hxx>
59 #include <OSD_Directory.hxx>
60 #include <OSD_File.hxx>
61 #include <OSD_Path.hxx>
62 #include <OSD_Protection.hxx>
63 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
64 #include <TColStd_MapOfInteger.hxx>
65 #include <TColStd_SequenceOfInteger.hxx>
66 #include <TCollection_AsciiString.hxx>
68 #include <TopExp_Explorer.hxx>
69 #include <TopoDS_Compound.hxx>
70 #include <TopTools_MapOfShape.hxx>
71 #include <TopTools_MapIteratorOfMapOfShape.hxx>
81 static int MYDEBUG = 0;
83 static int MYDEBUG = 0;
87 using SMESH::TPythonDump;
89 int SMESH_Mesh_i::myIdGenerator = 0;
91 //To disable automatic genericobj management, the following line should be commented.
92 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
93 #define WITHGENERICOBJ
95 //=============================================================================
99 //=============================================================================
101 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
103 CORBA::Long studyId )
104 : SALOME::GenericObj_i( thePOA )
106 MESSAGE("SMESH_Mesh_i");
109 _id = myIdGenerator++;
113 //=============================================================================
117 //=============================================================================
119 SMESH_Mesh_i::~SMESH_Mesh_i()
121 MESSAGE("~SMESH_Mesh_i");
123 #ifdef WITHGENERICOBJ
125 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
126 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
127 if ( CORBA::is_nil( itGr->second ))
129 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
131 // this method is called from destructor of group (PAL6331)
132 //_impl->RemoveGroup( aGroup->GetLocalID() );
133 aGroup->myMeshServant = 0;
134 aGroup->UnRegister();
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
142 if ( CORBA::is_nil( itSM->second ))
144 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
146 aSubMesh->UnRegister();
149 _mapSubMeshIor.clear();
151 // destroy hypotheses
152 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
153 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
154 if ( CORBA::is_nil( itH->second ))
156 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
167 //=============================================================================
171 * Associates <this> mesh with <theShape> and puts a reference
172 * to <theShape> into the current study;
173 * the previous shape is substituted by the new one.
175 //=============================================================================
177 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
178 throw (SALOME::SALOME_Exception)
180 Unexpect aCatch(SALOME_SalomeException);
182 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
184 catch(SALOME_Exception & S_ex) {
185 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
187 // to track changes of GEOM groups
188 addGeomGroupData( theShapeObject, _this() );
191 //================================================================================
193 * \brief return true if mesh has a shape to build a shape on
195 //================================================================================
197 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
198 throw (SALOME::SALOME_Exception)
200 Unexpect aCatch(SALOME_SalomeException);
203 res = _impl->HasShapeToMesh();
205 catch(SALOME_Exception & S_ex) {
206 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
211 //=======================================================================
212 //function : GetShapeToMesh
214 //=======================================================================
216 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
217 throw (SALOME::SALOME_Exception)
219 Unexpect aCatch(SALOME_SalomeException);
220 GEOM::GEOM_Object_var aShapeObj;
222 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
224 aShapeObj = _gen_i->ShapeToGeomObject( S );
226 catch(SALOME_Exception & S_ex) {
227 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
229 return aShapeObj._retn();
232 //================================================================================
234 * \brief Remove all nodes and elements
236 //================================================================================
238 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
240 Unexpect aCatch(SALOME_SalomeException);
243 CheckGeomGroupModif(); // issue 20145
245 catch(SALOME_Exception & S_ex) {
246 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
248 TPythonDump() << _this() << ".Clear()";
251 //================================================================================
253 * \brief Remove all nodes and elements for indicated shape
255 //================================================================================
257 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
258 throw (SALOME::SALOME_Exception)
260 Unexpect aCatch(SALOME_SalomeException);
262 _impl->ClearSubMesh( ShapeID );
264 catch(SALOME_Exception & S_ex) {
265 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
269 //=============================================================================
273 //=============================================================================
275 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
277 SMESH::DriverMED_ReadStatus res;
280 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
281 res = SMESH::DRS_OK; break;
282 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
283 res = SMESH::DRS_EMPTY; break;
284 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
285 res = SMESH::DRS_WARN_RENUMBER; break;
286 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
287 res = SMESH::DRS_WARN_SKIP_ELEM; break;
288 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
290 res = SMESH::DRS_FAIL; break;
295 //=============================================================================
299 * Imports mesh data from MED file
301 //=============================================================================
303 SMESH::DriverMED_ReadStatus
304 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
305 throw ( SALOME::SALOME_Exception )
307 Unexpect aCatch(SALOME_SalomeException);
310 status = _impl->MEDToMesh( theFileName, theMeshName );
312 catch( SALOME_Exception& S_ex ) {
313 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
316 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
319 CreateGroupServants();
321 int major, minor, release;
322 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
323 major = minor = release = -1;
324 myFileInfo = new SALOME_MED::MedFileInfo();
325 myFileInfo->fileName = theFileName;
326 myFileInfo->fileSize = 0;
329 if ( ::_stati64( theFileName, &d ) != -1 )
332 if ( ::stat64( theFileName, &d ) != -1 )
334 myFileInfo->fileSize = d.st_size;
335 myFileInfo->major = major;
336 myFileInfo->minor = minor;
337 myFileInfo->release = release;
339 return ConvertDriverMEDReadStatus(status);
342 //================================================================================
344 * \brief Return string representation of a MED file version comprising nbDigits
346 //================================================================================
348 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
350 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
352 return CORBA::string_dup( ver.c_str() );
355 //=============================================================================
359 * Imports mesh data from MED file
361 //=============================================================================
363 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
364 throw ( SALOME::SALOME_Exception )
366 // Read mesh with name = <theMeshName> into SMESH_Mesh
367 _impl->UNVToMesh( theFileName );
369 CreateGroupServants();
374 //=============================================================================
378 * Imports mesh data from STL file
380 //=============================================================================
381 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
382 throw ( SALOME::SALOME_Exception )
384 // Read mesh with name = <theMeshName> into SMESH_Mesh
385 _impl->STLToMesh( theFileName );
390 //=============================================================================
394 * Imports mesh data from MED file
396 //=============================================================================
398 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
400 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
401 // int status = _impl->MEDToMesh( theFileName, theMeshName );
402 // CreateGroupServants();
407 //=============================================================================
411 //=============================================================================
413 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
415 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
416 (SMESH_Hypothesis::Hypothesis_Status theStatus)
419 RETURNCASE( HYP_OK );
420 RETURNCASE( HYP_MISSING );
421 RETURNCASE( HYP_CONCURENT );
422 RETURNCASE( HYP_BAD_PARAMETER );
423 RETURNCASE( HYP_HIDDEN_ALGO );
424 RETURNCASE( HYP_HIDING_ALGO );
425 RETURNCASE( HYP_UNKNOWN_FATAL );
426 RETURNCASE( HYP_INCOMPATIBLE );
427 RETURNCASE( HYP_NOTCONFORM );
428 RETURNCASE( HYP_ALREADY_EXIST );
429 RETURNCASE( HYP_BAD_DIM );
430 RETURNCASE( HYP_BAD_SUBSHAPE );
431 RETURNCASE( HYP_BAD_GEOMETRY );
432 RETURNCASE( HYP_NEED_SHAPE );
435 return SMESH::HYP_UNKNOWN_FATAL;
438 //=============================================================================
442 * calls internal addHypothesis() and then adds a reference to <anHyp> under
443 * the SObject actually having a reference to <aSubShape>.
444 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
446 //=============================================================================
448 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
449 SMESH::SMESH_Hypothesis_ptr anHyp)
450 throw(SALOME::SALOME_Exception)
452 Unexpect aCatch(SALOME_SalomeException);
453 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
455 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
456 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
457 aSubShapeObject, anHyp );
459 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
461 // Update Python script
462 if(_impl->HasShapeToMesh()) {
463 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
464 << aSubShapeObject << ", " << anHyp << " )";
467 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
470 return ConvertHypothesisStatus(status);
473 //=============================================================================
477 //=============================================================================
479 SMESH_Hypothesis::Hypothesis_Status
480 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
481 SMESH::SMESH_Hypothesis_ptr anHyp)
483 if(MYDEBUG) MESSAGE("addHypothesis");
485 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
486 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
489 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
490 if (CORBA::is_nil(myHyp))
491 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
494 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
497 TopoDS_Shape myLocSubShape;
498 //use PseudoShape in case if mesh has no shape
500 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
502 myLocSubShape = _impl->GetShapeToMesh();
504 int hypId = myHyp->GetId();
505 status = _impl->AddHypothesis(myLocSubShape, hypId);
506 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
507 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
508 #ifdef WITHGENERICOBJ
509 _mapHypo[hypId]->Register();
511 // assure there is a corresponding submesh
512 if ( !_impl->IsMainShape( myLocSubShape )) {
513 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
514 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
515 createSubMesh( aSubShapeObject );
519 catch(SALOME_Exception & S_ex)
521 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
526 //=============================================================================
530 //=============================================================================
532 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
533 SMESH::SMESH_Hypothesis_ptr anHyp)
534 throw(SALOME::SALOME_Exception)
536 Unexpect aCatch(SALOME_SalomeException);
537 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
539 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
540 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
541 aSubShapeObject, anHyp );
543 // Update Python script
544 // Update Python script
545 if(_impl->HasShapeToMesh()) {
546 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
547 << aSubShapeObject << ", " << anHyp << " )";
550 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
554 return ConvertHypothesisStatus(status);
557 //=============================================================================
561 //=============================================================================
563 SMESH_Hypothesis::Hypothesis_Status
564 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
565 SMESH::SMESH_Hypothesis_ptr anHyp)
567 if(MYDEBUG) MESSAGE("removeHypothesis()");
568 // **** proposer liste de subShape (selection multiple)
570 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
571 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
573 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
574 if (CORBA::is_nil(myHyp))
575 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
577 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
580 TopoDS_Shape myLocSubShape;
581 //use PseudoShape in case if mesh has no shape
583 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
585 myLocSubShape = _impl->GetShapeToMesh();
587 int hypId = myHyp->GetId();
588 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
589 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
590 // _mapHypo.erase( hypId );
592 catch(SALOME_Exception & S_ex)
594 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
599 //=============================================================================
603 //=============================================================================
605 SMESH::ListOfHypothesis *
606 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
607 throw(SALOME::SALOME_Exception)
609 Unexpect aCatch(SALOME_SalomeException);
610 if (MYDEBUG) MESSAGE("GetHypothesisList");
611 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
612 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
614 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
617 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
618 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
619 myLocSubShape = _impl->GetShapeToMesh();
620 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
621 int i = 0, n = aLocalList.size();
624 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
625 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
626 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
627 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
632 catch(SALOME_Exception & S_ex) {
633 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
636 return aList._retn();
639 //=============================================================================
643 //=============================================================================
644 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
645 const char* theName )
646 throw(SALOME::SALOME_Exception)
648 Unexpect aCatch(SALOME_SalomeException);
649 MESSAGE("SMESH_Mesh_i::GetSubMesh");
650 if (CORBA::is_nil(aSubShapeObject))
651 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
654 SMESH::SMESH_subMesh_var subMesh;
655 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
657 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
659 //Get or Create the SMESH_subMesh object implementation
661 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
663 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
665 TopoDS_Iterator it( myLocSubShape );
667 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
669 subMesh = getSubMesh( subMeshId );
671 // create a new subMesh object servant if there is none for the shape
672 if ( subMesh->_is_nil() )
673 subMesh = createSubMesh( aSubShapeObject );
674 if ( _gen_i->CanPublishInStudy( subMesh )) {
675 SALOMEDS::SObject_var aSO =
676 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
677 subMesh, aSubShapeObject, theName );
678 if ( !aSO->_is_nil()) {
679 // Update Python script
680 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
681 << aSubShapeObject << ", '" << theName << "' )";
685 catch(SALOME_Exception & S_ex) {
686 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
688 return subMesh._retn();
691 //=============================================================================
695 //=============================================================================
697 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
698 throw (SALOME::SALOME_Exception)
700 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
701 if ( theSubMesh->_is_nil() )
704 GEOM::GEOM_Object_var aSubShapeObject;
705 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
706 if ( !aStudy->_is_nil() ) {
707 // Remove submesh's SObject
708 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
709 if ( !anSO->_is_nil() ) {
710 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
711 SALOMEDS::SObject_var anObj, aRef;
712 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
713 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
715 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
716 // aSubShapeObject = theSubMesh->GetSubShape();
718 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
720 // Update Python script
721 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
725 removeSubMesh( theSubMesh, aSubShapeObject.in() );
728 //=============================================================================
732 //=============================================================================
733 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
734 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
736 switch (theElemType) {
741 CASE2STRING( VOLUME );
742 CASE2STRING( ELEM0D );
748 //=============================================================================
752 //=============================================================================
754 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
755 const char* theName )
756 throw(SALOME::SALOME_Exception)
758 Unexpect aCatch(SALOME_SalomeException);
759 SMESH::SMESH_Group_var aNewGroup =
760 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
762 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
763 SALOMEDS::SObject_var aSO =
764 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
765 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
766 if ( !aSO->_is_nil()) {
767 // Update Python script
768 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
769 << ElementTypeString(theElemType) << ", '" << theName << "' )";
772 return aNewGroup._retn();
776 //=============================================================================
780 //=============================================================================
781 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
783 GEOM::GEOM_Object_ptr theGeomObj)
784 throw(SALOME::SALOME_Exception)
786 Unexpect aCatch(SALOME_SalomeException);
787 SMESH::SMESH_GroupOnGeom_var aNewGroup;
789 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
790 if ( !aShape.IsNull() )
792 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
793 ( createGroup( theElemType, theName, aShape ));
795 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
796 SALOMEDS::SObject_var aSO =
797 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
798 aNewGroup, theGeomObj, theName);
799 if ( !aSO->_is_nil()) {
800 // Update Python script
801 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
802 << ElementTypeString(theElemType) << ", '" << theName << "', "
803 << theGeomObj << " )";
808 return aNewGroup._retn();
811 //=============================================================================
815 //=============================================================================
817 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
818 throw (SALOME::SALOME_Exception)
820 if ( theGroup->_is_nil() )
823 SMESH_GroupBase_i* aGroup =
824 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
828 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
829 if ( !aStudy->_is_nil() ) {
830 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
832 if ( !aGroupSO->_is_nil() ) {
833 // Update Python script
834 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
836 // Remove group's SObject
837 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
841 // Remove the group from SMESH data structures
842 removeGroup( aGroup->GetLocalID() );
845 //=============================================================================
846 /*! RemoveGroupWithContents
847 * Remove group with its contents
849 //=============================================================================
850 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
851 throw (SALOME::SALOME_Exception)
853 if ( theGroup->_is_nil() )
856 SMESH_GroupBase_i* aGroup =
857 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
861 SMESH::long_array_var anIds = aGroup->GetListOfID();
862 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
864 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
867 if ( aGroup->GetType() == SMESH::NODE )
868 aMeshEditor->RemoveNodes( anIds );
870 aMeshEditor->RemoveElements( anIds );
873 RemoveGroup( theGroup );
875 // Update Python script
876 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
879 //================================================================================
881 * \brief Get the list of groups existing in the mesh
882 * \retval SMESH::ListOfGroups * - list of groups
884 //================================================================================
886 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
888 Unexpect aCatch(SALOME_SalomeException);
889 if (MYDEBUG) MESSAGE("GetGroups");
891 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
894 TPythonDump aPythonDump;
895 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
899 aList->length( _mapGroups.size() );
901 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
902 for ( ; it != _mapGroups.end(); it++ ) {
903 if ( CORBA::is_nil( it->second )) continue;
904 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
906 if (i > 1) aPythonDump << ", ";
907 aPythonDump << it->second;
911 catch(SALOME_Exception & S_ex) {
912 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
915 // Update Python script
916 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
917 aPythonDump << " ] = " << _this() << ".GetGroups()";
919 return aList._retn();
922 //=============================================================================
924 * Get number of groups existing in the mesh
926 //=============================================================================
928 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
930 Unexpect aCatch(SALOME_SalomeException);
931 return _mapGroups.size();
934 //=============================================================================
936 * New group is created. All mesh elements that are
937 * present in initial groups are added to the new one
939 //=============================================================================
940 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
941 SMESH::SMESH_GroupBase_ptr theGroup2,
942 const char* theName )
943 throw (SALOME::SALOME_Exception)
947 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
948 theGroup1->GetType() != theGroup2->GetType() )
949 return SMESH::SMESH_Group::_nil();
952 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
953 if ( aResGrp->_is_nil() )
954 return SMESH::SMESH_Group::_nil();
956 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
957 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
959 TColStd_MapOfInteger aResMap;
961 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
962 aResMap.Add( anIds1[ i1 ] );
964 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
965 aResMap.Add( anIds2[ i2 ] );
967 SMESH::long_array_var aResIds = new SMESH::long_array;
968 aResIds->length( aResMap.Extent() );
971 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
972 for( ; anIter.More(); anIter.Next() )
973 aResIds[ resI++ ] = anIter.Key();
975 aResGrp->Add( aResIds );
977 // Clear python lines, created by CreateGroup() and Add()
978 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
979 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
980 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
982 // Update Python script
983 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
984 << theGroup1 << ", " << theGroup2 << ", '"
987 return aResGrp._retn();
991 return SMESH::SMESH_Group::_nil();
995 //=============================================================================
997 \brief Union list of groups. New group is created. All mesh elements that are
998 present in initial groups are added to the new one.
999 \param theGroups list of groups
1000 \param theName name of group to be created
1001 \return pointer on the group
1003 //=============================================================================
1004 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1005 const char* theName )
1006 throw (SALOME::SALOME_Exception)
1009 return SMESH::SMESH_Group::_nil();
1013 vector< int > anIds;
1014 SMESH::ElementType aType = SMESH::ALL;
1015 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1017 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1018 if ( CORBA::is_nil( aGrp ) )
1022 SMESH::ElementType aCurrType = aGrp->GetType();
1023 if ( aType == SMESH::ALL )
1027 if ( aType != aCurrType )
1028 return SMESH::SMESH_Group::_nil();
1032 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1033 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1035 int aCurrId = aCurrIds[ i ];
1036 anIds.push_back( aCurrId );
1041 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1042 if ( aResGrp->_is_nil() )
1043 return SMESH::SMESH_Group::_nil();
1045 // Create array of identifiers
1046 SMESH::long_array_var aResIds = new SMESH::long_array;
1047 aResIds->length( anIds.size() );
1049 //NCollection_Map< int >::Iterator anIter( anIds );
1050 for ( int i = 0; i<anIds.size(); i++ )
1052 aResIds[ i ] = anIds[i];
1054 aResGrp->Add( aResIds );
1056 // Clear python lines, created by CreateGroup() and Add()
1057 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1058 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1059 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1061 // Update Python script
1063 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1064 << &theGroups << ", '" << theName << "' )";
1066 return aResGrp._retn();
1070 return SMESH::SMESH_Group::_nil();
1074 //=============================================================================
1076 * New group is created. All mesh elements that are
1077 * present in both initial groups are added to the new one.
1079 //=============================================================================
1080 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1081 SMESH::SMESH_GroupBase_ptr theGroup2,
1082 const char* theName )
1083 throw (SALOME::SALOME_Exception)
1085 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1086 theGroup1->GetType() != theGroup2->GetType() )
1087 return SMESH::SMESH_Group::_nil();
1089 // Create Intersection
1090 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1091 if ( aResGrp->_is_nil() )
1094 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1095 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1097 TColStd_MapOfInteger aMap1;
1099 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1100 aMap1.Add( anIds1[ i1 ] );
1102 TColStd_SequenceOfInteger aSeq;
1104 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1105 if ( aMap1.Contains( anIds2[ i2 ] ) )
1106 aSeq.Append( anIds2[ i2 ] );
1108 SMESH::long_array_var aResIds = new SMESH::long_array;
1109 aResIds->length( aSeq.Length() );
1111 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1112 aResIds[ resI ] = aSeq( resI + 1 );
1114 aResGrp->Add( aResIds );
1116 // Clear python lines, created by CreateGroup() and Add()
1117 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1118 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1119 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1121 // Update Python script
1122 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1123 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1125 return aResGrp._retn();
1128 //=============================================================================
1130 \brief Intersect list of groups. New group is created. All mesh elements that
1131 are present in all initial groups simultaneously are added to the new one.
1132 \param theGroups list of groups
1133 \param theName name of group to be created
1134 \return pointer on the group
1136 //=============================================================================
1137 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1138 const SMESH::ListOfGroups& theGroups, const char* theName )
1139 throw (SALOME::SALOME_Exception)
1142 return SMESH::SMESH_Group::_nil();
1146 NCollection_DataMap< int, int > anIdToCount;
1147 SMESH::ElementType aType = SMESH::ALL;
1148 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1150 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1151 if ( CORBA::is_nil( aGrp ) )
1155 SMESH::ElementType aCurrType = aGrp->GetType();
1156 if ( aType == SMESH::ALL )
1160 if ( aType != aCurrType )
1161 return SMESH::SMESH_Group::_nil();
1164 // calculates number of occurance ids in groups
1165 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1166 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1168 int aCurrId = aCurrIds[ i ];
1169 if ( !anIdToCount.IsBound( aCurrId ) )
1170 anIdToCount.Bind( aCurrId, 1 );
1172 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1176 // create map of ids
1177 int nbGrp = theGroups.length();
1178 vector< int > anIds;
1179 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1180 for ( ; anIter.More(); anIter.Next() )
1182 int aCurrId = anIter.Key();
1183 int aCurrNb = anIter.Value();
1184 if ( aCurrNb == nbGrp )
1185 anIds.push_back( aCurrId );
1189 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1190 if ( aResGrp->_is_nil() )
1191 return SMESH::SMESH_Group::_nil();
1193 // Create array of identifiers
1194 SMESH::long_array_var aResIds = new SMESH::long_array;
1195 aResIds->length( anIds.size() );
1197 //NCollection_Map< int >::Iterator aListIter( anIds );
1198 for ( int i = 0; i<anIds.size(); i++ )
1200 aResIds[ i ] = anIds[i];
1202 aResGrp->Add( aResIds );
1204 // Clear python lines, created by CreateGroup() and Add()
1205 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1206 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1207 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1209 // Update Python script
1211 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1212 << &theGroups << ", '" << theName << "' )";
1214 return aResGrp._retn();
1218 return SMESH::SMESH_Group::_nil();
1222 //=============================================================================
1224 * New group is created. All mesh elements that are present in
1225 * main group but do not present in tool group are added to the new one
1227 //=============================================================================
1228 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1229 SMESH::SMESH_GroupBase_ptr theGroup2,
1230 const char* theName )
1231 throw (SALOME::SALOME_Exception)
1233 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1234 theGroup1->GetType() != theGroup2->GetType() )
1235 return SMESH::SMESH_Group::_nil();
1238 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1239 if ( aResGrp->_is_nil() )
1242 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1243 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1245 TColStd_MapOfInteger aMap2;
1247 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1248 aMap2.Add( anIds2[ i2 ] );
1250 TColStd_SequenceOfInteger aSeq;
1251 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1252 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1253 aSeq.Append( anIds1[ i1 ] );
1255 SMESH::long_array_var aResIds = new SMESH::long_array;
1256 aResIds->length( aSeq.Length() );
1258 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1259 aResIds[ resI ] = aSeq( resI + 1 );
1261 aResGrp->Add( aResIds );
1263 // Clear python lines, created by CreateGroup() and Add()
1264 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1265 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1266 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1268 // Update Python script
1269 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1270 << theGroup1 << ", " << theGroup2 << ", '"
1271 << theName << "' )";
1273 return aResGrp._retn();
1276 //=============================================================================
1278 \brief Cut lists of groups. New group is created. All mesh elements that are
1279 present in main groups but do not present in tool groups are added to the new one
1280 \param theMainGroups list of main groups
1281 \param theToolGroups list of tool groups
1282 \param theName name of group to be created
1283 \return pointer on the group
1285 //=============================================================================
1286 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1287 const SMESH::ListOfGroups& theMainGroups,
1288 const SMESH::ListOfGroups& theToolGroups,
1289 const char* theName )
1290 throw (SALOME::SALOME_Exception)
1293 return SMESH::SMESH_Group::_nil();
1297 set< int > aToolIds;
1298 SMESH::ElementType aType = SMESH::ALL;
1300 // iterate through tool groups
1301 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1303 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1304 if ( CORBA::is_nil( aGrp ) )
1308 SMESH::ElementType aCurrType = aGrp->GetType();
1309 if ( aType == SMESH::ALL )
1313 if ( aType != aCurrType )
1314 return SMESH::SMESH_Group::_nil();
1318 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1319 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1321 int aCurrId = aCurrIds[ i ];
1322 aToolIds.insert( aCurrId );
1326 vector< int > anIds; // result
1328 // Iterate through main group
1329 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1331 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1332 if ( CORBA::is_nil( aGrp ) )
1336 SMESH::ElementType aCurrType = aGrp->GetType();
1337 if ( aType == SMESH::ALL )
1341 if ( aType != aCurrType )
1342 return SMESH::SMESH_Group::_nil();
1346 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1347 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1349 int aCurrId = aCurrIds[ i ];
1350 if ( !aToolIds.count( aCurrId ) )
1351 anIds.push_back( aCurrId );
1356 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1357 if ( aResGrp->_is_nil() )
1358 return SMESH::SMESH_Group::_nil();
1360 // Create array of identifiers
1361 SMESH::long_array_var aResIds = new SMESH::long_array;
1362 aResIds->length( anIds.size() );
1364 for (int i=0; i<anIds.size(); i++ )
1366 aResIds[ i ] = anIds[i];
1368 aResGrp->Add( aResIds );
1370 // Clear python lines, created by CreateGroup() and Add()
1371 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1372 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1373 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1375 // Update Python script
1377 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1378 << &theMainGroups << ", " << &theToolGroups << ", '"
1379 << theName << "' )";
1381 return aResGrp._retn();
1385 return SMESH::SMESH_Group::_nil();
1389 //=============================================================================
1391 \brief Create groups of entities from existing groups of superior dimensions
1393 1) extract all nodes from each group,
1394 2) combine all elements of specified dimension laying on these nodes.
1395 \param theGroups list of source groups
1396 \param theElemType dimension of elements
1397 \param theName name of new group
1398 \return pointer on new group
1400 //=============================================================================
1401 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1402 const SMESH::ListOfGroups& theGroups,
1403 SMESH::ElementType theElemType,
1404 const char* theName )
1405 throw (SALOME::SALOME_Exception)
1407 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1409 if ( !theName || !aMeshDS )
1410 return SMESH::SMESH_Group::_nil();
1412 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1416 // Create map of nodes from all groups
1418 set< int > aNodeMap;
1420 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1422 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1423 if ( CORBA::is_nil( aGrp ) )
1426 SMESH::ElementType aType = aGrp->GetType();
1427 if ( aType == SMESH::ALL )
1429 else if ( aType == SMESH::NODE )
1431 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1432 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1434 int aCurrId = aCurrIds[ i ];
1435 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1437 aNodeMap.insert( aNode->GetID() );
1442 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1443 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1445 int aCurrId = aCurrIds[ i ];
1446 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1449 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1450 while( aNodeIter->more() )
1452 const SMDS_MeshNode* aNode =
1453 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1455 aNodeMap.insert( aNode->GetID() );
1461 // Get result identifiers
1463 vector< int > aResultIds;
1464 if ( theElemType == SMESH::NODE )
1466 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1467 set<int>::iterator iter = aNodeMap.begin();
1468 for ( ; iter != aNodeMap.end(); iter++ )
1469 aResultIds.push_back( *iter);
1473 // Create list of elements of given dimension constructed on the nodes
1474 vector< int > anElemList;
1475 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1476 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1477 set<int>::iterator iter = aNodeMap.begin();
1478 for ( ; iter != aNodeMap.end(); iter++ )
1480 const SMDS_MeshElement* aNode =
1481 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1485 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1486 while( anElemIter->more() )
1488 const SMDS_MeshElement* anElem =
1489 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1490 if ( anElem && anElem->GetType() == anElemType )
1491 anElemList.push_back( anElem->GetID() );
1495 // check whether all nodes of elements are present in nodes map
1496 //NCollection_Map< int >::Iterator anIter( anElemList );
1497 //for ( ; anIter.More(); anIter.Next() )
1498 for (int i=0; i< anElemList.size(); i++)
1500 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1505 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1506 while( aNodeIter->more() )
1508 const SMDS_MeshNode* aNode =
1509 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1510 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1517 aResultIds.push_back( anElem->GetID() );
1523 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1524 if ( aResGrp->_is_nil() )
1525 return SMESH::SMESH_Group::_nil();
1527 // Create array of identifiers
1528 SMESH::long_array_var aResIds = new SMESH::long_array;
1529 aResIds->length( aResultIds.size() );
1531 //NCollection_Map< int >::Iterator aResIter( aResultIds );
1532 //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1533 for (int i=0; i< aResultIds.size(); i++)
1534 aResIds[ i ] = aResultIds[i];
1535 aResGrp->Add( aResIds );
1537 // Remove strings corresponding to group creation
1538 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1539 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1540 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1542 // Update Python script
1544 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1545 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1547 return aResGrp._retn();
1551 return SMESH::SMESH_Group::_nil();
1555 //================================================================================
1557 * \brief Remember GEOM group data
1559 //================================================================================
1561 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1562 CORBA::Object_ptr theSmeshObj)
1564 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1567 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1568 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1569 if ( groupSO->_is_nil() )
1572 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1573 GEOM::GEOM_IGroupOperations_var groupOp =
1574 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1575 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1578 _geomGroupData.push_back( TGeomGroupData() );
1579 TGeomGroupData & groupData = _geomGroupData.back();
1581 CORBA::String_var entry = groupSO->GetID();
1582 groupData._groupEntry = entry.in();
1584 for ( int i = 0; i < ids->length(); ++i )
1585 groupData._indices.insert( ids[i] );
1587 groupData._smeshObject = theSmeshObj;
1590 //================================================================================
1592 * Remove GEOM group data relating to removed smesh object
1594 //================================================================================
1596 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1598 list<TGeomGroupData>::iterator
1599 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1600 for ( ; data != dataEnd; ++data ) {
1601 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1602 _geomGroupData.erase( data );
1608 //================================================================================
1610 * \brief Return new group contents if it has been changed and update group data
1612 //================================================================================
1614 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1616 TopoDS_Shape newShape;
1619 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1620 if ( study->_is_nil() ) return newShape; // means "not changed"
1621 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1622 if ( !groupSO->_is_nil() )
1624 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1625 if ( CORBA::is_nil( groupObj )) return newShape;
1626 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1628 // get indices of group items
1629 set<int> curIndices;
1630 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1631 GEOM::GEOM_IGroupOperations_var groupOp =
1632 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1633 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1634 for ( int i = 0; i < ids->length(); ++i )
1635 curIndices.insert( ids[i] );
1637 if ( groupData._indices == curIndices )
1638 return newShape; // group not changed
1641 groupData._indices = curIndices;
1643 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1644 if ( !geomClient ) return newShape;
1645 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1646 geomClient->RemoveShapeFromBuffer( groupIOR );
1647 newShape = _gen_i->GeomObjectToShape( geomGroup );
1650 if ( newShape.IsNull() ) {
1651 // geom group becomes empty - return empty compound
1652 TopoDS_Compound compound;
1653 BRep_Builder().MakeCompound(compound);
1654 newShape = compound;
1660 //=============================================================================
1662 * \brief Storage of shape and index used in CheckGeomGroupModif()
1664 //=============================================================================
1665 struct TIndexedShape {
1667 TopoDS_Shape _shape;
1668 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1671 //=============================================================================
1673 * \brief Update objects depending on changed geom groups
1675 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1676 * issue 0020210: Update of a smesh group after modification of the associated geom group
1678 //=============================================================================
1680 void SMESH_Mesh_i::CheckGeomGroupModif()
1682 if ( !_impl->HasShapeToMesh() ) return;
1684 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1685 if ( study->_is_nil() ) return;
1687 CORBA::Long nbEntities = NbNodes() + NbElements();
1689 // Check if group contents changed
1691 typedef map< string, TopoDS_Shape > TEntry2Geom;
1692 TEntry2Geom newGroupContents;
1694 list<TGeomGroupData>::iterator
1695 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1696 for ( ; data != dataEnd; ++data )
1698 pair< TEntry2Geom::iterator, bool > it_new =
1699 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1700 bool processedGroup = !it_new.second;
1701 TopoDS_Shape& newShape = it_new.first->second;
1702 if ( !processedGroup )
1703 newShape = newGroupShape( *data );
1704 if ( newShape.IsNull() )
1705 continue; // no changes
1707 if ( processedGroup ) { // update group indices
1708 list<TGeomGroupData>::iterator data2 = data;
1709 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1710 data->_indices = data2->_indices;
1713 // Update SMESH objects according to new GEOM group contents
1715 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1716 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1718 int oldID = submesh->GetId();
1719 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1721 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1723 // update hypotheses
1724 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1725 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1726 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1728 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1729 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1731 // care of submeshes
1732 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1733 int newID = newSubmesh->GetId();
1734 if ( newID != oldID ) {
1735 _mapSubMesh [ newID ] = newSubmesh;
1736 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1737 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1738 _mapSubMesh. erase(oldID);
1739 _mapSubMesh_i. erase(oldID);
1740 _mapSubMeshIor.erase(oldID);
1741 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1746 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1747 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1748 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1750 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1752 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1753 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1754 ds->SetShape( newShape );
1759 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1760 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1762 // Remove groups and submeshes basing on removed sub-shapes
1764 TopTools_MapOfShape newShapeMap;
1765 TopoDS_Iterator shapeIt( newShape );
1766 for ( ; shapeIt.More(); shapeIt.Next() )
1767 newShapeMap.Add( shapeIt.Value() );
1769 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1770 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1772 if ( newShapeMap.Contains( shapeIt.Value() ))
1774 TopTools_IndexedMapOfShape oldShapeMap;
1775 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1776 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1778 const TopoDS_Shape& oldShape = oldShapeMap(i);
1779 int oldInd = meshDS->ShapeToIndex( oldShape );
1781 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1782 if ( i_smIor != _mapSubMeshIor.end() ) {
1783 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1786 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1787 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1789 // check if a group bases on oldInd shape
1790 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1791 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1792 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1793 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1795 RemoveGroup( i_grp->second ); // several groups can base on same shape
1796 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1801 // Reassign hypotheses and update groups after setting the new shape to mesh
1803 // collect anassigned hypotheses
1804 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1805 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1806 TShapeHypList assignedHyps;
1807 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1809 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1810 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1811 if ( !hyps.empty() ) {
1812 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1813 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1814 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1817 // collect shapes supporting groups
1818 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1819 TShapeTypeList groupData;
1820 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1821 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1822 for ( ; grIt != groups.end(); ++grIt )
1824 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1826 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1828 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1829 _impl->ShapeToMesh( newShape );
1831 // reassign hypotheses
1832 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1833 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1835 TIndexedShape& geom = indS_hyps->first;
1836 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1837 int oldID = geom._index;
1838 int newID = meshDS->ShapeToIndex( geom._shape );
1841 if ( oldID == 1 ) { // main shape
1843 geom._shape = newShape;
1845 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1846 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1847 // care of submeshes
1848 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1849 if ( newID != oldID ) {
1850 _mapSubMesh [ newID ] = newSubmesh;
1851 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1852 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1853 _mapSubMesh. erase(oldID);
1854 _mapSubMesh_i. erase(oldID);
1855 _mapSubMeshIor.erase(oldID);
1856 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1860 TShapeTypeList::iterator geomType = groupData.begin();
1861 for ( ; geomType != groupData.end(); ++geomType )
1863 const TIndexedShape& geom = geomType->first;
1864 int oldID = geom._index;
1865 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1868 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1869 CORBA::String_var name = groupSO->GetName();
1871 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1873 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1874 group_i->changeLocalId( newID );
1877 break; // everything has been updated
1880 } // loop on group data
1884 CORBA::Long newNbEntities = NbNodes() + NbElements();
1885 list< SALOMEDS::SObject_var > soToUpdateIcons;
1886 if ( newNbEntities != nbEntities )
1888 // Add all SObjects with icons
1889 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1891 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1892 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1893 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1895 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1896 i_gr != _mapGroups.end(); ++i_gr ) // groups
1897 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1900 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1901 for ( ; so != soToUpdateIcons.end(); ++so )
1902 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1905 //=============================================================================
1907 * \brief Create standalone group instead if group on geometry
1909 //=============================================================================
1911 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1913 SMESH::SMESH_Group_var aGroup;
1914 if ( theGroup->_is_nil() )
1915 return aGroup._retn();
1917 Unexpect aCatch(SALOME_SalomeException);
1919 SMESH_GroupBase_i* aGroupToRem =
1920 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1922 return aGroup._retn();
1924 int anId = aGroupToRem->GetLocalID();
1925 if ( !_impl->ConvertToStandalone( anId ) )
1926 return aGroup._retn();
1927 removeGeomGroupData( theGroup );
1929 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1931 // remove old instance of group from own map
1932 _mapGroups.erase( anId );
1934 SALOMEDS::StudyBuilder_var builder;
1935 SALOMEDS::SObject_var aGroupSO;
1936 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1937 if ( !aStudy->_is_nil() ) {
1938 builder = aStudy->NewBuilder();
1939 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1940 if ( !aGroupSO->_is_nil() ) {
1942 // remove reference to geometry
1943 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1944 for ( ; chItr->More(); chItr->Next() )
1945 // Remove group's child SObject
1946 builder->RemoveObject( chItr->Value() );
1948 // Update Python script
1949 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1950 << aGroupSO << " )";
1954 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1955 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1956 aGroupImpl->Register();
1957 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1959 // remember new group in own map
1960 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1961 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1963 // register CORBA object for persistence
1964 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1966 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1968 return aGroup._retn();
1971 //=============================================================================
1975 //=============================================================================
1977 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1979 if(MYDEBUG) MESSAGE( "createSubMesh" );
1980 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1982 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1983 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1984 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1985 SMESH::SMESH_subMesh_var subMesh
1986 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1988 _mapSubMesh[subMeshId] = mySubMesh;
1989 _mapSubMesh_i[subMeshId] = subMeshServant;
1990 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1992 // register CORBA object for persistence
1993 int nextId = _gen_i->RegisterObject( subMesh );
1994 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1996 // to track changes of GEOM groups
1997 addGeomGroupData( theSubShapeObject, subMesh );
1999 return subMesh._retn();
2002 //=======================================================================
2003 //function : getSubMesh
2005 //=======================================================================
2007 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2009 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2010 if ( it == _mapSubMeshIor.end() )
2011 return SMESH::SMESH_subMesh::_nil();
2013 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2017 //=============================================================================
2021 //=============================================================================
2023 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2024 GEOM::GEOM_Object_ptr theSubShapeObject )
2026 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2027 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2030 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2032 CORBA::Long shapeId = theSubMesh->GetId();
2033 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2035 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2038 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2039 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2040 for ( ; hyp != hyps.end(); ++hyp )
2041 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2048 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2049 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2050 removeHypothesis( theSubShapeObject, aHypList[i] );
2053 catch( const SALOME::SALOME_Exception& ) {
2054 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2056 removeGeomGroupData( theSubShapeObject );
2058 int subMeshId = theSubMesh->GetId();
2060 _mapSubMesh.erase(subMeshId);
2061 _mapSubMesh_i.erase(subMeshId);
2062 _mapSubMeshIor.erase(subMeshId);
2063 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2066 //=============================================================================
2070 //=============================================================================
2072 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2073 const char* theName,
2074 const TopoDS_Shape& theShape )
2076 std::string newName;
2077 if ( !theName || strlen( theName ) == 0 )
2079 std::set< std::string > presentNames;
2080 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2081 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2082 presentNames.insert( i_gr->second->GetName() );
2084 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2085 } while ( !presentNames.insert( newName ).second );
2086 theName = newName.c_str();
2089 SMESH::SMESH_GroupBase_var aGroup;
2090 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2091 SMESH_GroupBase_i* aGroupImpl;
2092 if ( !theShape.IsNull() )
2093 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2095 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2097 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2098 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2099 aGroupImpl->Register();
2100 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2102 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2103 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2105 // register CORBA object for persistence
2106 int nextId = _gen_i->RegisterObject( aGroup );
2107 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2109 // to track changes of GEOM groups
2110 if ( !theShape.IsNull() ) {
2111 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2112 addGeomGroupData( geom, aGroup );
2115 return aGroup._retn();
2118 //=============================================================================
2120 * SMESH_Mesh_i::removeGroup
2122 * Should be called by ~SMESH_Group_i()
2124 //=============================================================================
2126 void SMESH_Mesh_i::removeGroup( const int theId )
2128 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2129 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2130 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2131 _mapGroups.erase( theId );
2132 removeGeomGroupData( group );
2133 if (! _impl->RemoveGroup( theId ))
2135 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2136 RemoveGroup( group );
2141 //=============================================================================
2145 //=============================================================================
2147 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2148 throw(SALOME::SALOME_Exception)
2150 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2152 SMESH::log_array_var aLog;
2154 list < SMESHDS_Command * >logDS = _impl->GetLog();
2155 aLog = new SMESH::log_array;
2157 int lg = logDS.size();
2160 list < SMESHDS_Command * >::iterator its = logDS.begin();
2161 while(its != logDS.end()){
2162 SMESHDS_Command *com = *its;
2163 int comType = com->GetType();
2165 int lgcom = com->GetNumber();
2167 const list < int >&intList = com->GetIndexes();
2168 int inum = intList.size();
2170 list < int >::const_iterator ii = intList.begin();
2171 const list < double >&coordList = com->GetCoords();
2172 int rnum = coordList.size();
2174 list < double >::const_iterator ir = coordList.begin();
2175 aLog[indexLog].commandType = comType;
2176 aLog[indexLog].number = lgcom;
2177 aLog[indexLog].coords.length(rnum);
2178 aLog[indexLog].indexes.length(inum);
2179 for(int i = 0; i < rnum; i++){
2180 aLog[indexLog].coords[i] = *ir;
2181 //MESSAGE(" "<<i<<" "<<ir.Value());
2184 for(int i = 0; i < inum; i++){
2185 aLog[indexLog].indexes[i] = *ii;
2186 //MESSAGE(" "<<i<<" "<<ii.Value());
2195 catch(SALOME_Exception & S_ex){
2196 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2198 return aLog._retn();
2202 //=============================================================================
2206 //=============================================================================
2208 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2210 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2214 //=============================================================================
2218 //=============================================================================
2220 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2222 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2226 //=============================================================================
2230 //=============================================================================
2232 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2237 //=============================================================================
2240 //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
2241 // SMESH_Mesh::RemoveGroup() (issue 0020918)
2242 struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
2244 SMESH_Mesh_i* _mesh;
2245 TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2246 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2250 //=============================================================================
2254 //=============================================================================
2256 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2258 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2261 _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
2264 //=============================================================================
2268 //=============================================================================
2270 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2272 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2276 //=============================================================================
2278 * Return mesh editor
2280 //=============================================================================
2282 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2284 // Create MeshEditor
2285 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2286 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2288 // Update Python script
2289 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2291 return aMesh._retn();
2294 //=============================================================================
2296 * Return mesh edition previewer
2298 //=============================================================================
2300 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2302 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2303 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2304 return aMesh._retn();
2307 //================================================================================
2309 * \brief Return true if the mesh has been edited since a last total re-compute
2310 * and those modifications may prevent successful partial re-compute
2312 //================================================================================
2314 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2316 Unexpect aCatch(SALOME_SalomeException);
2317 return _impl->HasModificationsToDiscard();
2320 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2322 const int MAX_ATTEMPTS = 100;
2324 double tolerance = 0.5;
2325 SALOMEDS::Color col;
2329 // generate random color
2330 double red = (double)rand() / RAND_MAX;
2331 double green = (double)rand() / RAND_MAX;
2332 double blue = (double)rand() / RAND_MAX;
2333 // check existence in the list of the existing colors
2334 bool matched = false;
2335 std::list<SALOMEDS::Color>::const_iterator it;
2336 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2337 SALOMEDS::Color color = *it;
2338 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2339 matched = tol < tolerance;
2341 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2342 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2350 //=============================================================================
2354 //=============================================================================
2355 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2357 Unexpect aCatch(SALOME_SalomeException);
2358 _impl->SetAutoColor(theAutoColor);
2360 TPythonDump pyDump; // not to dump group->SetColor() from below code
2361 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2363 std::list<SALOMEDS::Color> aReservedColors;
2364 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2365 for ( ; it != _mapGroups.end(); it++ ) {
2366 if ( CORBA::is_nil( it->second )) continue;
2367 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2368 it->second->SetColor( aColor );
2369 aReservedColors.push_back( aColor );
2373 //=============================================================================
2377 //=============================================================================
2378 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2380 Unexpect aCatch(SALOME_SalomeException);
2381 return _impl->GetAutoColor();
2385 //=============================================================================
2387 * Export in different formats
2389 //=============================================================================
2391 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2393 return _impl->HasDuplicatedGroupNamesMED();
2396 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2398 TCollection_AsciiString aFullName ((char*)file);
2399 OSD_Path aPath (aFullName);
2400 OSD_File aFile (aPath);
2401 if (aFile.Exists()) {
2402 // existing filesystem node
2403 if (aFile.KindOfFile() == OSD_FILE) {
2404 if (aFile.IsWriteable()) {
2409 if (aFile.Failed()) {
2410 TCollection_AsciiString msg ("File ");
2411 msg += aFullName + " cannot be replaced.";
2412 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2415 TCollection_AsciiString msg ("File ");
2416 msg += aFullName + " cannot be overwritten.";
2417 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2420 TCollection_AsciiString msg ("Location ");
2421 msg += aFullName + " is not a file.";
2422 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2425 // nonexisting file; check if it can be created
2427 aFile.Build(OSD_WriteOnly, OSD_Protection());
2428 if (aFile.Failed()) {
2429 TCollection_AsciiString msg ("You cannot create the file ");
2430 msg += aFullName + ". Check the directory existance and access rights.";
2431 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2439 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2440 CORBA::Boolean auto_groups,
2441 SMESH::MED_VERSION theVersion,
2442 CORBA::Boolean overwrite)
2443 throw(SALOME::SALOME_Exception)
2445 Unexpect aCatch(SALOME_SalomeException);
2448 PrepareForWriting(file, overwrite);
2449 const char* aMeshName = "Mesh";
2450 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2451 if ( !aStudy->_is_nil() ) {
2452 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2453 if ( !aMeshSO->_is_nil() ) {
2454 aMeshName = aMeshSO->GetName();
2455 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2456 if ( !aStudy->GetProperties()->IsLocked() )
2458 SALOMEDS::GenericAttribute_var anAttr;
2459 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2460 SALOMEDS::AttributeExternalFileDef_var aFileName;
2461 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2462 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2463 ASSERT(!aFileName->_is_nil());
2464 aFileName->SetValue(file);
2465 SALOMEDS::AttributeFileType_var aFileType;
2466 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2467 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2468 ASSERT(!aFileType->_is_nil());
2469 aFileType->SetValue("FICHIERMED");
2473 // Update Python script
2474 // set name of mesh before export
2475 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2477 // check names of groups
2480 TPythonDump() << _this() << ".ExportToMEDX( r'"
2481 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2483 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2486 void SMESH_Mesh_i::ExportToMED (const char* file,
2487 CORBA::Boolean auto_groups,
2488 SMESH::MED_VERSION theVersion)
2489 throw(SALOME::SALOME_Exception)
2491 ExportToMEDX(file,auto_groups,theVersion,true);
2494 void SMESH_Mesh_i::ExportMED (const char* file,
2495 CORBA::Boolean auto_groups)
2496 throw(SALOME::SALOME_Exception)
2498 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2501 void SMESH_Mesh_i::ExportDAT (const char *file)
2502 throw(SALOME::SALOME_Exception)
2504 Unexpect aCatch(SALOME_SalomeException);
2506 // Update Python script
2507 // check names of groups
2509 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2512 PrepareForWriting(file);
2513 _impl->ExportDAT(file);
2516 void SMESH_Mesh_i::ExportUNV (const char *file)
2517 throw(SALOME::SALOME_Exception)
2519 Unexpect aCatch(SALOME_SalomeException);
2521 // Update Python script
2522 // check names of groups
2524 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2527 PrepareForWriting(file);
2528 _impl->ExportUNV(file);
2531 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2532 throw(SALOME::SALOME_Exception)
2534 Unexpect aCatch(SALOME_SalomeException);
2536 // Update Python script
2537 // check names of groups
2539 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2542 PrepareForWriting(file);
2543 _impl->ExportSTL(file, isascii);
2546 //=============================================================================
2550 //=============================================================================
2552 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2554 Unexpect aCatch(SALOME_SalomeException);
2555 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2556 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2557 return aMesh._retn();
2560 //=============================================================================
2564 //=============================================================================
2565 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2567 Unexpect aCatch(SALOME_SalomeException);
2568 return _impl->NbNodes();
2571 //=============================================================================
2575 //=============================================================================
2576 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2578 Unexpect aCatch(SALOME_SalomeException);
2579 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2582 //=============================================================================
2586 //=============================================================================
2587 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2589 Unexpect aCatch(SALOME_SalomeException);
2590 return _impl->Nb0DElements();
2593 //=============================================================================
2597 //=============================================================================
2598 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2600 Unexpect aCatch(SALOME_SalomeException);
2601 return _impl->NbEdges();
2604 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2605 throw(SALOME::SALOME_Exception)
2607 Unexpect aCatch(SALOME_SalomeException);
2608 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2611 //=============================================================================
2615 //=============================================================================
2616 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2618 Unexpect aCatch(SALOME_SalomeException);
2619 return _impl->NbFaces();
2622 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2624 Unexpect aCatch(SALOME_SalomeException);
2625 return _impl->NbTriangles();
2628 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2630 Unexpect aCatch(SALOME_SalomeException);
2631 return _impl->NbQuadrangles();
2634 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2636 Unexpect aCatch(SALOME_SalomeException);
2637 return _impl->NbPolygons();
2640 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2641 throw(SALOME::SALOME_Exception)
2643 Unexpect aCatch(SALOME_SalomeException);
2644 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2647 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2648 throw(SALOME::SALOME_Exception)
2650 Unexpect aCatch(SALOME_SalomeException);
2651 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2654 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2655 throw(SALOME::SALOME_Exception)
2657 Unexpect aCatch(SALOME_SalomeException);
2658 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2661 //=============================================================================
2665 //=============================================================================
2666 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2668 Unexpect aCatch(SALOME_SalomeException);
2669 return _impl->NbVolumes();
2672 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2674 Unexpect aCatch(SALOME_SalomeException);
2675 return _impl->NbTetras();
2678 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2680 Unexpect aCatch(SALOME_SalomeException);
2681 return _impl->NbHexas();
2684 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2686 Unexpect aCatch(SALOME_SalomeException);
2687 return _impl->NbPyramids();
2690 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2692 Unexpect aCatch(SALOME_SalomeException);
2693 return _impl->NbPrisms();
2696 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2698 Unexpect aCatch(SALOME_SalomeException);
2699 return _impl->NbPolyhedrons();
2702 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2703 throw(SALOME::SALOME_Exception)
2705 Unexpect aCatch(SALOME_SalomeException);
2706 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2709 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2710 throw(SALOME::SALOME_Exception)
2712 Unexpect aCatch(SALOME_SalomeException);
2713 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2716 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2717 throw(SALOME::SALOME_Exception)
2719 Unexpect aCatch(SALOME_SalomeException);
2720 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2723 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2724 throw(SALOME::SALOME_Exception)
2726 Unexpect aCatch(SALOME_SalomeException);
2727 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2730 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2731 throw(SALOME::SALOME_Exception)
2733 Unexpect aCatch(SALOME_SalomeException);
2734 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2737 //=============================================================================
2741 //=============================================================================
2742 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2744 Unexpect aCatch(SALOME_SalomeException);
2745 return _mapSubMesh_i.size();
2748 //=============================================================================
2752 //=============================================================================
2753 char* SMESH_Mesh_i::Dump()
2757 return CORBA::string_dup( os.str().c_str() );
2760 //=============================================================================
2764 //=============================================================================
2765 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2767 // SMESH::long_array_var aResult = new SMESH::long_array();
2768 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2769 // int aMinId = aSMESHDS_Mesh->MinElementID();
2770 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2772 // aResult->length(aMaxId - aMinId + 1);
2774 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2775 // aResult[i++] = id;
2777 // return aResult._retn();
2779 return GetElementsId();
2782 //=============================================================================
2786 //=============================================================================
2788 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2789 throw (SALOME::SALOME_Exception)
2791 Unexpect aCatch(SALOME_SalomeException);
2792 MESSAGE("SMESH_Mesh_i::GetElementsId");
2793 SMESH::long_array_var aResult = new SMESH::long_array();
2794 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2796 if ( aSMESHDS_Mesh == NULL )
2797 return aResult._retn();
2799 long nbElements = NbElements();
2800 aResult->length( nbElements );
2801 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2802 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2803 aResult[i] = anIt->next()->GetID();
2805 return aResult._retn();
2809 //=============================================================================
2813 //=============================================================================
2815 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2816 throw (SALOME::SALOME_Exception)
2818 Unexpect aCatch(SALOME_SalomeException);
2819 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2820 SMESH::long_array_var aResult = new SMESH::long_array();
2821 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2823 if ( aSMESHDS_Mesh == NULL )
2824 return aResult._retn();
2826 long nbElements = NbElements();
2828 // No sense in returning ids of elements along with ids of nodes:
2829 // when theElemType == SMESH::ALL, return node ids only if
2830 // there are no elements
2831 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
2832 return GetNodesId();
2834 aResult->length( nbElements );
2838 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2839 while ( i < nbElements && anIt->more() ) {
2840 const SMDS_MeshElement* anElem = anIt->next();
2841 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2842 aResult[i++] = anElem->GetID();
2845 aResult->length( i );
2847 return aResult._retn();
2850 //=============================================================================
2854 //=============================================================================
2856 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2857 throw (SALOME::SALOME_Exception)
2859 Unexpect aCatch(SALOME_SalomeException);
2860 MESSAGE("SMESH_subMesh_i::GetNodesId");
2861 SMESH::long_array_var aResult = new SMESH::long_array();
2862 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2864 if ( aSMESHDS_Mesh == NULL )
2865 return aResult._retn();
2867 long nbNodes = NbNodes();
2868 aResult->length( nbNodes );
2869 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
2870 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2871 aResult[i] = anIt->next()->GetID();
2873 return aResult._retn();
2876 //=============================================================================
2880 //=============================================================================
2882 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2883 throw (SALOME::SALOME_Exception)
2885 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2888 //=============================================================================
2892 //=============================================================================
2894 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2895 throw (SALOME::SALOME_Exception)
2897 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2899 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2901 return ( SMESH::EntityType ) e->GetEntityType();
2904 //=============================================================================
2906 * Returns ID of elements for given submesh
2908 //=============================================================================
2909 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2910 throw (SALOME::SALOME_Exception)
2912 SMESH::long_array_var aResult = new SMESH::long_array();
2914 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2915 if(!SM) return aResult._retn();
2917 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2918 if(!SDSM) return aResult._retn();
2920 aResult->length(SDSM->NbElements());
2922 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2924 while ( eIt->more() ) {
2925 aResult[i++] = eIt->next()->GetID();
2928 return aResult._retn();
2932 //=============================================================================
2934 * Returns ID of nodes for given submesh
2935 * If param all==true - returns all nodes, else -
2936 * returns only nodes on shapes.
2938 //=============================================================================
2939 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2940 throw (SALOME::SALOME_Exception)
2942 SMESH::long_array_var aResult = new SMESH::long_array();
2944 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2945 if(!SM) return aResult._retn();
2947 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2948 if(!SDSM) return aResult._retn();
2951 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2952 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2953 while ( nIt->more() ) {
2954 const SMDS_MeshNode* elem = nIt->next();
2955 theElems.insert( elem->GetID() );
2958 else { // all nodes of submesh elements
2959 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2960 while ( eIt->more() ) {
2961 const SMDS_MeshElement* anElem = eIt->next();
2962 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2963 while ( nIt->more() ) {
2964 const SMDS_MeshElement* elem = nIt->next();
2965 theElems.insert( elem->GetID() );
2970 aResult->length(theElems.size());
2971 set<int>::iterator itElem;
2973 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2974 aResult[i++] = *itElem;
2976 return aResult._retn();
2980 //=============================================================================
2982 * Returns type of elements for given submesh
2984 //=============================================================================
2985 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2986 throw (SALOME::SALOME_Exception)
2988 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2989 if(!SM) return SMESH::ALL;
2991 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2992 if(!SDSM) return SMESH::ALL;
2994 if(SDSM->NbElements()==0)
2995 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2997 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2998 const SMDS_MeshElement* anElem = eIt->next();
2999 return ( SMESH::ElementType ) anElem->GetType();
3003 //=============================================================================
3007 //=============================================================================
3009 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3011 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3013 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3018 //=============================================================================
3020 * Get XYZ coordinates of node as list of double
3021 * If there is not node for given ID - returns empty list
3023 //=============================================================================
3025 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3027 SMESH::double_array_var aResult = new SMESH::double_array();
3028 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3029 if ( aSMESHDS_Mesh == NULL )
3030 return aResult._retn();
3033 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3035 return aResult._retn();
3039 aResult[0] = aNode->X();
3040 aResult[1] = aNode->Y();
3041 aResult[2] = aNode->Z();
3042 return aResult._retn();
3046 //=============================================================================
3048 * For given node returns list of IDs of inverse elements
3049 * If there is not node for given ID - returns empty list
3051 //=============================================================================
3053 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3055 SMESH::long_array_var aResult = new SMESH::long_array();
3056 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3057 if ( aSMESHDS_Mesh == NULL )
3058 return aResult._retn();
3061 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3063 return aResult._retn();
3065 // find inverse elements
3066 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3067 TColStd_SequenceOfInteger IDs;
3068 while(eIt->more()) {
3069 const SMDS_MeshElement* elem = eIt->next();
3070 IDs.Append(elem->GetID());
3072 if(IDs.Length()>0) {
3073 aResult->length(IDs.Length());
3075 for(; i<=IDs.Length(); i++) {
3076 aResult[i-1] = IDs.Value(i);
3079 return aResult._retn();
3082 //=============================================================================
3084 * \brief Return position of a node on shape
3086 //=============================================================================
3088 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3090 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3091 aNodePosition->shapeID = 0;
3092 aNodePosition->shapeType = GEOM::SHAPE;
3094 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3095 if ( !mesh ) return aNodePosition;
3097 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3099 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3101 aNodePosition->shapeID = aNode->getshapeId();
3102 switch ( pos->GetTypeOfPosition() ) {
3104 aNodePosition->shapeType = GEOM::EDGE;
3105 aNodePosition->params.length(1);
3106 aNodePosition->params[0] =
3107 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3110 aNodePosition->shapeType = GEOM::FACE;
3111 aNodePosition->params.length(2);
3112 aNodePosition->params[0] =
3113 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3114 aNodePosition->params[1] =
3115 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3117 case SMDS_TOP_VERTEX:
3118 aNodePosition->shapeType = GEOM::VERTEX;
3120 case SMDS_TOP_3DSPACE:
3121 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3122 aNodePosition->shapeType = GEOM::SOLID;
3123 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3124 aNodePosition->shapeType = GEOM::SHELL;
3130 return aNodePosition;
3133 //=============================================================================
3135 * If given element is node returns IDs of shape from position
3136 * If there is not node for given ID - returns -1
3138 //=============================================================================
3140 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3142 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3143 if ( aSMESHDS_Mesh == NULL )
3147 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3149 return aNode->getshapeId();
3156 //=============================================================================
3158 * For given element returns ID of result shape after
3159 * ::FindShape() from SMESH_MeshEditor
3160 * If there is not element for given ID - returns -1
3162 //=============================================================================
3164 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3166 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3167 if ( aSMESHDS_Mesh == NULL )
3170 // try to find element
3171 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3175 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3176 ::SMESH_MeshEditor aMeshEditor(_impl);
3177 int index = aMeshEditor.FindShape( elem );
3185 //=============================================================================
3187 * Returns number of nodes for given element
3188 * If there is not element for given ID - returns -1
3190 //=============================================================================
3192 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3194 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3195 if ( aSMESHDS_Mesh == NULL ) return -1;
3196 // try to find element
3197 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3198 if(!elem) return -1;
3199 return elem->NbNodes();
3203 //=============================================================================
3205 * Returns ID of node by given index for given element
3206 * If there is not element for given ID - returns -1
3207 * If there is not node for given index - returns -2
3209 //=============================================================================
3211 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3213 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3214 if ( aSMESHDS_Mesh == NULL ) return -1;
3215 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3216 if(!elem) return -1;
3217 if( index>=elem->NbNodes() || index<0 ) return -1;
3218 return elem->GetNode(index)->GetID();
3221 //=============================================================================
3223 * Returns IDs of nodes of given element
3225 //=============================================================================
3227 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3229 SMESH::long_array_var aResult = new SMESH::long_array();
3230 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3232 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3234 aResult->length( elem->NbNodes() );
3235 for ( int i = 0; i < elem->NbNodes(); ++i )
3236 aResult[ i ] = elem->GetNode( i )->GetID();
3239 return aResult._retn();
3242 //=============================================================================
3244 * Returns true if given node is medium node
3245 * in given quadratic element
3247 //=============================================================================
3249 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3251 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3252 if ( aSMESHDS_Mesh == NULL ) return false;
3254 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3255 if(!aNode) return false;
3256 // try to find element
3257 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3258 if(!elem) return false;
3260 return elem->IsMediumNode(aNode);
3264 //=============================================================================
3266 * Returns true if given node is medium node
3267 * in one of quadratic elements
3269 //=============================================================================
3271 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3272 SMESH::ElementType theElemType)
3274 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3275 if ( aSMESHDS_Mesh == NULL ) return false;
3278 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3279 if(!aNode) return false;
3281 SMESH_MesherHelper aHelper( *(_impl) );
3283 SMDSAbs_ElementType aType;
3284 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3285 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3286 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3287 else aType = SMDSAbs_All;
3289 return aHelper.IsMedium(aNode,aType);
3293 //=============================================================================
3295 * Returns number of edges for given element
3297 //=============================================================================
3299 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3301 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3302 if ( aSMESHDS_Mesh == NULL ) return -1;
3303 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3304 if(!elem) return -1;
3305 return elem->NbEdges();
3309 //=============================================================================
3311 * Returns number of faces for given element
3313 //=============================================================================
3315 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3317 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3318 if ( aSMESHDS_Mesh == NULL ) return -1;
3319 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3320 if(!elem) return -1;
3321 return elem->NbFaces();
3324 //=======================================================================
3325 //function : GetElemFaceNodes
3326 //purpose : Returns nodes of given face (counted from zero) for given element.
3327 //=======================================================================
3329 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3330 CORBA::Short faceIndex)
3332 SMESH::long_array_var aResult = new SMESH::long_array();
3333 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3335 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3337 SMDS_VolumeTool vtool( elem );
3338 if ( faceIndex < vtool.NbFaces() )
3340 aResult->length( vtool.NbFaceNodes( faceIndex ));
3341 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3342 for ( int i = 0; i < aResult->length(); ++i )
3343 aResult[ i ] = nn[ i ]->GetID();
3347 return aResult._retn();
3350 //=======================================================================
3351 //function : FindElementByNodes
3352 //purpose : Returns an element based on all given nodes.
3353 //=======================================================================
3355 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3357 CORBA::Long elemID(0);
3358 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3360 vector< const SMDS_MeshNode * > nn( nodes.length() );
3361 for ( int i = 0; i < nodes.length(); ++i )
3362 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3365 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3366 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3367 _impl->NbFaces( ORDER_QUADRATIC ) ||
3368 _impl->NbVolumes( ORDER_QUADRATIC )))
3369 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3371 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3376 //=============================================================================
3378 * Returns true if given element is polygon
3380 //=============================================================================
3382 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3384 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3385 if ( aSMESHDS_Mesh == NULL ) return false;
3386 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3387 if(!elem) return false;
3388 return elem->IsPoly();
3392 //=============================================================================
3394 * Returns true if given element is quadratic
3396 //=============================================================================
3398 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3400 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3401 if ( aSMESHDS_Mesh == NULL ) return false;
3402 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3403 if(!elem) return false;
3404 return elem->IsQuadratic();
3408 //=============================================================================
3410 * Returns bary center for given element
3412 //=============================================================================
3414 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3416 SMESH::double_array_var aResult = new SMESH::double_array();
3417 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3418 if ( aSMESHDS_Mesh == NULL )
3419 return aResult._retn();
3421 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3423 return aResult._retn();
3425 if(elem->GetType()==SMDSAbs_Volume) {
3426 SMDS_VolumeTool aTool;
3427 if(aTool.Set(elem)) {
3429 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3434 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3436 double x=0., y=0., z=0.;
3437 for(; anIt->more(); ) {
3439 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3453 return aResult._retn();
3457 //=============================================================================
3459 * Create and publish group servants if any groups were imported or created anyhow
3461 //=============================================================================
3463 void SMESH_Mesh_i::CreateGroupServants()
3465 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3468 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3469 while ( groupIt->more() )
3471 ::SMESH_Group* group = groupIt->next();
3472 int anId = group->GetGroupDS()->GetID();
3474 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3475 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3477 addedIDs.insert( anId );
3479 SMESH_GroupBase_i* aGroupImpl;
3481 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3482 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3484 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3485 shape = groupOnGeom->GetShape();
3488 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3491 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3492 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3493 aGroupImpl->Register();
3495 SMESH::SMESH_GroupBase_var groupVar =
3496 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3497 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3499 // register CORBA object for persistence
3500 int nextId = _gen_i->RegisterObject( groupVar );
3501 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3503 // publishing the groups in the study
3504 if ( !aStudy->_is_nil() ) {
3505 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3506 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3509 if ( !addedIDs.empty() )
3512 set<int>::iterator id = addedIDs.begin();
3513 for ( ; id != addedIDs.end(); ++id )
3515 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3516 int i = std::distance( _mapGroups.begin(), it );
3517 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3522 //=============================================================================
3524 * \brief Return groups cantained in _mapGroups by their IDs
3526 //=============================================================================
3528 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3530 int nbGroups = groupIDs.size();
3531 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3532 aList->length( nbGroups );
3534 list<int>::const_iterator ids = groupIDs.begin();
3535 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3537 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3538 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3539 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3541 aList->length( nbGroups );
3542 return aList._retn();
3545 //=============================================================================
3547 * \brief Return information about imported file
3549 //=============================================================================
3551 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3553 SALOME_MED::MedFileInfo_var res( myFileInfo );
3554 if ( !res.operator->() ) {
3555 res = new SALOME_MED::MedFileInfo;
3557 res->fileSize = res->major = res->minor = res->release = -1;
3562 //=============================================================================
3564 * \brief Check and correct names of mesh groups
3566 //=============================================================================
3568 void SMESH_Mesh_i::checkGroupNames()
3570 int nbGrp = NbGroups();
3574 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3575 if ( aStudy->_is_nil() )
3576 return; // nothing to do
3578 SMESH::ListOfGroups* grpList = 0;
3579 // avoid dump of "GetGroups"
3581 // store python dump into a local variable inside local scope
3582 SMESH::TPythonDump pDump; // do not delete this line of code
3583 grpList = GetGroups();
3586 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3587 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3590 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3591 if ( aGrpSO->_is_nil() )
3593 // correct name of the mesh group if necessary
3594 const char* guiName = aGrpSO->GetName();
3595 if ( strcmp(guiName, aGrp->GetName()) )
3596 aGrp->SetName( guiName );
3600 //=============================================================================
3602 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3604 //=============================================================================
3605 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3607 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3608 CORBA::string_dup(theParameters));
3611 //=============================================================================
3613 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3615 //=============================================================================
3616 char* SMESH_Mesh_i::GetParameters()
3618 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3619 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3622 //=============================================================================
3624 * \brief Returns list of notebook variables used for last Mesh operation
3626 //=============================================================================
3627 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3629 SMESH::string_array_var aResult = new SMESH::string_array();
3630 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3632 char *aParameters = GetParameters();
3633 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3634 if(!aStudy->_is_nil()) {
3635 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3636 if(aSections->length() > 0) {
3637 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3638 aResult->length(aVars.length());
3639 for(int i = 0;i < aVars.length();i++)
3640 aResult[i] = CORBA::string_dup( aVars[i]);
3644 return aResult._retn();
3647 //=======================================================================
3648 //function : GetTypes
3649 //purpose : Returns types of elements it contains
3650 //=======================================================================
3652 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3654 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3658 if (_impl->NbEdges())
3659 types[nbTypes++] = SMESH::EDGE;
3660 if (_impl->NbFaces())
3661 types[nbTypes++] = SMESH::FACE;
3662 if (_impl->NbVolumes())
3663 types[nbTypes++] = SMESH::VOLUME;
3664 if (_impl->Nb0DElements())
3665 types[nbTypes++] = SMESH::ELEM0D;
3666 types->length( nbTypes );
3668 return types._retn();
3671 //=======================================================================
3672 //function : GetMesh
3673 //purpose : Returns self
3674 //=======================================================================
3676 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3678 return SMESH::SMESH_Mesh::_duplicate( _this() );
3681 //=============================================================================
3683 * \brief Returns statistic of mesh elements
3685 //=============================================================================
3686 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3688 SMESH::long_array_var aRes = new SMESH::long_array();
3689 aRes->length(SMESH::Entity_Last);
3690 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3692 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3694 return aRes._retn();
3695 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3696 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3697 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3698 return aRes._retn();
3701 //=============================================================================
3703 * \brief Collect statistic of mesh elements given by iterator
3705 //=============================================================================
3706 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3707 SMESH::long_array& theInfo)
3709 if (!theItr) return;
3710 while (theItr->more())
3711 theInfo[ theItr->next()->GetEntityType() ]++;
3714 //=============================================================================
3716 * \brief mapping of mesh dimension into shape type
3718 //=============================================================================
3719 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3721 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3723 case 0: aType = TopAbs_VERTEX; break;
3724 case 1: aType = TopAbs_EDGE; break;
3725 case 2: aType = TopAbs_FACE; break;
3727 default:aType = TopAbs_SOLID; break;
3732 //=============================================================================
3734 * \brief Internal structure used to find concurent submeshes
3736 * It represents a pair < submesh, concurent dimension >, where
3737 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3738 * with another submesh. In other words, it is dimension of a hypothesis assigned
3741 //=============================================================================
3747 int _dim; //!< a dimension the algo can build (concurrent dimension)
3748 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3749 TopTools_MapOfShape _shapeMap;
3750 SMESH_subMesh* _subMesh;
3751 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3754 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3756 const TopoDS_Shape& theShape)
3758 _subMesh = (SMESH_subMesh*)theSubMesh;
3759 SetShape( theDim, theShape );
3763 void SetShape(const int theDim,
3764 const TopoDS_Shape& theShape)
3767 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3768 if (_dim >= _ownDim)
3769 _shapeMap.Add( theShape );
3771 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3772 for( ; anExp.More(); anExp.Next() )
3773 _shapeMap.Add( anExp.Current() );
3777 //! Check sharing of sub shapes
3778 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3779 const TopTools_MapOfShape& theToFind,
3780 const TopAbs_ShapeEnum theType)
3782 bool isShared = false;
3783 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3784 for (; !isShared && anItr.More(); anItr.Next() ) {
3785 const TopoDS_Shape aSubSh = anItr.Key();
3786 // check for case when concurrent dimensions are same
3787 isShared = theToFind.Contains( aSubSh );
3788 // check for subshape with concurrent dimension
3789 TopExp_Explorer anExp( aSubSh, theType );
3790 for ( ; !isShared && anExp.More(); anExp.Next() )
3791 isShared = theToFind.Contains( anExp.Current() );
3796 //! check algorithms
3797 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3798 const SMESHDS_Hypothesis* theA2)
3800 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3801 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3802 return false; // one of the hypothesis is not algorithm
3803 // check algorithm names (should be equal)
3804 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3808 //! Check if subshape hypotheses are concurrent
3809 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3811 if ( _subMesh == theOther->_subMesh )
3812 return false; // same subshape - should not be
3814 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3815 // any of the two submeshes is not on COMPOUND shape )
3816 // -> no concurrency
3817 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3818 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3819 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3822 // bool checkSubShape = ( _dim >= theOther->_dim )
3823 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3824 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3825 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3826 if ( !checkSubShape )
3829 // check algorithms to be same
3830 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3831 return true; // different algorithms
3833 // check hypothesises for concurrence (skip first as algorithm)
3835 // pointers should be same, becase it is referenes from mesh hypothesis partition
3836 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3837 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3838 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3839 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3841 // the submeshes are concurrent if their algorithms has different parameters
3842 return nbSame != theOther->_hypothesises.size() - 1;
3845 }; // end of SMESH_DimHyp
3847 typedef list<SMESH_DimHyp*> TDimHypList;
3849 static void addDimHypInstance(const int theDim,
3850 const TopoDS_Shape& theShape,
3851 const SMESH_Algo* theAlgo,
3852 const SMESH_subMesh* theSubMesh,
3853 const list <const SMESHDS_Hypothesis*>& theHypList,
3854 TDimHypList* theDimHypListArr )
3856 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3857 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3858 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3859 listOfdimHyp.push_back( dimHyp );
3862 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3863 dimHyp->_hypothesises.push_front(theAlgo);
3864 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3865 for( ; hypIt != theHypList.end(); hypIt++ )
3866 dimHyp->_hypothesises.push_back( *hypIt );
3869 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3870 const TDimHypList& theListOfDimHyp,
3871 TListOfInt& theListOfConcurr )
3873 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3874 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3875 const SMESH_DimHyp* curDimHyp = *rIt;
3876 if ( curDimHyp == theDimHyp )
3877 break; // meet own dimHyp pointer in same dimension
3878 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3879 if ( find( theListOfConcurr.begin(),
3880 theListOfConcurr.end(),
3881 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3882 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3886 static void unionLists(TListOfInt& theListOfId,
3887 TListOfListOfInt& theListOfListOfId,
3890 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3891 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3893 continue; //skip already treated lists
3894 // check if other list has any same submesh object
3895 TListOfInt& otherListOfId = *it;
3896 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3897 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3900 // union two lists (from source into target)
3901 TListOfInt::iterator it2 = otherListOfId.begin();
3902 for ( ; it2 != otherListOfId.end(); it2++ ) {
3903 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3904 theListOfId.push_back(*it2);
3906 // clear source list
3907 otherListOfId.clear();
3911 //! free memory allocated for dimension-hypothesis objects
3912 static void removeDimHyps( TDimHypList* theArrOfList )
3914 for (int i = 0; i < 4; i++ ) {
3915 TDimHypList& listOfdimHyp = theArrOfList[i];
3916 TDimHypList::const_iterator it = listOfdimHyp.begin();
3917 for ( ; it != listOfdimHyp.end(); it++ )
3922 //=============================================================================
3924 * \brief Return submesh objects list in meshing order
3926 //=============================================================================
3928 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3930 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3932 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3934 return aResult._retn();
3936 ::SMESH_Mesh& mesh = GetImpl();
3937 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3938 if ( !anOrder.size() ) {
3940 // collect submeshes detecting concurrent algorithms and hypothesises
3941 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3943 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3944 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3945 ::SMESH_subMesh* sm = (*i_sm).second;
3947 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3949 // list of assigned hypothesises
3950 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3951 // Find out dimensions where the submesh can be concurrent.
3952 // We define the dimensions by algo of each of hypotheses in hypList
3953 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3954 for( ; hypIt != hypList.end(); hypIt++ ) {
3955 SMESH_Algo* anAlgo = 0;
3956 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3957 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3958 // hyp it-self is algo
3959 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3961 // try to find algorithm with help of subshapes
3962 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3963 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3964 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3967 continue; // no assigned algorithm to current submesh
3969 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3970 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3972 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3973 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3974 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3976 } // end iterations on submesh
3978 // iterate on created dimension-hypotheses and check for concurrents
3979 for ( int i = 0; i < 4; i++ ) {
3980 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3981 // check for concurrents in own and other dimensions (step-by-step)
3982 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3983 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3984 const SMESH_DimHyp* dimHyp = *dhIt;
3985 TListOfInt listOfConcurr;
3986 // looking for concurrents and collect into own list
3987 for ( int j = i; j < 4; j++ )
3988 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3989 // check if any concurrents found
3990 if ( listOfConcurr.size() > 0 ) {
3991 // add own submesh to list of concurrent
3992 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3993 anOrder.push_back( listOfConcurr );
3998 removeDimHyps(dimHypListArr);
4000 // now, minimise the number of concurrent groups
4001 // Here we assume that lists of submhes can has same submesh
4002 // in case of multi-dimension algorithms, as result
4003 // list with common submesh have to be union into one list
4005 TListOfListOfInt::iterator listIt = anOrder.begin();
4006 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4007 unionLists( *listIt, anOrder, listIndx + 1 );
4009 // convert submesh ids into interface instances
4010 // and dump command into python
4011 convertMeshOrder( anOrder, aResult, true );
4013 return aResult._retn();
4016 //=============================================================================
4018 * \brief find common submeshes with given submesh
4019 * \param theSubMeshList list of already collected submesh to check
4020 * \param theSubMesh given submesh to intersect with other
4021 * \param theCommonSubMeshes collected common submeshes
4023 //=============================================================================
4025 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4026 const SMESH_subMesh* theSubMesh,
4027 set<const SMESH_subMesh*>& theCommon )
4031 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4032 for ( ; it != theSubMeshList.end(); it++ )
4033 theSubMesh->FindIntersection( *it, theCommon );
4034 theSubMeshList.push_back( theSubMesh );
4035 //theCommon.insert( theSubMesh );
4038 //=============================================================================
4040 * \brief Set submesh object order
4041 * \param theSubMeshArray submesh array order
4043 //=============================================================================
4045 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4048 ::SMESH_Mesh& mesh = GetImpl();
4050 TPythonDump aPythonDump; // prevent dump of called methods
4051 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4053 TListOfListOfInt subMeshOrder;
4054 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4056 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4057 TListOfInt subMeshIds;
4058 aPythonDump << "[ ";
4059 // Collect subMeshes which should be clear
4060 // do it list-by-list, because modification of submesh order
4061 // take effect between concurrent submeshes only
4062 set<const SMESH_subMesh*> subMeshToClear;
4063 list<const SMESH_subMesh*> subMeshList;
4064 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4066 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4068 aPythonDump << ", ";
4069 aPythonDump << subMesh;
4070 subMeshIds.push_back( subMesh->GetId() );
4071 // detect common parts of submeshes
4072 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4073 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4075 aPythonDump << " ]";
4076 subMeshOrder.push_back( subMeshIds );
4078 // clear collected submeshes
4079 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4080 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4081 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4083 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4084 // ClearSubMesh( *clrIt );
4087 aPythonDump << " ])";
4089 mesh.SetMeshOrder( subMeshOrder );
4095 //=============================================================================
4097 * \brief Convert submesh ids into submesh interfaces
4099 //=============================================================================
4101 void SMESH_Mesh_i::convertMeshOrder
4102 (const TListOfListOfInt& theIdsOrder,
4103 SMESH::submesh_array_array& theResOrder,
4104 const bool theIsDump)
4106 int nbSet = theIdsOrder.size();
4107 TPythonDump aPythonDump; // prevent dump of called methods
4109 aPythonDump << "[ ";
4110 theResOrder.length(nbSet);
4111 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4113 for( ; it != theIdsOrder.end(); it++ ) {
4114 // translate submesh identificators into submesh objects
4115 // takeing into account real number of concurrent lists
4116 const TListOfInt& aSubOrder = (*it);
4117 if (!aSubOrder.size())
4120 aPythonDump << "[ ";
4121 // convert shape indeces into interfaces
4122 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4123 aResSubSet->length(aSubOrder.size());
4124 TListOfInt::const_iterator subIt = aSubOrder.begin();
4125 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4126 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4128 SMESH::SMESH_subMesh_var subMesh =
4129 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4132 aPythonDump << ", ";
4133 aPythonDump << subMesh;
4135 aResSubSet[ j++ ] = subMesh;
4138 aPythonDump << " ]";
4139 theResOrder[ listIndx++ ] = aResSubSet;
4141 // correct number of lists
4142 theResOrder.length( listIndx );
4145 // finilise python dump
4146 aPythonDump << " ]";
4147 aPythonDump << " = " << _this() << ".GetMeshOrder()";