1 // Copyright (C) 2007-2008 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 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
23 // File : SMESH_Mesh_i.cxx
24 // Author : Paul RASCLE, EDF
27 #include "SMESH_Mesh_i.hxx"
29 #include "SMESH_Filter_i.hxx"
30 #include "SMESH_Gen_i.hxx"
31 #include "SMESH_Group_i.hxx"
32 #include "SMESH_MEDMesh_i.hxx"
33 #include "SMESH_MeshEditor_i.hxx"
34 #include "SMESH_PythonDump.hxx"
35 #include "SMESH_subMesh_i.hxx"
37 #include "DriverMED_R_SMESHDS_Mesh.h"
38 #include "DriverMED_W_SMESHDS_Mesh.h"
39 #include "SMDS_VolumeTool.hxx"
40 #include "SMDS_ElemIterator.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_GroupOnGeom.hxx"
44 #include "SMESH_Group.hxx"
45 #include "SMESH_MeshEditor.hxx"
46 #include "SMESH_MesherHelper.hxx"
47 #include "SMDS_EdgePosition.hxx"
48 #include "SMDS_FacePosition.hxx"
51 #include "SALOME_NamingService.hxx"
52 #include "Utils_CorbaException.hxx"
53 #include "Utils_ExceptHandlers.hxx"
54 #include "Utils_SINGLETON.hxx"
55 #include "utilities.h"
56 #include "GEOMImpl_Types.hxx"
59 #include <BRep_Builder.hxx>
60 #include <OSD_Directory.hxx>
61 #include <OSD_File.hxx>
62 #include <OSD_Path.hxx>
63 #include <OSD_Protection.hxx>
64 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
65 #include <TColStd_MapOfInteger.hxx>
66 #include <TColStd_SequenceOfInteger.hxx>
67 #include <TCollection_AsciiString.hxx>
69 #include <TopExp_Explorer.hxx>
70 #include <TopoDS_Compound.hxx>
71 #include <TopTools_MapOfShape.hxx>
72 #include <TopTools_MapIteratorOfMapOfShape.hxx>
82 static int MYDEBUG = 0;
84 static int MYDEBUG = 0;
88 using SMESH::TPythonDump;
90 int SMESH_Mesh_i::myIdGenerator = 0;
94 //=============================================================================
98 //=============================================================================
100 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
102 CORBA::Long studyId )
103 : SALOME::GenericObj_i( thePOA )
105 MESSAGE("SMESH_Mesh_i");
108 _id = myIdGenerator++;
112 //=============================================================================
116 //=============================================================================
118 SMESH_Mesh_i::~SMESH_Mesh_i()
120 INFOS("~SMESH_Mesh_i");
121 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
122 for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
123 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
125 // this method is colled from destructor of group (PAL6331)
126 //_impl->RemoveGroup( aGroup->GetLocalID() );
135 //=============================================================================
139 * Associates <this> mesh with <theShape> and puts a reference
140 * to <theShape> into the current study;
141 * the previous shape is substituted by the new one.
143 //=============================================================================
145 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
146 throw (SALOME::SALOME_Exception)
148 Unexpect aCatch(SALOME_SalomeException);
150 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
152 catch(SALOME_Exception & S_ex) {
153 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
155 // to track changes of GEOM groups
156 addGeomGroupData( theShapeObject, _this() );
159 //================================================================================
161 * \brief return true if mesh has a shape to build a shape on
163 //================================================================================
165 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
166 throw (SALOME::SALOME_Exception)
168 Unexpect aCatch(SALOME_SalomeException);
171 res = _impl->HasShapeToMesh();
173 catch(SALOME_Exception & S_ex) {
174 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
179 //=======================================================================
180 //function : GetShapeToMesh
182 //=======================================================================
184 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
185 throw (SALOME::SALOME_Exception)
187 Unexpect aCatch(SALOME_SalomeException);
188 GEOM::GEOM_Object_var aShapeObj;
190 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
192 aShapeObj = _gen_i->ShapeToGeomObject( S );
194 catch(SALOME_Exception & S_ex) {
195 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
197 return aShapeObj._retn();
200 //================================================================================
202 * \brief Remove all nodes and elements
204 //================================================================================
206 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 CheckGeomGroupModif(); // issue 20145
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
216 TPythonDump() << _this() << ".Clear()";
219 //================================================================================
221 * \brief Remove all nodes and elements for indicated shape
223 //================================================================================
225 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
226 throw (SALOME::SALOME_Exception)
228 Unexpect aCatch(SALOME_SalomeException);
230 _impl->ClearSubMesh( ShapeID );
232 catch(SALOME_Exception & S_ex) {
233 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
237 //=============================================================================
241 //=============================================================================
243 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
245 SMESH::DriverMED_ReadStatus res;
248 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
249 res = SMESH::DRS_OK; break;
250 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
251 res = SMESH::DRS_EMPTY; break;
252 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
253 res = SMESH::DRS_WARN_RENUMBER; break;
254 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
255 res = SMESH::DRS_WARN_SKIP_ELEM; break;
256 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
258 res = SMESH::DRS_FAIL; break;
263 //=============================================================================
267 * Imports mesh data from MED file
269 //=============================================================================
271 SMESH::DriverMED_ReadStatus
272 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
273 throw ( SALOME::SALOME_Exception )
275 Unexpect aCatch(SALOME_SalomeException);
278 status = _impl->MEDToMesh( theFileName, theMeshName );
280 catch( SALOME_Exception& S_ex ) {
281 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
284 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
287 CreateGroupServants();
289 int major, minor, release;
290 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
291 major = minor = release = -1;
292 myFileInfo = new SALOME_MED::MedFileInfo();
293 myFileInfo->fileName = theFileName;
294 myFileInfo->fileSize = 0;
297 if ( ::_stati64( theFileName, &d ) != -1 )
300 if ( ::stat64( theFileName, &d ) != -1 )
302 myFileInfo->fileSize = d.st_size;
303 myFileInfo->major = major;
304 myFileInfo->minor = minor;
305 myFileInfo->release = release;
307 return ConvertDriverMEDReadStatus(status);
310 //================================================================================
312 * \brief Return string representation of a MED file version comprising nbDigits
314 //================================================================================
316 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
318 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
320 return CORBA::string_dup( ver.c_str() );
323 //=============================================================================
327 * Imports mesh data from MED file
329 //=============================================================================
331 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
332 throw ( SALOME::SALOME_Exception )
334 // Read mesh with name = <theMeshName> into SMESH_Mesh
335 _impl->UNVToMesh( theFileName );
337 CreateGroupServants();
342 //=============================================================================
346 * Imports mesh data from STL file
348 //=============================================================================
349 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
350 throw ( SALOME::SALOME_Exception )
352 // Read mesh with name = <theMeshName> into SMESH_Mesh
353 _impl->STLToMesh( theFileName );
358 //=============================================================================
362 * Imports mesh data from MED file
364 //=============================================================================
366 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
368 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
369 // int status = _impl->MEDToMesh( theFileName, theMeshName );
370 // CreateGroupServants();
375 //=============================================================================
379 //=============================================================================
381 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
383 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
384 (SMESH_Hypothesis::Hypothesis_Status theStatus)
387 RETURNCASE( HYP_OK );
388 RETURNCASE( HYP_MISSING );
389 RETURNCASE( HYP_CONCURENT );
390 RETURNCASE( HYP_BAD_PARAMETER );
391 RETURNCASE( HYP_HIDDEN_ALGO );
392 RETURNCASE( HYP_HIDING_ALGO );
393 RETURNCASE( HYP_UNKNOWN_FATAL );
394 RETURNCASE( HYP_INCOMPATIBLE );
395 RETURNCASE( HYP_NOTCONFORM );
396 RETURNCASE( HYP_ALREADY_EXIST );
397 RETURNCASE( HYP_BAD_DIM );
398 RETURNCASE( HYP_BAD_SUBSHAPE );
399 RETURNCASE( HYP_BAD_GEOMETRY );
400 RETURNCASE( HYP_NEED_SHAPE );
403 return SMESH::HYP_UNKNOWN_FATAL;
406 //=============================================================================
410 * calls internal addHypothesis() and then adds a reference to <anHyp> under
411 * the SObject actually having a reference to <aSubShape>.
412 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
414 //=============================================================================
416 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
417 SMESH::SMESH_Hypothesis_ptr anHyp)
418 throw(SALOME::SALOME_Exception)
420 Unexpect aCatch(SALOME_SalomeException);
421 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
423 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
424 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
425 aSubShapeObject, anHyp );
427 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
429 // Update Python script
430 if(_impl->HasShapeToMesh()) {
431 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
432 << aSubShapeObject << ", " << anHyp << " )";
435 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
438 return ConvertHypothesisStatus(status);
441 //=============================================================================
445 //=============================================================================
447 SMESH_Hypothesis::Hypothesis_Status
448 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
449 SMESH::SMESH_Hypothesis_ptr anHyp)
451 if(MYDEBUG) MESSAGE("addHypothesis");
453 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
454 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
457 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
458 if (CORBA::is_nil(myHyp))
459 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
462 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
465 TopoDS_Shape myLocSubShape;
466 //use PseudoShape in case if mesh has no shape
468 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
470 myLocSubShape = _impl->GetShapeToMesh();
472 int hypId = myHyp->GetId();
473 status = _impl->AddHypothesis(myLocSubShape, hypId);
474 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
475 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
476 // assure there is a corresponding submesh
477 if ( !_impl->IsMainShape( myLocSubShape )) {
478 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
479 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
480 createSubMesh( aSubShapeObject );
484 catch(SALOME_Exception & S_ex)
486 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
491 //=============================================================================
495 //=============================================================================
497 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
498 SMESH::SMESH_Hypothesis_ptr anHyp)
499 throw(SALOME::SALOME_Exception)
501 Unexpect aCatch(SALOME_SalomeException);
502 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
504 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
505 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
506 aSubShapeObject, anHyp );
508 // Update Python script
509 // Update Python script
510 if(_impl->HasShapeToMesh()) {
511 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
512 << aSubShapeObject << ", " << anHyp << " )";
515 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
519 return ConvertHypothesisStatus(status);
522 //=============================================================================
526 //=============================================================================
528 SMESH_Hypothesis::Hypothesis_Status
529 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
530 SMESH::SMESH_Hypothesis_ptr anHyp)
532 if(MYDEBUG) MESSAGE("removeHypothesis()");
533 // **** proposer liste de subShape (selection multiple)
535 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
536 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
538 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
539 if (CORBA::is_nil(myHyp))
540 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
542 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
545 TopoDS_Shape myLocSubShape;
546 //use PseudoShape in case if mesh has no shape
548 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
550 myLocSubShape = _impl->GetShapeToMesh();
552 int hypId = myHyp->GetId();
553 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
554 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
555 // _mapHypo.erase( hypId );
557 catch(SALOME_Exception & S_ex)
559 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
564 //=============================================================================
568 //=============================================================================
570 SMESH::ListOfHypothesis *
571 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
572 throw(SALOME::SALOME_Exception)
574 Unexpect aCatch(SALOME_SalomeException);
575 if (MYDEBUG) MESSAGE("GetHypothesisList");
576 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
577 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
579 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
582 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
583 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
584 myLocSubShape = _impl->GetShapeToMesh();
585 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
586 int i = 0, n = aLocalList.size();
589 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
590 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
591 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
592 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
597 catch(SALOME_Exception & S_ex) {
598 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
601 return aList._retn();
604 //=============================================================================
608 //=============================================================================
609 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
610 const char* theName )
611 throw(SALOME::SALOME_Exception)
613 Unexpect aCatch(SALOME_SalomeException);
614 MESSAGE("SMESH_Mesh_i::GetSubMesh");
615 if (CORBA::is_nil(aSubShapeObject))
616 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
619 SMESH::SMESH_subMesh_var subMesh;
620 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
622 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
624 //Get or Create the SMESH_subMesh object implementation
626 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
627 subMesh = getSubMesh( subMeshId );
629 // create a new subMesh object servant if there is none for the shape
630 if ( subMesh->_is_nil() )
631 subMesh = createSubMesh( aSubShapeObject );
632 if ( _gen_i->CanPublishInStudy( subMesh )) {
633 SALOMEDS::SObject_var aSO =
634 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
635 subMesh, aSubShapeObject, theName );
636 if ( !aSO->_is_nil()) {
637 // Update Python script
638 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
639 << aSubShapeObject << ", '" << theName << "' )";
643 catch(SALOME_Exception & S_ex) {
644 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
646 return subMesh._retn();
649 //=============================================================================
653 //=============================================================================
655 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
656 throw (SALOME::SALOME_Exception)
658 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
659 if ( theSubMesh->_is_nil() )
662 GEOM::GEOM_Object_var aSubShapeObject;
663 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
664 if ( !aStudy->_is_nil() ) {
665 // Remove submesh's SObject
666 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
667 if ( !anSO->_is_nil() ) {
668 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
669 SALOMEDS::SObject_var anObj, aRef;
670 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
671 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
673 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
674 // aSubShapeObject = theSubMesh->GetSubShape();
676 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
678 // Update Python script
679 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
683 removeSubMesh( theSubMesh, aSubShapeObject.in() );
686 //=============================================================================
690 //=============================================================================
691 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
692 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
694 switch (theElemType) {
699 CASE2STRING( VOLUME );
705 //=============================================================================
709 //=============================================================================
711 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
712 const char* theName )
713 throw(SALOME::SALOME_Exception)
715 Unexpect aCatch(SALOME_SalomeException);
716 SMESH::SMESH_Group_var aNewGroup =
717 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
719 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
720 SALOMEDS::SObject_var aSO =
721 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
722 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
723 if ( !aSO->_is_nil()) {
724 // Update Python script
725 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
726 << ElementTypeString(theElemType) << ", '" << theName << "' )";
729 return aNewGroup._retn();
733 //=============================================================================
737 //=============================================================================
738 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
740 GEOM::GEOM_Object_ptr theGeomObj)
741 throw(SALOME::SALOME_Exception)
743 Unexpect aCatch(SALOME_SalomeException);
744 SMESH::SMESH_GroupOnGeom_var aNewGroup;
746 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
747 if ( !aShape.IsNull() )
749 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
750 ( createGroup( theElemType, theName, aShape ));
752 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
753 SALOMEDS::SObject_var aSO =
754 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
755 aNewGroup, theGeomObj, theName);
756 if ( !aSO->_is_nil()) {
757 // Update Python script
758 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
759 << ElementTypeString(theElemType) << ", '" << theName << "', "
760 << theGeomObj << " )";
765 return aNewGroup._retn();
768 //=============================================================================
772 //=============================================================================
774 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
775 throw (SALOME::SALOME_Exception)
777 if ( theGroup->_is_nil() )
780 SMESH_GroupBase_i* aGroup =
781 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
785 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
786 if ( !aStudy->_is_nil() ) {
787 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
789 if ( !aGroupSO->_is_nil() ) {
790 // Update Python script
791 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
793 // Remove group's SObject
794 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
798 // Remove the group from SMESH data structures
799 removeGroup( aGroup->GetLocalID() );
802 //=============================================================================
803 /*! RemoveGroupWithContents
804 * Remove group with its contents
806 //=============================================================================
807 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
808 throw (SALOME::SALOME_Exception)
810 if ( theGroup->_is_nil() )
813 SMESH_GroupBase_i* aGroup =
814 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
818 SMESH::long_array_var anIds = aGroup->GetListOfID();
819 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
821 // Update Python script
822 TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
825 if ( aGroup->GetType() == SMESH::NODE )
826 aMeshEditor->RemoveNodes( anIds );
828 aMeshEditor->RemoveElements( anIds );
831 RemoveGroup( theGroup );
833 // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
834 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
835 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
839 //================================================================================
841 * \brief Get the list of groups existing in the mesh
842 * \retval SMESH::ListOfGroups * - list of groups
844 //================================================================================
846 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
848 Unexpect aCatch(SALOME_SalomeException);
849 if (MYDEBUG) MESSAGE("GetGroups");
851 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
854 TPythonDump aPythonDump;
855 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
859 aList->length( _mapGroups.size() );
861 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
862 for ( ; it != _mapGroups.end(); it++ ) {
863 if ( CORBA::is_nil( it->second )) continue;
864 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
866 if (i > 1) aPythonDump << ", ";
867 aPythonDump << it->second;
871 catch(SALOME_Exception & S_ex) {
872 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
875 // Update Python script
876 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
877 aPythonDump << " ] = " << _this() << ".GetGroups()";
879 return aList._retn();
881 //=============================================================================
883 * Get number of groups existing in the mesh
885 //=============================================================================
887 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
889 Unexpect aCatch(SALOME_SalomeException);
890 return _mapGroups.size();
893 //=============================================================================
895 * New group is created. All mesh elements that are
896 * present in initial groups are added to the new one
898 //=============================================================================
899 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
900 SMESH::SMESH_GroupBase_ptr theGroup2,
901 const char* theName )
902 throw (SALOME::SALOME_Exception)
906 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
907 theGroup1->GetType() != theGroup2->GetType() )
908 return SMESH::SMESH_Group::_nil();
911 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
912 if ( aResGrp->_is_nil() )
913 return SMESH::SMESH_Group::_nil();
915 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
916 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
918 TColStd_MapOfInteger aResMap;
920 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
921 aResMap.Add( anIds1[ i1 ] );
923 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
924 aResMap.Add( anIds2[ i2 ] );
926 SMESH::long_array_var aResIds = new SMESH::long_array;
927 aResIds->length( aResMap.Extent() );
930 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
931 for( ; anIter.More(); anIter.Next() )
932 aResIds[ resI++ ] = anIter.Key();
934 aResGrp->Add( aResIds );
936 // Clear python lines, created by CreateGroup() and Add()
937 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
938 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
939 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
941 // Update Python script
942 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
943 << theGroup1 << ", " << theGroup2 << ", '"
946 return aResGrp._retn();
950 return SMESH::SMESH_Group::_nil();
954 //=============================================================================
956 \brief Union list of groups. New group is created. All mesh elements that are
957 present in initial groups are added to the new one.
958 \param theGroups list of groups
959 \param theName name of group to be created
960 \return pointer on the group
962 //=============================================================================
963 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
964 const char* theName )
965 throw (SALOME::SALOME_Exception)
968 return SMESH::SMESH_Group::_nil();
972 NCollection_Map< int > anIds;
973 SMESH::ElementType aType = SMESH::ALL;
974 for ( int g = 0, n = theGroups.length(); g < n; g++ )
976 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
977 if ( CORBA::is_nil( aGrp ) )
981 SMESH::ElementType aCurrType = aGrp->GetType();
982 if ( aType == SMESH::ALL )
986 if ( aType != aCurrType )
987 return SMESH::SMESH_Group::_nil();
991 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
992 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
994 int aCurrId = aCurrIds[ i ];
995 anIds.Add( aCurrId );
1000 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1001 if ( aResGrp->_is_nil() )
1002 return SMESH::SMESH_Group::_nil();
1004 // Create array of identifiers
1005 SMESH::long_array_var aResIds = new SMESH::long_array;
1006 aResIds->length( anIds.Extent() );
1008 NCollection_Map< int >::Iterator anIter( anIds );
1009 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1011 aResIds[ i ] = anIter.Value();
1013 aResGrp->Add( aResIds );
1015 // Clear python lines, created by CreateGroup() and Add()
1016 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1017 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1018 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1020 // Update Python script
1022 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1023 << &theGroups << ", '" << theName << "' )";
1025 return aResGrp._retn();
1029 return SMESH::SMESH_Group::_nil();
1033 //=============================================================================
1035 * New group is created. All mesh elements that are
1036 * present in both initial groups are added to the new one.
1038 //=============================================================================
1039 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1040 SMESH::SMESH_GroupBase_ptr theGroup2,
1041 const char* theName )
1042 throw (SALOME::SALOME_Exception)
1044 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1045 theGroup1->GetType() != theGroup2->GetType() )
1046 return SMESH::SMESH_Group::_nil();
1048 // Create Intersection
1049 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1050 if ( aResGrp->_is_nil() )
1053 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1054 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1056 TColStd_MapOfInteger aMap1;
1058 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1059 aMap1.Add( anIds1[ i1 ] );
1061 TColStd_SequenceOfInteger aSeq;
1063 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1064 if ( aMap1.Contains( anIds2[ i2 ] ) )
1065 aSeq.Append( anIds2[ i2 ] );
1067 SMESH::long_array_var aResIds = new SMESH::long_array;
1068 aResIds->length( aSeq.Length() );
1070 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1071 aResIds[ resI ] = aSeq( resI + 1 );
1073 aResGrp->Add( aResIds );
1075 // Clear python lines, created by CreateGroup() and Add()
1076 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1077 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1078 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1080 // Update Python script
1081 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1082 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1084 return aResGrp._retn();
1087 //=============================================================================
1089 \brief Intersect list of groups. New group is created. All mesh elements that
1090 are present in all initial groups simultaneously are added to the new one.
1091 \param theGroups list of groups
1092 \param theName name of group to be created
1093 \return pointer on the group
1095 //=============================================================================
1096 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1097 const SMESH::ListOfGroups& theGroups, const char* theName )
1098 throw (SALOME::SALOME_Exception)
1101 return SMESH::SMESH_Group::_nil();
1105 NCollection_DataMap< int, int > anIdToCount;
1106 SMESH::ElementType aType = SMESH::ALL;
1107 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1109 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1110 if ( CORBA::is_nil( aGrp ) )
1114 SMESH::ElementType aCurrType = aGrp->GetType();
1115 if ( aType == SMESH::ALL )
1119 if ( aType != aCurrType )
1120 return SMESH::SMESH_Group::_nil();
1123 // calculates number of occurance ids in groups
1124 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1125 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1127 int aCurrId = aCurrIds[ i ];
1128 if ( !anIdToCount.IsBound( aCurrId ) )
1129 anIdToCount.Bind( aCurrId, 1 );
1131 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1135 // create map of ids
1136 int nbGrp = theGroups.length();
1137 NCollection_Map< int > anIds;
1138 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1139 for ( ; anIter.More(); anIter.Next() )
1141 int aCurrId = anIter.Key();
1142 int aCurrNb = anIter.Value();
1143 if ( aCurrNb == nbGrp )
1144 anIds.Add( aCurrId );
1148 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1149 if ( aResGrp->_is_nil() )
1150 return SMESH::SMESH_Group::_nil();
1152 // Create array of identifiers
1153 SMESH::long_array_var aResIds = new SMESH::long_array;
1154 aResIds->length( anIds.Extent() );
1156 NCollection_Map< int >::Iterator aListIter( anIds );
1157 for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1159 aResIds[ i ] = aListIter.Value();
1161 aResGrp->Add( aResIds );
1163 // Clear python lines, created by CreateGroup() and Add()
1164 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1165 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1166 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1168 // Update Python script
1170 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1171 << &theGroups << ", '" << theName << "' )";
1173 return aResGrp._retn();
1177 return SMESH::SMESH_Group::_nil();
1181 //=============================================================================
1183 * New group is created. All mesh elements that are present in
1184 * main group but do not present in tool group are added to the new one
1186 //=============================================================================
1187 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1188 SMESH::SMESH_GroupBase_ptr theGroup2,
1189 const char* theName )
1190 throw (SALOME::SALOME_Exception)
1192 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1193 theGroup1->GetType() != theGroup2->GetType() )
1194 return SMESH::SMESH_Group::_nil();
1197 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1198 if ( aResGrp->_is_nil() )
1201 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1202 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1204 TColStd_MapOfInteger aMap2;
1206 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1207 aMap2.Add( anIds2[ i2 ] );
1209 TColStd_SequenceOfInteger aSeq;
1210 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1211 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1212 aSeq.Append( anIds1[ i1 ] );
1214 SMESH::long_array_var aResIds = new SMESH::long_array;
1215 aResIds->length( aSeq.Length() );
1217 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1218 aResIds[ resI ] = aSeq( resI + 1 );
1220 aResGrp->Add( aResIds );
1222 // Clear python lines, created by CreateGroup() and Add()
1223 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1224 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1225 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1227 // Update Python script
1228 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1229 << theGroup1 << ", " << theGroup2 << ", '"
1230 << theName << "' )";
1232 return aResGrp._retn();
1235 //=============================================================================
1237 \brief Cut lists of groups. New group is created. All mesh elements that are
1238 present in main groups but do not present in tool groups are added to the new one
1239 \param theMainGroups list of main groups
1240 \param theToolGroups list of tool groups
1241 \param theName name of group to be created
1242 \return pointer on the group
1244 //=============================================================================
1245 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1246 const SMESH::ListOfGroups& theMainGroups,
1247 const SMESH::ListOfGroups& theToolGroups,
1248 const char* theName )
1249 throw (SALOME::SALOME_Exception)
1252 return SMESH::SMESH_Group::_nil();
1256 NCollection_Map< int > aToolIds;
1257 SMESH::ElementType aType = SMESH::ALL;
1259 // iterate through tool groups
1260 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1262 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1263 if ( CORBA::is_nil( aGrp ) )
1267 SMESH::ElementType aCurrType = aGrp->GetType();
1268 if ( aType == SMESH::ALL )
1272 if ( aType != aCurrType )
1273 return SMESH::SMESH_Group::_nil();
1277 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1278 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1280 int aCurrId = aCurrIds[ i ];
1281 aToolIds.Add( aCurrId );
1285 NCollection_Map< int > anIds; // result
1287 // Iterate through main group
1288 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1290 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1291 if ( CORBA::is_nil( aGrp ) )
1295 SMESH::ElementType aCurrType = aGrp->GetType();
1296 if ( aType == SMESH::ALL )
1300 if ( aType != aCurrType )
1301 return SMESH::SMESH_Group::_nil();
1305 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1306 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1308 int aCurrId = aCurrIds[ i ];
1309 if ( !aToolIds.Contains( aCurrId ) )
1310 anIds.Add( aCurrId );
1315 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1316 if ( aResGrp->_is_nil() )
1317 return SMESH::SMESH_Group::_nil();
1319 // Create array of identifiers
1320 SMESH::long_array_var aResIds = new SMESH::long_array;
1321 aResIds->length( anIds.Extent() );
1323 NCollection_Map< int >::Iterator anIter( anIds );
1324 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1326 aResIds[ i ] = anIter.Value();
1328 aResGrp->Add( aResIds );
1330 // Clear python lines, created by CreateGroup() and Add()
1331 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1332 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1333 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1335 // Update Python script
1337 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1338 << &theMainGroups << ", " << &theToolGroups << ", '"
1339 << theName << "' )";
1341 return aResGrp._retn();
1345 return SMESH::SMESH_Group::_nil();
1349 //=============================================================================
1351 \brief Create groups of entities from existing groups of superior dimensions
1353 1) extract all nodes from each group,
1354 2) combine all elements of specified dimension laying on these nodes.
1355 \param theGroups list of source groups
1356 \param theElemType dimension of elements
1357 \param theName name of new group
1358 \return pointer on new group
1360 //=============================================================================
1361 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1362 const SMESH::ListOfGroups& theGroups,
1363 SMESH::ElementType theElemType,
1364 const char* theName )
1365 throw (SALOME::SALOME_Exception)
1367 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1369 if ( !theName || !aMeshDS )
1370 return SMESH::SMESH_Group::_nil();
1372 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1376 // Create map of nodes from all groups
1378 NCollection_Map< int > aNodeMap;
1380 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1382 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1383 if ( CORBA::is_nil( aGrp ) )
1386 SMESH::ElementType aType = aGrp->GetType();
1387 if ( aType == SMESH::ALL )
1389 else if ( aType == SMESH::NODE )
1391 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1392 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1394 int aCurrId = aCurrIds[ i ];
1395 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1397 aNodeMap.Add( aNode->GetID() );
1402 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1403 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1405 int aCurrId = aCurrIds[ i ];
1406 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1409 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1410 while( aNodeIter->more() )
1412 const SMDS_MeshNode* aNode =
1413 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1415 aNodeMap.Add( aNode->GetID() );
1421 // Get result identifiers
1423 NCollection_Map< int > aResultIds;
1424 if ( theElemType == SMESH::NODE )
1426 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1427 for ( ; aNodeIter.More(); aNodeIter.Next() )
1428 aResultIds.Add( aNodeIter.Value() );
1432 // Create list of elements of given dimension constructed on the nodes
1433 NCollection_Map< int > anElemList;
1434 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1435 for ( ; aNodeIter.More(); aNodeIter.Next() )
1437 const SMDS_MeshElement* aNode =
1438 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1442 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1443 while( anElemIter->more() )
1445 const SMDS_MeshElement* anElem =
1446 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1447 if ( anElem && anElem->GetType() == anElemType )
1448 anElemList.Add( anElem->GetID() );
1452 // check whether all nodes of elements are present in nodes map
1453 NCollection_Map< int >::Iterator anIter( anElemList );
1454 for ( ; anIter.More(); anIter.Next() )
1456 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1461 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1462 while( aNodeIter->more() )
1464 const SMDS_MeshNode* aNode =
1465 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1466 if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1473 aResultIds.Add( anElem->GetID() );
1479 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1480 if ( aResGrp->_is_nil() )
1481 return SMESH::SMESH_Group::_nil();
1483 // Create array of identifiers
1484 SMESH::long_array_var aResIds = new SMESH::long_array;
1485 aResIds->length( aResultIds.Extent() );
1487 NCollection_Map< int >::Iterator aResIter( aResultIds );
1488 for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1489 aResIds[ i ] = aResIter.Value();
1490 aResGrp->Add( aResIds );
1492 // Remove strings corresponding to group creation
1493 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1494 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1495 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1497 // Update Python script
1499 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1500 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1502 return aResGrp._retn();
1506 return SMESH::SMESH_Group::_nil();
1510 //================================================================================
1512 * \brief Remember GEOM group data
1514 //================================================================================
1516 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1517 CORBA::Object_ptr theSmeshObj)
1519 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1522 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1523 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1524 if ( groupSO->_is_nil() )
1527 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1528 GEOM::GEOM_IGroupOperations_var groupOp =
1529 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1530 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1533 _geomGroupData.push_back( TGeomGroupData() );
1534 TGeomGroupData & groupData = _geomGroupData.back();
1536 CORBA::String_var entry = groupSO->GetID();
1537 groupData._groupEntry = entry.in();
1539 for ( int i = 0; i < ids->length(); ++i )
1540 groupData._indices.insert( ids[i] );
1542 groupData._smeshObject = theSmeshObj;
1545 //================================================================================
1547 * Remove GEOM group data relating to removed smesh object
1549 //================================================================================
1551 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1553 list<TGeomGroupData>::iterator
1554 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1555 for ( ; data != dataEnd; ++data ) {
1556 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1557 _geomGroupData.erase( data );
1563 //================================================================================
1565 * \brief Return new group contents if it has been changed and update group data
1567 //================================================================================
1569 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1571 TopoDS_Shape newShape;
1574 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1575 if ( study->_is_nil() ) return newShape; // means "not changed"
1576 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1577 if ( !groupSO->_is_nil() )
1579 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1580 if ( CORBA::is_nil( groupObj )) return newShape;
1581 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1583 // get indices of group items
1584 set<int> curIndices;
1585 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1586 GEOM::GEOM_IGroupOperations_var groupOp =
1587 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1588 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1589 for ( int i = 0; i < ids->length(); ++i )
1590 curIndices.insert( ids[i] );
1592 if ( groupData._indices == curIndices )
1593 return newShape; // group not changed
1596 groupData._indices = curIndices;
1598 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1599 if ( !geomClient ) return newShape;
1600 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1601 geomClient->RemoveShapeFromBuffer( groupIOR );
1602 newShape = _gen_i->GeomObjectToShape( geomGroup );
1605 if ( newShape.IsNull() ) {
1606 // geom group becomes empty - return empty compound
1607 TopoDS_Compound compound;
1608 BRep_Builder().MakeCompound(compound);
1609 newShape = compound;
1615 //=============================================================================
1617 * \brief Storage of shape and index used in CheckGeomGroupModif()
1619 //=============================================================================
1620 struct TIndexedShape {
1622 TopoDS_Shape _shape;
1623 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1626 //=============================================================================
1628 * \brief Update objects depending on changed geom groups
1630 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1631 * issue 0020210: Update of a smesh group after modification of the associated geom group
1633 //=============================================================================
1635 void SMESH_Mesh_i::CheckGeomGroupModif()
1637 if ( !_impl->HasShapeToMesh() ) return;
1639 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1640 if ( study->_is_nil() ) return;
1642 CORBA::Long nbEntities = NbNodes() + NbElements();
1644 // Check if group contents changed
1646 typedef map< string, TopoDS_Shape > TEntry2Geom;
1647 TEntry2Geom newGroupContents;
1649 list<TGeomGroupData>::iterator
1650 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1651 for ( ; data != dataEnd; ++data )
1653 pair< TEntry2Geom::iterator, bool > it_new =
1654 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1655 bool processedGroup = !it_new.second;
1656 TopoDS_Shape& newShape = it_new.first->second;
1657 if ( !processedGroup )
1658 newShape = newGroupShape( *data );
1659 if ( newShape.IsNull() )
1660 continue; // no changes
1662 if ( processedGroup ) { // update group indices
1663 list<TGeomGroupData>::iterator data2 = data;
1664 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1665 data->_indices = data2->_indices;
1668 // Update SMESH objects according to new GEOM group contents
1670 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1671 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1673 int oldID = submesh->GetId();
1674 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1676 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1678 // update hypotheses
1679 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1680 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1681 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1683 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1684 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1686 // care of submeshes
1687 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1688 int newID = newSubmesh->GetId();
1689 if ( newID != oldID ) {
1690 _mapSubMesh [ newID ] = newSubmesh;
1691 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1692 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1693 _mapSubMesh. erase(oldID);
1694 _mapSubMesh_i. erase(oldID);
1695 _mapSubMeshIor.erase(oldID);
1696 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1701 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1702 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1703 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1705 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1707 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1708 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1709 ds->SetShape( newShape );
1714 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1715 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1717 // Remove groups and submeshes basing on removed sub-shapes
1719 TopTools_MapOfShape newShapeMap;
1720 TopoDS_Iterator shapeIt( newShape );
1721 for ( ; shapeIt.More(); shapeIt.Next() )
1722 newShapeMap.Add( shapeIt.Value() );
1724 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1725 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1727 if ( newShapeMap.Contains( shapeIt.Value() ))
1729 TopTools_IndexedMapOfShape oldShapeMap;
1730 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1731 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1733 const TopoDS_Shape& oldShape = oldShapeMap(i);
1734 int oldInd = meshDS->ShapeToIndex( oldShape );
1736 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1737 if ( i_smIor != _mapSubMeshIor.end() ) {
1738 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1741 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1742 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1744 // check if a group bases on oldInd shape
1745 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1746 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1747 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1748 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1750 RemoveGroup( i_grp->second ); // several groups can base on same shape
1751 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1756 // Reassign hypotheses and update groups after setting the new shape to mesh
1758 // collect anassigned hypotheses
1759 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1760 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1761 TShapeHypList assignedHyps;
1762 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1764 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1765 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1766 if ( !hyps.empty() ) {
1767 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1768 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1769 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1772 // collect shapes supporting groups
1773 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1774 TShapeTypeList groupData;
1775 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1776 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1777 for ( ; grIt != groups.end(); ++grIt )
1779 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1781 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1783 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1784 _impl->ShapeToMesh( newShape );
1786 // reassign hypotheses
1787 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1788 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1790 TIndexedShape& geom = indS_hyps->first;
1791 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1792 int oldID = geom._index;
1793 int newID = meshDS->ShapeToIndex( geom._shape );
1796 if ( oldID == 1 ) { // main shape
1798 geom._shape = newShape;
1800 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1801 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1802 // care of submeshes
1803 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1804 if ( newID != oldID ) {
1805 _mapSubMesh [ newID ] = newSubmesh;
1806 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1807 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1808 _mapSubMesh. erase(oldID);
1809 _mapSubMesh_i. erase(oldID);
1810 _mapSubMeshIor.erase(oldID);
1811 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1815 TShapeTypeList::iterator geomType = groupData.begin();
1816 for ( ; geomType != groupData.end(); ++geomType )
1818 const TIndexedShape& geom = geomType->first;
1819 int oldID = geom._index;
1820 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1823 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1824 CORBA::String_var name = groupSO->GetName();
1826 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1828 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1829 group_i->changeLocalId( newID );
1832 break; // everything has been updated
1835 } // loop on group data
1839 CORBA::Long newNbEntities = NbNodes() + NbElements();
1840 list< SALOMEDS::SObject_var > soToUpdateIcons;
1841 if ( newNbEntities != nbEntities )
1843 // Add all SObjects with icons
1844 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1846 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1847 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1848 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1850 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1851 i_gr != _mapGroups.end(); ++i_gr ) // groups
1852 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1855 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1856 for ( ; so != soToUpdateIcons.end(); ++so )
1857 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1860 //=============================================================================
1862 * \brief Create standalone group instead if group on geometry
1865 //=============================================================================
1867 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1869 SMESH::SMESH_Group_var aGroup;
1870 if ( theGroup->_is_nil() )
1871 return aGroup._retn();
1873 Unexpect aCatch(SALOME_SalomeException);
1875 SMESH_GroupBase_i* aGroupToRem =
1876 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1878 return aGroup._retn();
1880 int anId = aGroupToRem->GetLocalID();
1881 if ( !_impl->ConvertToStandalone( anId ) )
1882 return aGroup._retn();
1883 removeGeomGroupData( theGroup );
1885 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1887 // remove old instance of group from own map
1888 _mapGroups.erase( anId );
1890 SALOMEDS::StudyBuilder_var builder;
1891 SALOMEDS::SObject_var aGroupSO;
1892 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1893 if ( !aStudy->_is_nil() ) {
1894 builder = aStudy->NewBuilder();
1895 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1896 if ( !aGroupSO->_is_nil() ) {
1898 // remove reference to geometry
1899 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1900 for ( ; chItr->More(); chItr->Next() )
1901 // Remove group's child SObject
1902 builder->RemoveObject( chItr->Value() );
1904 // Update Python script
1905 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1906 << aGroupSO << " )";
1910 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1911 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1912 aGroupImpl->Register();
1913 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1915 // remember new group in own map
1916 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1917 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1919 // register CORBA object for persistence
1920 //int nextId = _gen_i->RegisterObject( aGroup );
1921 //if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1922 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1924 return aGroup._retn();
1927 //=============================================================================
1931 //=============================================================================
1933 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1935 if(MYDEBUG) MESSAGE( "createSubMesh" );
1936 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1938 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1939 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1940 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1941 SMESH::SMESH_subMesh_var subMesh
1942 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1944 _mapSubMesh[subMeshId] = mySubMesh;
1945 _mapSubMesh_i[subMeshId] = subMeshServant;
1946 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1948 // register CORBA object for persistence
1949 int nextId = _gen_i->RegisterObject( subMesh );
1950 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1952 // to track changes of GEOM groups
1953 addGeomGroupData( theSubShapeObject, subMesh );
1955 return subMesh._retn();
1958 //=======================================================================
1959 //function : getSubMesh
1961 //=======================================================================
1963 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1965 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1966 if ( it == _mapSubMeshIor.end() )
1967 return SMESH::SMESH_subMesh::_nil();
1969 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
1973 //=============================================================================
1977 //=============================================================================
1979 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
1980 GEOM::GEOM_Object_ptr theSubShapeObject )
1982 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
1983 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
1986 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
1988 CORBA::Long shapeId = theSubMesh->GetId();
1989 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
1991 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
1994 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
1995 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
1996 for ( ; hyp != hyps.end(); ++hyp )
1997 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2004 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2005 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2006 removeHypothesis( theSubShapeObject, aHypList[i] );
2009 catch( const SALOME::SALOME_Exception& ) {
2010 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2012 removeGeomGroupData( theSubShapeObject );
2014 int subMeshId = theSubMesh->GetId();
2016 _mapSubMesh.erase(subMeshId);
2017 _mapSubMesh_i.erase(subMeshId);
2018 _mapSubMeshIor.erase(subMeshId);
2019 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2022 //=============================================================================
2026 //=============================================================================
2028 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2029 const char* theName,
2030 const TopoDS_Shape& theShape )
2033 SMESH::SMESH_GroupBase_var aGroup;
2034 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2035 SMESH_GroupBase_i* aGroupImpl;
2036 if ( !theShape.IsNull() )
2037 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2039 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2041 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2042 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2043 aGroupImpl->Register();
2044 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2046 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2047 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2049 // register CORBA object for persistence
2050 int nextId = _gen_i->RegisterObject( aGroup );
2051 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2053 // to track changes of GEOM groups
2054 if ( !theShape.IsNull() ) {
2055 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2056 addGeomGroupData( geom, aGroup );
2059 return aGroup._retn();
2062 //=============================================================================
2064 * SMESH_Mesh_i::removeGroup
2066 * Should be called by ~SMESH_Group_i()
2068 //=============================================================================
2070 void SMESH_Mesh_i::removeGroup( const int theId )
2072 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2073 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2074 removeGeomGroupData( _mapGroups[theId] );
2075 _mapGroups.erase( theId );
2076 _impl->RemoveGroup( theId );
2081 //=============================================================================
2085 //=============================================================================
2087 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2088 throw(SALOME::SALOME_Exception)
2090 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2092 SMESH::log_array_var aLog;
2094 list < SMESHDS_Command * >logDS = _impl->GetLog();
2095 aLog = new SMESH::log_array;
2097 int lg = logDS.size();
2100 list < SMESHDS_Command * >::iterator its = logDS.begin();
2101 while(its != logDS.end()){
2102 SMESHDS_Command *com = *its;
2103 int comType = com->GetType();
2105 int lgcom = com->GetNumber();
2107 const list < int >&intList = com->GetIndexes();
2108 int inum = intList.size();
2110 list < int >::const_iterator ii = intList.begin();
2111 const list < double >&coordList = com->GetCoords();
2112 int rnum = coordList.size();
2114 list < double >::const_iterator ir = coordList.begin();
2115 aLog[indexLog].commandType = comType;
2116 aLog[indexLog].number = lgcom;
2117 aLog[indexLog].coords.length(rnum);
2118 aLog[indexLog].indexes.length(inum);
2119 for(int i = 0; i < rnum; i++){
2120 aLog[indexLog].coords[i] = *ir;
2121 //MESSAGE(" "<<i<<" "<<ir.Value());
2124 for(int i = 0; i < inum; i++){
2125 aLog[indexLog].indexes[i] = *ii;
2126 //MESSAGE(" "<<i<<" "<<ii.Value());
2135 catch(SALOME_Exception & S_ex){
2136 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2138 return aLog._retn();
2142 //=============================================================================
2146 //=============================================================================
2148 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2150 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2154 //=============================================================================
2158 //=============================================================================
2160 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2162 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2166 //=============================================================================
2170 //=============================================================================
2172 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2177 //=============================================================================
2181 //=============================================================================
2183 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2185 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2189 //=============================================================================
2193 //=============================================================================
2195 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2197 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2201 //=============================================================================
2203 * Return mesh editor
2205 //=============================================================================
2207 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2209 // Create MeshEditor
2210 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2211 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2213 // Update Python script
2214 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2216 return aMesh._retn();
2219 //=============================================================================
2221 * Return mesh edition previewer
2223 //=============================================================================
2225 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2227 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2228 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2229 return aMesh._retn();
2232 //=============================================================================
2236 //=============================================================================
2237 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2239 Unexpect aCatch(SALOME_SalomeException);
2240 _impl->SetAutoColor(theAutoColor);
2243 //=============================================================================
2247 //=============================================================================
2248 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2250 Unexpect aCatch(SALOME_SalomeException);
2251 return _impl->GetAutoColor();
2255 //=============================================================================
2257 * Export in different formats
2259 //=============================================================================
2261 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2263 return _impl->HasDuplicatedGroupNamesMED();
2266 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2268 TCollection_AsciiString aFullName ((char*)file);
2269 OSD_Path aPath (aFullName);
2270 OSD_File aFile (aPath);
2271 if (aFile.Exists()) {
2272 // existing filesystem node
2273 if (aFile.KindOfFile() == OSD_FILE) {
2274 if (aFile.IsWriteable()) {
2279 if (aFile.Failed()) {
2280 TCollection_AsciiString msg ("File ");
2281 msg += aFullName + " cannot be replaced.";
2282 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2285 TCollection_AsciiString msg ("File ");
2286 msg += aFullName + " cannot be overwritten.";
2287 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2290 TCollection_AsciiString msg ("Location ");
2291 msg += aFullName + " is not a file.";
2292 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2295 // nonexisting file; check if it can be created
2297 aFile.Build(OSD_WriteOnly, OSD_Protection());
2298 if (aFile.Failed()) {
2299 TCollection_AsciiString msg ("You cannot create the file ");
2300 msg += aFullName + ". Check the directory existance and access rights.";
2301 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2309 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2310 CORBA::Boolean auto_groups,
2311 SMESH::MED_VERSION theVersion,
2312 CORBA::Boolean overwrite)
2313 throw(SALOME::SALOME_Exception)
2315 Unexpect aCatch(SALOME_SalomeException);
2318 PrepareForWriting(file, overwrite);
2319 const char* aMeshName = "Mesh";
2320 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2321 if ( !aStudy->_is_nil() ) {
2322 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2323 if ( !aMeshSO->_is_nil() ) {
2324 aMeshName = aMeshSO->GetName();
2325 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2326 if ( !aStudy->GetProperties()->IsLocked() )
2328 SALOMEDS::GenericAttribute_var anAttr;
2329 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2330 SALOMEDS::AttributeExternalFileDef_var aFileName;
2331 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2332 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2333 ASSERT(!aFileName->_is_nil());
2334 aFileName->SetValue(file);
2335 SALOMEDS::AttributeFileType_var aFileType;
2336 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2337 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2338 ASSERT(!aFileType->_is_nil());
2339 aFileType->SetValue("FICHIERMED");
2343 // Update Python script
2344 // set name of mesh before export
2345 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2347 // check names of groups
2350 TPythonDump() << _this() << ".ExportToMEDX( '"
2351 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2353 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2356 void SMESH_Mesh_i::ExportToMED (const char* file,
2357 CORBA::Boolean auto_groups,
2358 SMESH::MED_VERSION theVersion)
2359 throw(SALOME::SALOME_Exception)
2361 ExportToMEDX(file,auto_groups,theVersion,true);
2364 void SMESH_Mesh_i::ExportMED (const char* file,
2365 CORBA::Boolean auto_groups)
2366 throw(SALOME::SALOME_Exception)
2368 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2371 void SMESH_Mesh_i::ExportDAT (const char *file)
2372 throw(SALOME::SALOME_Exception)
2374 Unexpect aCatch(SALOME_SalomeException);
2376 // Update Python script
2377 // check names of groups
2379 TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
2382 PrepareForWriting(file);
2383 _impl->ExportDAT(file);
2386 void SMESH_Mesh_i::ExportUNV (const char *file)
2387 throw(SALOME::SALOME_Exception)
2389 Unexpect aCatch(SALOME_SalomeException);
2391 // Update Python script
2392 // check names of groups
2394 TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
2397 PrepareForWriting(file);
2398 _impl->ExportUNV(file);
2401 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2402 throw(SALOME::SALOME_Exception)
2404 Unexpect aCatch(SALOME_SalomeException);
2406 // Update Python script
2407 // check names of groups
2409 TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
2412 PrepareForWriting(file);
2413 _impl->ExportSTL(file, isascii);
2416 //=============================================================================
2420 //=============================================================================
2422 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2424 Unexpect aCatch(SALOME_SalomeException);
2425 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2426 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2427 return aMesh._retn();
2430 //=============================================================================
2434 //=============================================================================
2435 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2437 Unexpect aCatch(SALOME_SalomeException);
2438 return _impl->NbNodes();
2441 //=============================================================================
2445 //=============================================================================
2446 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2448 Unexpect aCatch(SALOME_SalomeException);
2449 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2452 //=============================================================================
2456 //=============================================================================
2457 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2459 Unexpect aCatch(SALOME_SalomeException);
2460 return _impl->Nb0DElements();
2463 //=============================================================================
2467 //=============================================================================
2468 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2470 Unexpect aCatch(SALOME_SalomeException);
2471 return _impl->NbEdges();
2474 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2475 throw(SALOME::SALOME_Exception)
2477 Unexpect aCatch(SALOME_SalomeException);
2478 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2481 //=============================================================================
2485 //=============================================================================
2486 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2488 Unexpect aCatch(SALOME_SalomeException);
2489 return _impl->NbFaces();
2492 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2494 Unexpect aCatch(SALOME_SalomeException);
2495 return _impl->NbTriangles();
2498 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2500 Unexpect aCatch(SALOME_SalomeException);
2501 return _impl->NbQuadrangles();
2504 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2506 Unexpect aCatch(SALOME_SalomeException);
2507 return _impl->NbPolygons();
2510 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2511 throw(SALOME::SALOME_Exception)
2513 Unexpect aCatch(SALOME_SalomeException);
2514 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2517 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2518 throw(SALOME::SALOME_Exception)
2520 Unexpect aCatch(SALOME_SalomeException);
2521 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2524 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2525 throw(SALOME::SALOME_Exception)
2527 Unexpect aCatch(SALOME_SalomeException);
2528 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2531 //=============================================================================
2535 //=============================================================================
2536 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2538 Unexpect aCatch(SALOME_SalomeException);
2539 return _impl->NbVolumes();
2542 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2544 Unexpect aCatch(SALOME_SalomeException);
2545 return _impl->NbTetras();
2548 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2550 Unexpect aCatch(SALOME_SalomeException);
2551 return _impl->NbHexas();
2554 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2556 Unexpect aCatch(SALOME_SalomeException);
2557 return _impl->NbPyramids();
2560 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2562 Unexpect aCatch(SALOME_SalomeException);
2563 return _impl->NbPrisms();
2566 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2568 Unexpect aCatch(SALOME_SalomeException);
2569 return _impl->NbPolyhedrons();
2572 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2573 throw(SALOME::SALOME_Exception)
2575 Unexpect aCatch(SALOME_SalomeException);
2576 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2579 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2580 throw(SALOME::SALOME_Exception)
2582 Unexpect aCatch(SALOME_SalomeException);
2583 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2586 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2587 throw(SALOME::SALOME_Exception)
2589 Unexpect aCatch(SALOME_SalomeException);
2590 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2593 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2594 throw(SALOME::SALOME_Exception)
2596 Unexpect aCatch(SALOME_SalomeException);
2597 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2600 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2601 throw(SALOME::SALOME_Exception)
2603 Unexpect aCatch(SALOME_SalomeException);
2604 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2607 //=============================================================================
2611 //=============================================================================
2612 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2614 Unexpect aCatch(SALOME_SalomeException);
2615 return _mapSubMesh_i.size();
2618 //=============================================================================
2622 //=============================================================================
2623 char* SMESH_Mesh_i::Dump()
2627 return CORBA::string_dup( os.str().c_str() );
2630 //=============================================================================
2634 //=============================================================================
2635 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2637 // SMESH::long_array_var aResult = new SMESH::long_array();
2638 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2639 // int aMinId = aSMESHDS_Mesh->MinElementID();
2640 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2642 // aResult->length(aMaxId - aMinId + 1);
2644 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2645 // aResult[i++] = id;
2647 // return aResult._retn();
2649 return GetElementsId();
2652 //=============================================================================
2656 //=============================================================================
2658 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2659 throw (SALOME::SALOME_Exception)
2661 Unexpect aCatch(SALOME_SalomeException);
2662 MESSAGE("SMESH_Mesh_i::GetElementsId");
2663 SMESH::long_array_var aResult = new SMESH::long_array();
2664 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2666 if ( aSMESHDS_Mesh == NULL )
2667 return aResult._retn();
2669 long nbElements = NbElements();
2670 aResult->length( nbElements );
2671 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2672 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2673 aResult[i] = anIt->next()->GetID();
2675 return aResult._retn();
2679 //=============================================================================
2683 //=============================================================================
2685 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2686 throw (SALOME::SALOME_Exception)
2688 Unexpect aCatch(SALOME_SalomeException);
2689 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2690 SMESH::long_array_var aResult = new SMESH::long_array();
2691 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2693 if ( aSMESHDS_Mesh == NULL )
2694 return aResult._retn();
2696 long nbElements = NbElements();
2698 // No sense in returning ids of elements along with ids of nodes:
2699 // when theElemType == SMESH::ALL, return node ids only if
2700 // there are no elements
2701 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2702 return GetNodesId();
2704 aResult->length( nbElements );
2708 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2709 while ( i < nbElements && anIt->more() ) {
2710 const SMDS_MeshElement* anElem = anIt->next();
2711 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2712 aResult[i++] = anElem->GetID();
2715 aResult->length( i );
2717 return aResult._retn();
2720 //=============================================================================
2724 //=============================================================================
2726 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2727 throw (SALOME::SALOME_Exception)
2729 Unexpect aCatch(SALOME_SalomeException);
2730 MESSAGE("SMESH_subMesh_i::GetNodesId");
2731 SMESH::long_array_var aResult = new SMESH::long_array();
2732 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2734 if ( aSMESHDS_Mesh == NULL )
2735 return aResult._retn();
2737 long nbNodes = NbNodes();
2738 aResult->length( nbNodes );
2739 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2740 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2741 aResult[i] = anIt->next()->GetID();
2743 return aResult._retn();
2746 //=============================================================================
2750 //=============================================================================
2752 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2753 throw (SALOME::SALOME_Exception)
2755 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2759 //=============================================================================
2761 * Returns ID of elements for given submesh
2763 //=============================================================================
2764 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2765 throw (SALOME::SALOME_Exception)
2767 SMESH::long_array_var aResult = new SMESH::long_array();
2769 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2770 if(!SM) return aResult._retn();
2772 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2773 if(!SDSM) return aResult._retn();
2775 aResult->length(SDSM->NbElements());
2777 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2779 while ( eIt->more() ) {
2780 aResult[i++] = eIt->next()->GetID();
2783 return aResult._retn();
2787 //=============================================================================
2789 * Returns ID of nodes for given submesh
2790 * If param all==true - returns all nodes, else -
2791 * returns only nodes on shapes.
2793 //=============================================================================
2794 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2795 throw (SALOME::SALOME_Exception)
2797 SMESH::long_array_var aResult = new SMESH::long_array();
2799 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2800 if(!SM) return aResult._retn();
2802 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2803 if(!SDSM) return aResult._retn();
2806 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2807 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2808 while ( nIt->more() ) {
2809 const SMDS_MeshNode* elem = nIt->next();
2810 theElems.insert( elem->GetID() );
2813 else { // all nodes of submesh elements
2814 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2815 while ( eIt->more() ) {
2816 const SMDS_MeshElement* anElem = eIt->next();
2817 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2818 while ( nIt->more() ) {
2819 const SMDS_MeshElement* elem = nIt->next();
2820 theElems.insert( elem->GetID() );
2825 aResult->length(theElems.size());
2826 set<int>::iterator itElem;
2828 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2829 aResult[i++] = *itElem;
2831 return aResult._retn();
2835 //=============================================================================
2837 * Returns type of elements for given submesh
2839 //=============================================================================
2840 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2841 throw (SALOME::SALOME_Exception)
2843 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2844 if(!SM) return SMESH::ALL;
2846 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2847 if(!SDSM) return SMESH::ALL;
2849 if(SDSM->NbElements()==0)
2850 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2852 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2853 const SMDS_MeshElement* anElem = eIt->next();
2854 return ( SMESH::ElementType ) anElem->GetType();
2858 //=============================================================================
2862 //=============================================================================
2864 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2866 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2868 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2873 //=============================================================================
2875 * Get XYZ coordinates of node as list of double
2876 * If there is not node for given ID - returns empty list
2878 //=============================================================================
2880 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2882 SMESH::double_array_var aResult = new SMESH::double_array();
2883 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2884 if ( aSMESHDS_Mesh == NULL )
2885 return aResult._retn();
2888 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2890 return aResult._retn();
2894 aResult[0] = aNode->X();
2895 aResult[1] = aNode->Y();
2896 aResult[2] = aNode->Z();
2897 return aResult._retn();
2901 //=============================================================================
2903 * For given node returns list of IDs of inverse elements
2904 * If there is not node for given ID - returns empty list
2906 //=============================================================================
2908 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2910 SMESH::long_array_var aResult = new SMESH::long_array();
2911 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2912 if ( aSMESHDS_Mesh == NULL )
2913 return aResult._retn();
2916 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2918 return aResult._retn();
2920 // find inverse elements
2921 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2922 TColStd_SequenceOfInteger IDs;
2923 while(eIt->more()) {
2924 const SMDS_MeshElement* elem = eIt->next();
2925 IDs.Append(elem->GetID());
2927 if(IDs.Length()>0) {
2928 aResult->length(IDs.Length());
2930 for(; i<=IDs.Length(); i++) {
2931 aResult[i-1] = IDs.Value(i);
2934 return aResult._retn();
2937 //=============================================================================
2939 * \brief Return position of a node on shape
2941 //=============================================================================
2943 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
2945 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
2946 aNodePosition->shapeID = 0;
2947 aNodePosition->shapeType = GEOM::SHAPE;
2949 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
2950 if ( !mesh ) return aNodePosition;
2952 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
2954 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
2956 aNodePosition->shapeID = pos->GetShapeId();
2957 switch ( pos->GetTypeOfPosition() ) {
2959 aNodePosition->shapeType = GEOM::EDGE;
2960 aNodePosition->params.length(1);
2961 aNodePosition->params[0] =
2962 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
2965 aNodePosition->shapeType = GEOM::FACE;
2966 aNodePosition->params.length(2);
2967 aNodePosition->params[0] =
2968 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
2969 aNodePosition->params[1] =
2970 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
2972 case SMDS_TOP_VERTEX:
2973 aNodePosition->shapeType = GEOM::VERTEX;
2975 case SMDS_TOP_3DSPACE:
2976 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
2977 aNodePosition->shapeType = GEOM::SOLID;
2978 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
2979 aNodePosition->shapeType = GEOM::SHELL;
2985 return aNodePosition;
2988 //=============================================================================
2990 * If given element is node returns IDs of shape from position
2991 * If there is not node for given ID - returns -1
2993 //=============================================================================
2995 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
2997 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2998 if ( aSMESHDS_Mesh == NULL )
3002 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3004 SMDS_PositionPtr pos = aNode->GetPosition();
3008 return pos->GetShapeId();
3015 //=============================================================================
3017 * For given element returns ID of result shape after
3018 * ::FindShape() from SMESH_MeshEditor
3019 * If there is not element for given ID - returns -1
3021 //=============================================================================
3023 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3025 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3026 if ( aSMESHDS_Mesh == NULL )
3029 // try to find element
3030 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3034 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3035 ::SMESH_MeshEditor aMeshEditor(_impl);
3036 int index = aMeshEditor.FindShape( elem );
3044 //=============================================================================
3046 * Returns number of nodes for given element
3047 * If there is not element for given ID - returns -1
3049 //=============================================================================
3051 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3053 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3054 if ( aSMESHDS_Mesh == NULL ) return -1;
3055 // try to find element
3056 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3057 if(!elem) return -1;
3058 return elem->NbNodes();
3062 //=============================================================================
3064 * Returns ID of node by given index for given element
3065 * If there is not element for given ID - returns -1
3066 * If there is not node for given index - returns -2
3068 //=============================================================================
3070 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3072 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3073 if ( aSMESHDS_Mesh == NULL ) return -1;
3074 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3075 if(!elem) return -1;
3076 if( index>=elem->NbNodes() || index<0 ) return -1;
3077 return elem->GetNode(index)->GetID();
3080 //=============================================================================
3082 * Returns IDs of nodes of given element
3084 //=============================================================================
3086 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3088 SMESH::long_array_var aResult = new SMESH::long_array();
3089 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3091 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3093 aResult->length( elem->NbNodes() );
3094 for ( int i = 0; i < elem->NbNodes(); ++i )
3095 aResult[ i ] = elem->GetNode( i )->GetID();
3098 return aResult._retn();
3101 //=============================================================================
3103 * Returns true if given node is medium node
3104 * in given quadratic element
3106 //=============================================================================
3108 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3110 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3111 if ( aSMESHDS_Mesh == NULL ) return false;
3113 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3114 if(!aNode) return false;
3115 // try to find element
3116 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3117 if(!elem) return false;
3119 return elem->IsMediumNode(aNode);
3123 //=============================================================================
3125 * Returns true if given node is medium node
3126 * in one of quadratic elements
3128 //=============================================================================
3130 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3131 SMESH::ElementType theElemType)
3133 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3134 if ( aSMESHDS_Mesh == NULL ) return false;
3137 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3138 if(!aNode) return false;
3140 SMESH_MesherHelper aHelper( *(_impl) );
3142 SMDSAbs_ElementType aType;
3143 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3144 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3145 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3146 else aType = SMDSAbs_All;
3148 return aHelper.IsMedium(aNode,aType);
3152 //=============================================================================
3154 * Returns number of edges for given element
3156 //=============================================================================
3158 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3160 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3161 if ( aSMESHDS_Mesh == NULL ) return -1;
3162 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3163 if(!elem) return -1;
3164 return elem->NbEdges();
3168 //=============================================================================
3170 * Returns number of faces for given element
3172 //=============================================================================
3174 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3176 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3177 if ( aSMESHDS_Mesh == NULL ) return -1;
3178 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3179 if(!elem) return -1;
3180 return elem->NbFaces();
3184 //=============================================================================
3186 * Returns true if given element is polygon
3188 //=============================================================================
3190 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3192 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3193 if ( aSMESHDS_Mesh == NULL ) return false;
3194 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3195 if(!elem) return false;
3196 return elem->IsPoly();
3200 //=============================================================================
3202 * Returns true if given element is quadratic
3204 //=============================================================================
3206 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3208 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3209 if ( aSMESHDS_Mesh == NULL ) return false;
3210 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3211 if(!elem) return false;
3212 return elem->IsQuadratic();
3216 //=============================================================================
3218 * Returns bary center for given element
3220 //=============================================================================
3222 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3224 SMESH::double_array_var aResult = new SMESH::double_array();
3225 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3226 if ( aSMESHDS_Mesh == NULL )
3227 return aResult._retn();
3229 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3231 return aResult._retn();
3233 if(elem->GetType()==SMDSAbs_Volume) {
3234 SMDS_VolumeTool aTool;
3235 if(aTool.Set(elem)) {
3237 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3242 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3244 double x=0., y=0., z=0.;
3245 for(; anIt->more(); ) {
3247 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3261 return aResult._retn();
3265 //=============================================================================
3267 * Create and publish group servants if any groups were imported or created anyhow
3269 //=============================================================================
3271 void SMESH_Mesh_i::CreateGroupServants()
3273 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3275 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3276 while ( groupIt->more() )
3278 ::SMESH_Group* group = groupIt->next();
3279 int anId = group->GetGroupDS()->GetID();
3281 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3282 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3285 SMESH_GroupBase_i* aGroupImpl;
3287 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3288 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3290 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3291 shape = groupOnGeom->GetShape();
3294 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3297 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3298 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3299 aGroupImpl->Register();
3301 SMESH::SMESH_GroupBase_var groupVar =
3302 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3303 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3305 // register CORBA object for persistence
3306 int nextId = _gen_i->RegisterObject( groupVar );
3307 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3309 // publishing of the groups in the study
3310 if ( !aStudy->_is_nil() ) {
3311 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3312 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3317 //=============================================================================
3319 * \brief Return groups cantained in _mapGroups by their IDs
3321 //=============================================================================
3323 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3325 int nbGroups = groupIDs.size();
3326 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3327 aList->length( nbGroups );
3329 list<int>::const_iterator ids = groupIDs.begin();
3330 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3332 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3333 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3334 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3336 aList->length( nbGroups );
3337 return aList._retn();
3340 //=============================================================================
3342 * \brief Return information about imported file
3344 //=============================================================================
3346 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3348 SALOME_MED::MedFileInfo_var res( myFileInfo );
3349 if ( !res.operator->() ) {
3350 res = new SALOME_MED::MedFileInfo;
3352 res->fileSize = res->major = res->minor = res->release = -1;
3357 //=============================================================================
3359 * \brief Check and correct names of mesh groups
3361 //=============================================================================
3363 void SMESH_Mesh_i::checkGroupNames()
3365 int nbGrp = NbGroups();
3369 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3370 if ( aStudy->_is_nil() )
3371 return; // nothing to do
3373 SMESH::ListOfGroups* grpList = 0;
3374 // avoid dump of "GetGroups"
3376 // store python dump into a local variable inside local scope
3377 SMESH::TPythonDump pDump; // do not delete this line of code
3378 grpList = GetGroups();
3381 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3382 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3385 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3386 if ( aGrpSO->_is_nil() )
3388 // correct name of the mesh group if necessary
3389 const char* guiName = aGrpSO->GetName();
3390 if ( strcmp(guiName, aGrp->GetName()) )
3391 aGrp->SetName( guiName );
3395 //=============================================================================
3397 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3399 //=============================================================================
3400 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3402 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3403 CORBA::string_dup(theParameters));
3406 //=============================================================================
3408 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3410 //=============================================================================
3411 char* SMESH_Mesh_i::GetParameters()
3413 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3414 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3417 //=============================================================================
3419 * \brief Returns list of notebook variables used for last Mesh operation
3421 //=============================================================================
3422 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3424 SMESH::string_array_var aResult = new SMESH::string_array();
3425 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3427 char *aParameters = GetParameters();
3428 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3429 if(!aStudy->_is_nil()) {
3430 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3431 if(aSections->length() > 0) {
3432 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3433 aResult->length(aVars.length());
3434 for(int i = 0;i < aVars.length();i++)
3435 aResult[i] = CORBA::string_dup( aVars[i]);
3439 return aResult._retn();
3442 //=============================================================================
3444 * \brief Returns statistic of mesh elements
3446 //=============================================================================
3447 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3449 SMESH::long_array_var aRes = new SMESH::long_array();
3450 aRes->length(SMESH::Entity_Last);
3451 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3453 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3455 return aRes._retn();
3456 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3457 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3458 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3459 return aRes._retn();
3462 //=============================================================================
3464 * \brief Collect statistic of mesh elements given by iterator
3466 //=============================================================================
3467 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3468 SMESH::long_array& theInfo)
3470 if (!theItr) return;
3471 while (theItr->more())
3472 theInfo[ theItr->next()->GetEntityType() ]++;
3475 //=============================================================================
3477 * \brief mapping of mesh dimension into shape type
3479 //=============================================================================
3480 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3482 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3484 case 0: aType = TopAbs_VERTEX; break;
3485 case 1: aType = TopAbs_EDGE; break;
3486 case 2: aType = TopAbs_FACE; break;
3488 default:aType = TopAbs_SOLID; break;
3493 //=============================================================================
3495 * \brief Internal structure used to find concurent submeshes
3497 * It represents a pair < submesh, concurent dimension >, where
3498 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3499 * with another submesh. In other words, it is dimension of a hypothesis assigned
3502 //=============================================================================
3508 int _dim; //!< a dimension the algo can build (concurrent dimension)
3509 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3510 TopTools_MapOfShape _shapeMap;
3511 SMESH_subMesh* _subMesh;
3512 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3515 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3517 const TopoDS_Shape& theShape)
3519 _subMesh = (SMESH_subMesh*)theSubMesh;
3520 SetShape( theDim, theShape );
3524 void SetShape(const int theDim,
3525 const TopoDS_Shape& theShape)
3528 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3529 if (_dim >= _ownDim)
3530 _shapeMap.Add( theShape );
3532 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3533 for( ; anExp.More(); anExp.Next() )
3534 _shapeMap.Add( anExp.Current() );
3538 //! Check sharing of sub shapes
3539 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3540 const TopTools_MapOfShape& theToFind,
3541 const TopAbs_ShapeEnum theType)
3543 bool isShared = false;
3544 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3545 for (; !isShared && anItr.More(); anItr.Next() ) {
3546 const TopoDS_Shape aSubSh = anItr.Key();
3547 // check for case when concurrent dimensions are same
3548 isShared = theToFind.Contains( aSubSh );
3549 // check for subshape with concurrent dimension
3550 TopExp_Explorer anExp( aSubSh, theType );
3551 for ( ; !isShared && anExp.More(); anExp.Next() )
3552 isShared = theToFind.Contains( anExp.Current() );
3557 //! check algorithms
3558 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3559 const SMESHDS_Hypothesis* theA2)
3561 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3562 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3563 return false; // one of the hypothesis is not algorithm
3564 // check algorithm names (should be equal)
3565 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3569 //! Check if subshape hypotheses are concurrent
3570 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3572 if ( _subMesh == theOther->_subMesh )
3573 return false; // same subshape - should not be
3575 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3576 // any of the two submeshes is not on COMPOUND shape )
3577 // -> no concurrency
3578 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3579 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3580 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3583 // bool checkSubShape = ( _dim >= theOther->_dim )
3584 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3585 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3586 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3587 if ( !checkSubShape )
3590 // check algorithms to be same
3591 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3592 return true; // different algorithms
3594 // check hypothesises for concurrence (skip first as algorithm)
3596 // pointers should be same, becase it is referenes from mesh hypothesis partition
3597 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3598 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3599 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3600 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3602 // the submeshes are concurrent if their algorithms has different parameters
3603 return nbSame != theOther->_hypothesises.size() - 1;
3606 }; // end of SMESH_DimHyp
3608 typedef list<SMESH_DimHyp*> TDimHypList;
3610 static void addDimHypInstance(const int theDim,
3611 const TopoDS_Shape& theShape,
3612 const SMESH_Algo* theAlgo,
3613 const SMESH_subMesh* theSubMesh,
3614 const list <const SMESHDS_Hypothesis*>& theHypList,
3615 TDimHypList* theDimHypListArr )
3617 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3618 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3619 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3620 listOfdimHyp.push_back( dimHyp );
3623 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3624 dimHyp->_hypothesises.push_front(theAlgo);
3625 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3626 for( ; hypIt != theHypList.end(); hypIt++ )
3627 dimHyp->_hypothesises.push_back( *hypIt );
3630 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3631 const TDimHypList& theListOfDimHyp,
3632 TListOfInt& theListOfConcurr )
3634 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3635 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3636 const SMESH_DimHyp* curDimHyp = *rIt;
3637 if ( curDimHyp == theDimHyp )
3638 break; // meet own dimHyp pointer in same dimension
3639 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3640 if ( find( theListOfConcurr.begin(),
3641 theListOfConcurr.end(),
3642 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3643 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3647 static void unionLists(TListOfInt& theListOfId,
3648 TListOfListOfInt& theListOfListOfId,
3651 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3652 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3654 continue; //skip already treated lists
3655 // check if other list has any same submesh object
3656 TListOfInt& otherListOfId = *it;
3657 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3658 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3661 // union two lists (from source into target)
3662 TListOfInt::iterator it2 = otherListOfId.begin();
3663 for ( ; it2 != otherListOfId.end(); it2++ ) {
3664 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3665 theListOfId.push_back(*it2);
3667 // clear source list
3668 otherListOfId.clear();
3672 //! free memory allocated for dimension-hypothesis objects
3673 static void removeDimHyps( TDimHypList* theArrOfList )
3675 for (int i = 0; i < 4; i++ ) {
3676 TDimHypList& listOfdimHyp = theArrOfList[i];
3677 TDimHypList::const_iterator it = listOfdimHyp.begin();
3678 for ( ; it != listOfdimHyp.end(); it++ )
3683 //=============================================================================
3685 * \brief Return submesh objects list in meshing order
3687 //=============================================================================
3689 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3691 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3693 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3695 return aResult._retn();
3697 ::SMESH_Mesh& mesh = GetImpl();
3698 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3699 if ( !anOrder.size() ) {
3701 // collect submeshes detecting concurrent algorithms and hypothesises
3702 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3704 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3705 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3706 ::SMESH_subMesh* sm = (*i_sm).second;
3708 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3710 // list of assigned hypothesises
3711 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3712 // Find out dimensions where the submesh can be concurrent.
3713 // We define the dimensions by algo of each of hypotheses in hypList
3714 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3715 for( ; hypIt != hypList.end(); hypIt++ ) {
3716 SMESH_Algo* anAlgo = 0;
3717 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3718 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3719 // hyp it-self is algo
3720 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3722 // try to find algorithm with help of subshapes
3723 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3724 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3725 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3728 continue; // no assigned algorithm to current submesh
3730 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3731 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3733 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3734 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3735 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3737 } // end iterations on submesh
3739 // iterate on created dimension-hypotheses and check for concurrents
3740 for ( int i = 0; i < 4; i++ ) {
3741 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3742 // check for concurrents in own and other dimensions (step-by-step)
3743 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3744 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3745 const SMESH_DimHyp* dimHyp = *dhIt;
3746 TListOfInt listOfConcurr;
3747 // looking for concurrents and collect into own list
3748 for ( int j = i; j < 4; j++ )
3749 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3750 // check if any concurrents found
3751 if ( listOfConcurr.size() > 0 ) {
3752 // add own submesh to list of concurrent
3753 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3754 anOrder.push_back( listOfConcurr );
3759 removeDimHyps(dimHypListArr);
3761 // now, minimise the number of concurrent groups
3762 // Here we assume that lists of submhes can has same submesh
3763 // in case of multi-dimension algorithms, as result
3764 // list with common submesh have to be union into one list
3766 TListOfListOfInt::iterator listIt = anOrder.begin();
3767 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3768 unionLists( *listIt, anOrder, listIndx + 1 );
3770 // convert submesh ids into interface instances
3771 // and dump command into python
3772 convertMeshOrder( anOrder, aResult, true );
3774 return aResult._retn();
3777 //=============================================================================
3779 * \brief find common submeshes with given submesh
3780 * \param theSubMeshList list of already collected submesh to check
3781 * \param theSubMesh given submesh to intersect with other
3782 * \param theCommonSubMeshes collected common submeshes
3784 //=============================================================================
3786 static void findCommonSubMesh
3787 (list<const SMESH_subMesh*>& theSubMeshList,
3788 const SMESH_subMesh* theSubMesh,
3789 set<const SMESH_subMesh*>& theCommon )
3793 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
3794 for ( ; it != theSubMeshList.end(); it++ )
3795 theSubMesh->FindIntersection( *it, theCommon );
3796 theSubMeshList.push_back( theSubMesh );
3797 //theCommon.insert( theSubMesh );
3800 //=============================================================================
3802 * \brief Set submesh object order
3803 * \param theSubMeshArray submesh array order
3805 //=============================================================================
3807 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
3810 ::SMESH_Mesh& mesh = GetImpl();
3812 TPythonDump aPythonDump; // prevent dump of called methods
3813 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
3815 TListOfListOfInt subMeshOrder;
3816 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
3818 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
3819 TListOfInt subMeshIds;
3820 aPythonDump << "[ ";
3821 // Collect subMeshes which should be clear
3822 // do it list-by-list, because modification of submesh order
3823 // take effect between concurrent submeshes only
3824 set<const SMESH_subMesh*> subMeshToClear;
3825 list<const SMESH_subMesh*> subMeshList;
3826 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
3828 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
3830 aPythonDump << ", ";
3831 aPythonDump << subMesh;
3832 subMeshIds.push_back( subMesh->GetId() );
3833 // detect common parts of submeshes
3834 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
3835 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
3837 aPythonDump << " ]";
3838 subMeshOrder.push_back( subMeshIds );
3840 // clear collected submeshes
3841 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
3842 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
3843 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
3845 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
3846 // ClearSubMesh( *clrIt );
3849 aPythonDump << " ])";
3851 mesh.SetMeshOrder( subMeshOrder );
3857 //=============================================================================
3859 * \brief Convert submesh ids into submesh interfaces
3861 //=============================================================================
3863 void SMESH_Mesh_i::convertMeshOrder
3864 (const TListOfListOfInt& theIdsOrder,
3865 SMESH::submesh_array_array& theResOrder,
3866 const bool theIsDump)
3868 int nbSet = theIdsOrder.size();
3869 TPythonDump aPythonDump; // prevent dump of called methods
3871 aPythonDump << "[ ";
3872 theResOrder.length(nbSet);
3873 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
3875 for( ; it != theIdsOrder.end(); it++ ) {
3876 // translate submesh identificators into submesh objects
3877 // takeing into account real number of concurrent lists
3878 const TListOfInt& aSubOrder = (*it);
3879 if (!aSubOrder.size())
3882 aPythonDump << "[ ";
3883 // convert shape indeces into interfaces
3884 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
3885 aResSubSet->length(aSubOrder.size());
3886 TListOfInt::const_iterator subIt = aSubOrder.begin();
3887 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
3888 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
3890 SMESH::SMESH_subMesh_var subMesh =
3891 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
3894 aPythonDump << ", ";
3895 aPythonDump << subMesh;
3897 aResSubSet[ j++ ] = subMesh;
3900 aPythonDump << " ]";
3901 theResOrder[ listIndx++ ] = aResSubSet;
3903 // correct number of lists
3904 theResOrder.length( listIndx );
3907 // finilise python dump
3908 aPythonDump << " ]";
3909 aPythonDump << " = " << _this() << ".GetMeshOrder()";