1 // Copyright (C) 2007-2010 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
23 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
24 // File : SMESH_Mesh_i.cxx
25 // Author : Paul RASCLE, EDF
28 #include "SMESH_Mesh_i.hxx"
30 #include "SMESH_Filter_i.hxx"
31 #include "SMESH_Gen_i.hxx"
32 #include "SMESH_Group_i.hxx"
33 #include "SMESH_MEDMesh_i.hxx"
34 #include "SMESH_MeshEditor_i.hxx"
35 #include "SMESH_PythonDump.hxx"
36 #include "SMESH_subMesh_i.hxx"
38 #include "DriverMED_R_SMESHDS_Mesh.h"
39 #include "DriverMED_W_SMESHDS_Mesh.h"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMDS_ElemIterator.hxx"
42 #include "SMESHDS_Command.hxx"
43 #include "SMESHDS_CommandType.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Group.hxx"
46 #include "SMESH_MeshEditor.hxx"
47 #include "SMESH_MesherHelper.hxx"
48 #include "SMDS_EdgePosition.hxx"
49 #include "SMDS_FacePosition.hxx"
52 #include "SALOME_NamingService.hxx"
53 #include "Utils_CorbaException.hxx"
54 #include "Utils_ExceptHandlers.hxx"
55 #include "Utils_SINGLETON.hxx"
56 #include "utilities.h"
57 #include "GEOMImpl_Types.hxx"
60 #include <BRep_Builder.hxx>
61 #include <OSD_Directory.hxx>
62 #include <OSD_File.hxx>
63 #include <OSD_Path.hxx>
64 #include <OSD_Protection.hxx>
65 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
66 #include <TColStd_MapOfInteger.hxx>
67 #include <TColStd_SequenceOfInteger.hxx>
68 #include <TCollection_AsciiString.hxx>
70 #include <TopExp_Explorer.hxx>
71 #include <TopoDS_Compound.hxx>
72 #include <TopTools_MapOfShape.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
83 static int MYDEBUG = 0;
85 static int MYDEBUG = 0;
89 using SMESH::TPythonDump;
91 int SMESH_Mesh_i::myIdGenerator = 0;
95 //=============================================================================
99 //=============================================================================
101 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
103 CORBA::Long studyId )
104 : SALOME::GenericObj_i( thePOA )
106 MESSAGE("SMESH_Mesh_i");
109 _id = myIdGenerator++;
113 //=============================================================================
117 //=============================================================================
119 SMESH_Mesh_i::~SMESH_Mesh_i()
121 INFOS("~SMESH_Mesh_i");
122 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
123 for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
124 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
126 // this method is colled from destructor of group (PAL6331)
127 //_impl->RemoveGroup( aGroup->GetLocalID() );
136 //=============================================================================
140 * Associates <this> mesh with <theShape> and puts a reference
141 * to <theShape> into the current study;
142 * the previous shape is substituted by the new one.
144 //=============================================================================
146 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
147 throw (SALOME::SALOME_Exception)
149 Unexpect aCatch(SALOME_SalomeException);
151 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
153 catch(SALOME_Exception & S_ex) {
154 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
156 // to track changes of GEOM groups
157 addGeomGroupData( theShapeObject, _this() );
160 //================================================================================
162 * \brief return true if mesh has a shape to build a shape on
164 //================================================================================
166 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
167 throw (SALOME::SALOME_Exception)
169 Unexpect aCatch(SALOME_SalomeException);
172 res = _impl->HasShapeToMesh();
174 catch(SALOME_Exception & S_ex) {
175 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
180 //=======================================================================
181 //function : GetShapeToMesh
183 //=======================================================================
185 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
189 GEOM::GEOM_Object_var aShapeObj;
191 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
193 aShapeObj = _gen_i->ShapeToGeomObject( S );
195 catch(SALOME_Exception & S_ex) {
196 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
198 return aShapeObj._retn();
201 //================================================================================
203 * \brief Remove all nodes and elements
205 //================================================================================
207 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
209 Unexpect aCatch(SALOME_SalomeException);
212 CheckGeomGroupModif(); // issue 20145
214 catch(SALOME_Exception & S_ex) {
215 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
217 TPythonDump() << _this() << ".Clear()";
220 //================================================================================
222 * \brief Remove all nodes and elements for indicated shape
224 //================================================================================
226 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
227 throw (SALOME::SALOME_Exception)
229 Unexpect aCatch(SALOME_SalomeException);
231 _impl->ClearSubMesh( ShapeID );
233 catch(SALOME_Exception & S_ex) {
234 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
238 //=============================================================================
242 //=============================================================================
244 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
246 SMESH::DriverMED_ReadStatus res;
249 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
250 res = SMESH::DRS_OK; break;
251 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
252 res = SMESH::DRS_EMPTY; break;
253 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
254 res = SMESH::DRS_WARN_RENUMBER; break;
255 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
256 res = SMESH::DRS_WARN_SKIP_ELEM; break;
257 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
259 res = SMESH::DRS_FAIL; break;
264 //=============================================================================
268 * Imports mesh data from MED file
270 //=============================================================================
272 SMESH::DriverMED_ReadStatus
273 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
274 throw ( SALOME::SALOME_Exception )
276 Unexpect aCatch(SALOME_SalomeException);
279 status = _impl->MEDToMesh( theFileName, theMeshName );
281 catch( SALOME_Exception& S_ex ) {
282 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
285 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
288 CreateGroupServants();
290 int major, minor, release;
291 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
292 major = minor = release = -1;
293 myFileInfo = new SALOME_MED::MedFileInfo();
294 myFileInfo->fileName = theFileName;
295 myFileInfo->fileSize = 0;
298 if ( ::_stati64( theFileName, &d ) != -1 )
301 if ( ::stat64( theFileName, &d ) != -1 )
303 myFileInfo->fileSize = d.st_size;
304 myFileInfo->major = major;
305 myFileInfo->minor = minor;
306 myFileInfo->release = release;
308 return ConvertDriverMEDReadStatus(status);
311 //================================================================================
313 * \brief Return string representation of a MED file version comprising nbDigits
315 //================================================================================
317 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
319 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
321 return CORBA::string_dup( ver.c_str() );
324 //=============================================================================
328 * Imports mesh data from MED file
330 //=============================================================================
332 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
333 throw ( SALOME::SALOME_Exception )
335 // Read mesh with name = <theMeshName> into SMESH_Mesh
336 _impl->UNVToMesh( theFileName );
338 CreateGroupServants();
343 //=============================================================================
347 * Imports mesh data from STL file
349 //=============================================================================
350 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
351 throw ( SALOME::SALOME_Exception )
353 // Read mesh with name = <theMeshName> into SMESH_Mesh
354 _impl->STLToMesh( theFileName );
359 //=============================================================================
363 * Imports mesh data from MED file
365 //=============================================================================
367 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
369 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
370 // int status = _impl->MEDToMesh( theFileName, theMeshName );
371 // CreateGroupServants();
376 //=============================================================================
380 //=============================================================================
382 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
384 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
385 (SMESH_Hypothesis::Hypothesis_Status theStatus)
388 RETURNCASE( HYP_OK );
389 RETURNCASE( HYP_MISSING );
390 RETURNCASE( HYP_CONCURENT );
391 RETURNCASE( HYP_BAD_PARAMETER );
392 RETURNCASE( HYP_HIDDEN_ALGO );
393 RETURNCASE( HYP_HIDING_ALGO );
394 RETURNCASE( HYP_UNKNOWN_FATAL );
395 RETURNCASE( HYP_INCOMPATIBLE );
396 RETURNCASE( HYP_NOTCONFORM );
397 RETURNCASE( HYP_ALREADY_EXIST );
398 RETURNCASE( HYP_BAD_DIM );
399 RETURNCASE( HYP_BAD_SUBSHAPE );
400 RETURNCASE( HYP_BAD_GEOMETRY );
401 RETURNCASE( HYP_NEED_SHAPE );
404 return SMESH::HYP_UNKNOWN_FATAL;
407 //=============================================================================
411 * calls internal addHypothesis() and then adds a reference to <anHyp> under
412 * the SObject actually having a reference to <aSubShape>.
413 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
415 //=============================================================================
417 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
418 SMESH::SMESH_Hypothesis_ptr anHyp)
419 throw(SALOME::SALOME_Exception)
421 Unexpect aCatch(SALOME_SalomeException);
422 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
424 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
425 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
426 aSubShapeObject, anHyp );
428 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
430 // Update Python script
431 if(_impl->HasShapeToMesh()) {
432 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
433 << aSubShapeObject << ", " << anHyp << " )";
436 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
439 return ConvertHypothesisStatus(status);
442 //=============================================================================
446 //=============================================================================
448 SMESH_Hypothesis::Hypothesis_Status
449 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
450 SMESH::SMESH_Hypothesis_ptr anHyp)
452 if(MYDEBUG) MESSAGE("addHypothesis");
454 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
455 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
458 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
459 if (CORBA::is_nil(myHyp))
460 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
463 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
466 TopoDS_Shape myLocSubShape;
467 //use PseudoShape in case if mesh has no shape
469 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
471 myLocSubShape = _impl->GetShapeToMesh();
473 int hypId = myHyp->GetId();
474 status = _impl->AddHypothesis(myLocSubShape, hypId);
475 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
476 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
477 // assure there is a corresponding submesh
478 if ( !_impl->IsMainShape( myLocSubShape )) {
479 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
480 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
481 createSubMesh( aSubShapeObject );
485 catch(SALOME_Exception & S_ex)
487 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
492 //=============================================================================
496 //=============================================================================
498 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
499 SMESH::SMESH_Hypothesis_ptr anHyp)
500 throw(SALOME::SALOME_Exception)
502 Unexpect aCatch(SALOME_SalomeException);
503 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
505 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
506 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
507 aSubShapeObject, anHyp );
509 // Update Python script
510 // Update Python script
511 if(_impl->HasShapeToMesh()) {
512 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
513 << aSubShapeObject << ", " << anHyp << " )";
516 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
520 return ConvertHypothesisStatus(status);
523 //=============================================================================
527 //=============================================================================
529 SMESH_Hypothesis::Hypothesis_Status
530 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
531 SMESH::SMESH_Hypothesis_ptr anHyp)
533 if(MYDEBUG) MESSAGE("removeHypothesis()");
534 // **** proposer liste de subShape (selection multiple)
536 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
537 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
539 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
540 if (CORBA::is_nil(myHyp))
541 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
543 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
546 TopoDS_Shape myLocSubShape;
547 //use PseudoShape in case if mesh has no shape
549 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
551 myLocSubShape = _impl->GetShapeToMesh();
553 int hypId = myHyp->GetId();
554 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
555 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
556 // _mapHypo.erase( hypId );
558 catch(SALOME_Exception & S_ex)
560 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
565 //=============================================================================
569 //=============================================================================
571 SMESH::ListOfHypothesis *
572 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
573 throw(SALOME::SALOME_Exception)
575 Unexpect aCatch(SALOME_SalomeException);
576 if (MYDEBUG) MESSAGE("GetHypothesisList");
577 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
578 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
580 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
583 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
584 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
585 myLocSubShape = _impl->GetShapeToMesh();
586 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
587 int i = 0, n = aLocalList.size();
590 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
591 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
592 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
593 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
598 catch(SALOME_Exception & S_ex) {
599 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
602 return aList._retn();
605 //=============================================================================
609 //=============================================================================
610 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
611 const char* theName )
612 throw(SALOME::SALOME_Exception)
614 Unexpect aCatch(SALOME_SalomeException);
615 MESSAGE("SMESH_Mesh_i::GetSubMesh");
616 if (CORBA::is_nil(aSubShapeObject))
617 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
620 SMESH::SMESH_subMesh_var subMesh;
621 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
623 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
625 //Get or Create the SMESH_subMesh object implementation
627 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
628 subMesh = getSubMesh( subMeshId );
630 // create a new subMesh object servant if there is none for the shape
631 if ( subMesh->_is_nil() )
632 subMesh = createSubMesh( aSubShapeObject );
633 if ( _gen_i->CanPublishInStudy( subMesh )) {
634 SALOMEDS::SObject_var aSO =
635 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
636 subMesh, aSubShapeObject, theName );
637 if ( !aSO->_is_nil()) {
638 // Update Python script
639 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
640 << aSubShapeObject << ", '" << theName << "' )";
644 catch(SALOME_Exception & S_ex) {
645 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
647 return subMesh._retn();
650 //=============================================================================
654 //=============================================================================
656 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
657 throw (SALOME::SALOME_Exception)
659 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
660 if ( theSubMesh->_is_nil() )
663 GEOM::GEOM_Object_var aSubShapeObject;
664 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
665 if ( !aStudy->_is_nil() ) {
666 // Remove submesh's SObject
667 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
668 if ( !anSO->_is_nil() ) {
669 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
670 SALOMEDS::SObject_var anObj, aRef;
671 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
672 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
674 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
675 // aSubShapeObject = theSubMesh->GetSubShape();
677 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
679 // Update Python script
680 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
684 removeSubMesh( theSubMesh, aSubShapeObject.in() );
687 //=============================================================================
691 //=============================================================================
692 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
693 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
695 switch (theElemType) {
700 CASE2STRING( VOLUME );
706 //=============================================================================
710 //=============================================================================
712 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
713 const char* theName )
714 throw(SALOME::SALOME_Exception)
716 Unexpect aCatch(SALOME_SalomeException);
717 SMESH::SMESH_Group_var aNewGroup =
718 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
720 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
721 SALOMEDS::SObject_var aSO =
722 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
723 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
724 if ( !aSO->_is_nil()) {
725 // Update Python script
726 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
727 << ElementTypeString(theElemType) << ", '" << theName << "' )";
730 return aNewGroup._retn();
734 //=============================================================================
738 //=============================================================================
739 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
741 GEOM::GEOM_Object_ptr theGeomObj)
742 throw(SALOME::SALOME_Exception)
744 Unexpect aCatch(SALOME_SalomeException);
745 SMESH::SMESH_GroupOnGeom_var aNewGroup;
747 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
748 if ( !aShape.IsNull() )
750 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
751 ( createGroup( theElemType, theName, aShape ));
753 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
754 SALOMEDS::SObject_var aSO =
755 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
756 aNewGroup, theGeomObj, theName);
757 if ( !aSO->_is_nil()) {
758 // Update Python script
759 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
760 << ElementTypeString(theElemType) << ", '" << theName << "', "
761 << theGeomObj << " )";
766 return aNewGroup._retn();
769 //=============================================================================
773 //=============================================================================
775 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
776 throw (SALOME::SALOME_Exception)
778 if ( theGroup->_is_nil() )
781 SMESH_GroupBase_i* aGroup =
782 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
786 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
787 if ( !aStudy->_is_nil() ) {
788 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
790 if ( !aGroupSO->_is_nil() ) {
791 // Update Python script
792 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
794 // Remove group's SObject
795 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
799 // Remove the group from SMESH data structures
800 removeGroup( aGroup->GetLocalID() );
803 //=============================================================================
804 /*! RemoveGroupWithContents
805 * Remove group with its contents
807 //=============================================================================
808 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
809 throw (SALOME::SALOME_Exception)
811 if ( theGroup->_is_nil() )
814 SMESH_GroupBase_i* aGroup =
815 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
819 SMESH::long_array_var anIds = aGroup->GetListOfID();
820 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
822 // Update Python script
823 TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
826 if ( aGroup->GetType() == SMESH::NODE )
827 aMeshEditor->RemoveNodes( anIds );
829 aMeshEditor->RemoveElements( anIds );
832 RemoveGroup( theGroup );
834 // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
835 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
836 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
840 //================================================================================
842 * \brief Get the list of groups existing in the mesh
843 * \retval SMESH::ListOfGroups * - list of groups
845 //================================================================================
847 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
849 Unexpect aCatch(SALOME_SalomeException);
850 if (MYDEBUG) MESSAGE("GetGroups");
852 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
855 TPythonDump aPythonDump;
856 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
860 aList->length( _mapGroups.size() );
862 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
863 for ( ; it != _mapGroups.end(); it++ ) {
864 if ( CORBA::is_nil( it->second )) continue;
865 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
867 if (i > 1) aPythonDump << ", ";
868 aPythonDump << it->second;
872 catch(SALOME_Exception & S_ex) {
873 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
876 // Update Python script
877 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
878 aPythonDump << " ] = " << _this() << ".GetGroups()";
880 return aList._retn();
882 //=============================================================================
884 * Get number of groups existing in the mesh
886 //=============================================================================
888 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
890 Unexpect aCatch(SALOME_SalomeException);
891 return _mapGroups.size();
894 //=============================================================================
896 * New group is created. All mesh elements that are
897 * present in initial groups are added to the new one
899 //=============================================================================
900 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
901 SMESH::SMESH_GroupBase_ptr theGroup2,
902 const char* theName )
903 throw (SALOME::SALOME_Exception)
907 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
908 theGroup1->GetType() != theGroup2->GetType() )
909 return SMESH::SMESH_Group::_nil();
912 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
913 if ( aResGrp->_is_nil() )
914 return SMESH::SMESH_Group::_nil();
916 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
917 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
919 TColStd_MapOfInteger aResMap;
921 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
922 aResMap.Add( anIds1[ i1 ] );
924 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
925 aResMap.Add( anIds2[ i2 ] );
927 SMESH::long_array_var aResIds = new SMESH::long_array;
928 aResIds->length( aResMap.Extent() );
931 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
932 for( ; anIter.More(); anIter.Next() )
933 aResIds[ resI++ ] = anIter.Key();
935 aResGrp->Add( aResIds );
937 // Clear python lines, created by CreateGroup() and Add()
938 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
939 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
940 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
942 // Update Python script
943 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
944 << theGroup1 << ", " << theGroup2 << ", '"
947 return aResGrp._retn();
951 return SMESH::SMESH_Group::_nil();
955 //=============================================================================
957 \brief Union list of groups. New group is created. All mesh elements that are
958 present in initial groups are added to the new one.
959 \param theGroups list of groups
960 \param theName name of group to be created
961 \return pointer on the group
963 //=============================================================================
964 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
965 const char* theName )
966 throw (SALOME::SALOME_Exception)
969 return SMESH::SMESH_Group::_nil();
973 NCollection_Map< int > anIds;
974 SMESH::ElementType aType = SMESH::ALL;
975 for ( int g = 0, n = theGroups.length(); g < n; g++ )
977 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
978 if ( CORBA::is_nil( aGrp ) )
982 SMESH::ElementType aCurrType = aGrp->GetType();
983 if ( aType == SMESH::ALL )
987 if ( aType != aCurrType )
988 return SMESH::SMESH_Group::_nil();
992 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
993 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
995 int aCurrId = aCurrIds[ i ];
996 anIds.Add( aCurrId );
1001 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1002 if ( aResGrp->_is_nil() )
1003 return SMESH::SMESH_Group::_nil();
1005 // Create array of identifiers
1006 SMESH::long_array_var aResIds = new SMESH::long_array;
1007 aResIds->length( anIds.Extent() );
1009 NCollection_Map< int >::Iterator anIter( anIds );
1010 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1012 aResIds[ i ] = anIter.Value();
1014 aResGrp->Add( aResIds );
1016 // Clear python lines, created by CreateGroup() and Add()
1017 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1018 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1019 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1021 // Update Python script
1023 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1024 << &theGroups << ", '" << theName << "' )";
1026 return aResGrp._retn();
1030 return SMESH::SMESH_Group::_nil();
1034 //=============================================================================
1036 * New group is created. All mesh elements that are
1037 * present in both initial groups are added to the new one.
1039 //=============================================================================
1040 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1041 SMESH::SMESH_GroupBase_ptr theGroup2,
1042 const char* theName )
1043 throw (SALOME::SALOME_Exception)
1045 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1046 theGroup1->GetType() != theGroup2->GetType() )
1047 return SMESH::SMESH_Group::_nil();
1049 // Create Intersection
1050 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1051 if ( aResGrp->_is_nil() )
1054 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1055 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1057 TColStd_MapOfInteger aMap1;
1059 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1060 aMap1.Add( anIds1[ i1 ] );
1062 TColStd_SequenceOfInteger aSeq;
1064 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1065 if ( aMap1.Contains( anIds2[ i2 ] ) )
1066 aSeq.Append( anIds2[ i2 ] );
1068 SMESH::long_array_var aResIds = new SMESH::long_array;
1069 aResIds->length( aSeq.Length() );
1071 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1072 aResIds[ resI ] = aSeq( resI + 1 );
1074 aResGrp->Add( aResIds );
1076 // Clear python lines, created by CreateGroup() and Add()
1077 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1078 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1079 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1081 // Update Python script
1082 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1083 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1085 return aResGrp._retn();
1088 //=============================================================================
1090 \brief Intersect list of groups. New group is created. All mesh elements that
1091 are present in all initial groups simultaneously are added to the new one.
1092 \param theGroups list of groups
1093 \param theName name of group to be created
1094 \return pointer on the group
1096 //=============================================================================
1097 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1098 const SMESH::ListOfGroups& theGroups, const char* theName )
1099 throw (SALOME::SALOME_Exception)
1102 return SMESH::SMESH_Group::_nil();
1106 NCollection_DataMap< int, int > anIdToCount;
1107 SMESH::ElementType aType = SMESH::ALL;
1108 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1110 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1111 if ( CORBA::is_nil( aGrp ) )
1115 SMESH::ElementType aCurrType = aGrp->GetType();
1116 if ( aType == SMESH::ALL )
1120 if ( aType != aCurrType )
1121 return SMESH::SMESH_Group::_nil();
1124 // calculates number of occurance ids in groups
1125 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1126 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1128 int aCurrId = aCurrIds[ i ];
1129 if ( !anIdToCount.IsBound( aCurrId ) )
1130 anIdToCount.Bind( aCurrId, 1 );
1132 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1136 // create map of ids
1137 int nbGrp = theGroups.length();
1138 NCollection_Map< int > anIds;
1139 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1140 for ( ; anIter.More(); anIter.Next() )
1142 int aCurrId = anIter.Key();
1143 int aCurrNb = anIter.Value();
1144 if ( aCurrNb == nbGrp )
1145 anIds.Add( aCurrId );
1149 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1150 if ( aResGrp->_is_nil() )
1151 return SMESH::SMESH_Group::_nil();
1153 // Create array of identifiers
1154 SMESH::long_array_var aResIds = new SMESH::long_array;
1155 aResIds->length( anIds.Extent() );
1157 NCollection_Map< int >::Iterator aListIter( anIds );
1158 for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1160 aResIds[ i ] = aListIter.Value();
1162 aResGrp->Add( aResIds );
1164 // Clear python lines, created by CreateGroup() and Add()
1165 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1166 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1167 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1169 // Update Python script
1171 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1172 << &theGroups << ", '" << theName << "' )";
1174 return aResGrp._retn();
1178 return SMESH::SMESH_Group::_nil();
1182 //=============================================================================
1184 * New group is created. All mesh elements that are present in
1185 * main group but do not present in tool group are added to the new one
1187 //=============================================================================
1188 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1189 SMESH::SMESH_GroupBase_ptr theGroup2,
1190 const char* theName )
1191 throw (SALOME::SALOME_Exception)
1193 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1194 theGroup1->GetType() != theGroup2->GetType() )
1195 return SMESH::SMESH_Group::_nil();
1198 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1199 if ( aResGrp->_is_nil() )
1202 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1203 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1205 TColStd_MapOfInteger aMap2;
1207 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1208 aMap2.Add( anIds2[ i2 ] );
1210 TColStd_SequenceOfInteger aSeq;
1211 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1212 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1213 aSeq.Append( anIds1[ i1 ] );
1215 SMESH::long_array_var aResIds = new SMESH::long_array;
1216 aResIds->length( aSeq.Length() );
1218 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1219 aResIds[ resI ] = aSeq( resI + 1 );
1221 aResGrp->Add( aResIds );
1223 // Clear python lines, created by CreateGroup() and Add()
1224 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1225 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1226 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1228 // Update Python script
1229 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1230 << theGroup1 << ", " << theGroup2 << ", '"
1231 << theName << "' )";
1233 return aResGrp._retn();
1236 //=============================================================================
1238 \brief Cut lists of groups. New group is created. All mesh elements that are
1239 present in main groups but do not present in tool groups are added to the new one
1240 \param theMainGroups list of main groups
1241 \param theToolGroups list of tool groups
1242 \param theName name of group to be created
1243 \return pointer on the group
1245 //=============================================================================
1246 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1247 const SMESH::ListOfGroups& theMainGroups,
1248 const SMESH::ListOfGroups& theToolGroups,
1249 const char* theName )
1250 throw (SALOME::SALOME_Exception)
1253 return SMESH::SMESH_Group::_nil();
1257 NCollection_Map< int > aToolIds;
1258 SMESH::ElementType aType = SMESH::ALL;
1260 // iterate through tool groups
1261 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1263 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1264 if ( CORBA::is_nil( aGrp ) )
1268 SMESH::ElementType aCurrType = aGrp->GetType();
1269 if ( aType == SMESH::ALL )
1273 if ( aType != aCurrType )
1274 return SMESH::SMESH_Group::_nil();
1278 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1279 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1281 int aCurrId = aCurrIds[ i ];
1282 aToolIds.Add( aCurrId );
1286 NCollection_Map< int > anIds; // result
1288 // Iterate through main group
1289 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1291 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1292 if ( CORBA::is_nil( aGrp ) )
1296 SMESH::ElementType aCurrType = aGrp->GetType();
1297 if ( aType == SMESH::ALL )
1301 if ( aType != aCurrType )
1302 return SMESH::SMESH_Group::_nil();
1306 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1307 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1309 int aCurrId = aCurrIds[ i ];
1310 if ( !aToolIds.Contains( aCurrId ) )
1311 anIds.Add( aCurrId );
1316 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1317 if ( aResGrp->_is_nil() )
1318 return SMESH::SMESH_Group::_nil();
1320 // Create array of identifiers
1321 SMESH::long_array_var aResIds = new SMESH::long_array;
1322 aResIds->length( anIds.Extent() );
1324 NCollection_Map< int >::Iterator anIter( anIds );
1325 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1327 aResIds[ i ] = anIter.Value();
1329 aResGrp->Add( aResIds );
1331 // Clear python lines, created by CreateGroup() and Add()
1332 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1333 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1334 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1336 // Update Python script
1338 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1339 << &theMainGroups << ", " << &theToolGroups << ", '"
1340 << theName << "' )";
1342 return aResGrp._retn();
1346 return SMESH::SMESH_Group::_nil();
1350 //=============================================================================
1352 \brief Create groups of entities from existing groups of superior dimensions
1354 1) extract all nodes from each group,
1355 2) combine all elements of specified dimension laying on these nodes.
1356 \param theGroups list of source groups
1357 \param theElemType dimension of elements
1358 \param theName name of new group
1359 \return pointer on new group
1361 //=============================================================================
1362 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1363 const SMESH::ListOfGroups& theGroups,
1364 SMESH::ElementType theElemType,
1365 const char* theName )
1366 throw (SALOME::SALOME_Exception)
1368 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1370 if ( !theName || !aMeshDS )
1371 return SMESH::SMESH_Group::_nil();
1373 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1377 // Create map of nodes from all groups
1379 NCollection_Map< int > aNodeMap;
1381 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1383 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1384 if ( CORBA::is_nil( aGrp ) )
1387 SMESH::ElementType aType = aGrp->GetType();
1388 if ( aType == SMESH::ALL )
1390 else if ( aType == SMESH::NODE )
1392 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1393 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1395 int aCurrId = aCurrIds[ i ];
1396 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1398 aNodeMap.Add( aNode->GetID() );
1403 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1404 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1406 int aCurrId = aCurrIds[ i ];
1407 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1410 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1411 while( aNodeIter->more() )
1413 const SMDS_MeshNode* aNode =
1414 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1416 aNodeMap.Add( aNode->GetID() );
1422 // Get result identifiers
1424 NCollection_Map< int > aResultIds;
1425 if ( theElemType == SMESH::NODE )
1427 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1428 for ( ; aNodeIter.More(); aNodeIter.Next() )
1429 aResultIds.Add( aNodeIter.Value() );
1433 // Create list of elements of given dimension constructed on the nodes
1434 NCollection_Map< int > anElemList;
1435 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1436 for ( ; aNodeIter.More(); aNodeIter.Next() )
1438 const SMDS_MeshElement* aNode =
1439 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1443 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1444 while( anElemIter->more() )
1446 const SMDS_MeshElement* anElem =
1447 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1448 if ( anElem && anElem->GetType() == anElemType )
1449 anElemList.Add( anElem->GetID() );
1453 // check whether all nodes of elements are present in nodes map
1454 NCollection_Map< int >::Iterator anIter( anElemList );
1455 for ( ; anIter.More(); anIter.Next() )
1457 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1462 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1463 while( aNodeIter->more() )
1465 const SMDS_MeshNode* aNode =
1466 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1467 if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1474 aResultIds.Add( anElem->GetID() );
1480 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1481 if ( aResGrp->_is_nil() )
1482 return SMESH::SMESH_Group::_nil();
1484 // Create array of identifiers
1485 SMESH::long_array_var aResIds = new SMESH::long_array;
1486 aResIds->length( aResultIds.Extent() );
1488 NCollection_Map< int >::Iterator aResIter( aResultIds );
1489 for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1490 aResIds[ i ] = aResIter.Value();
1491 aResGrp->Add( aResIds );
1493 // Remove strings corresponding to group creation
1494 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1495 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1496 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1498 // Update Python script
1500 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1501 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1503 return aResGrp._retn();
1507 return SMESH::SMESH_Group::_nil();
1511 //================================================================================
1513 * \brief Remember GEOM group data
1515 //================================================================================
1517 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1518 CORBA::Object_ptr theSmeshObj)
1520 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1523 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1524 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1525 if ( groupSO->_is_nil() )
1528 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1529 GEOM::GEOM_IGroupOperations_var groupOp =
1530 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1531 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1534 _geomGroupData.push_back( TGeomGroupData() );
1535 TGeomGroupData & groupData = _geomGroupData.back();
1537 CORBA::String_var entry = groupSO->GetID();
1538 groupData._groupEntry = entry.in();
1540 for ( int i = 0; i < ids->length(); ++i )
1541 groupData._indices.insert( ids[i] );
1543 groupData._smeshObject = theSmeshObj;
1546 //================================================================================
1548 * Remove GEOM group data relating to removed smesh object
1550 //================================================================================
1552 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1554 list<TGeomGroupData>::iterator
1555 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1556 for ( ; data != dataEnd; ++data ) {
1557 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1558 _geomGroupData.erase( data );
1564 //================================================================================
1566 * \brief Return new group contents if it has been changed and update group data
1568 //================================================================================
1570 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1572 TopoDS_Shape newShape;
1575 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1576 if ( study->_is_nil() ) return newShape; // means "not changed"
1577 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1578 if ( !groupSO->_is_nil() )
1580 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1581 if ( CORBA::is_nil( groupObj )) return newShape;
1582 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1584 // get indices of group items
1585 set<int> curIndices;
1586 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1587 GEOM::GEOM_IGroupOperations_var groupOp =
1588 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1589 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1590 for ( int i = 0; i < ids->length(); ++i )
1591 curIndices.insert( ids[i] );
1593 if ( groupData._indices == curIndices )
1594 return newShape; // group not changed
1597 groupData._indices = curIndices;
1599 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1600 if ( !geomClient ) return newShape;
1601 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1602 geomClient->RemoveShapeFromBuffer( groupIOR );
1603 newShape = _gen_i->GeomObjectToShape( geomGroup );
1606 if ( newShape.IsNull() ) {
1607 // geom group becomes empty - return empty compound
1608 TopoDS_Compound compound;
1609 BRep_Builder().MakeCompound(compound);
1610 newShape = compound;
1616 //=============================================================================
1618 * \brief Storage of shape and index used in CheckGeomGroupModif()
1620 //=============================================================================
1621 struct TIndexedShape {
1623 TopoDS_Shape _shape;
1624 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1627 //=============================================================================
1629 * \brief Update objects depending on changed geom groups
1631 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1632 * issue 0020210: Update of a smesh group after modification of the associated geom group
1634 //=============================================================================
1636 void SMESH_Mesh_i::CheckGeomGroupModif()
1638 if ( !_impl->HasShapeToMesh() ) return;
1640 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1641 if ( study->_is_nil() ) return;
1643 CORBA::Long nbEntities = NbNodes() + NbElements();
1645 // Check if group contents changed
1647 typedef map< string, TopoDS_Shape > TEntry2Geom;
1648 TEntry2Geom newGroupContents;
1650 list<TGeomGroupData>::iterator
1651 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1652 for ( ; data != dataEnd; ++data )
1654 pair< TEntry2Geom::iterator, bool > it_new =
1655 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1656 bool processedGroup = !it_new.second;
1657 TopoDS_Shape& newShape = it_new.first->second;
1658 if ( !processedGroup )
1659 newShape = newGroupShape( *data );
1660 if ( newShape.IsNull() )
1661 continue; // no changes
1663 if ( processedGroup ) { // update group indices
1664 list<TGeomGroupData>::iterator data2 = data;
1665 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1666 data->_indices = data2->_indices;
1669 // Update SMESH objects according to new GEOM group contents
1671 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1672 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1674 int oldID = submesh->GetId();
1675 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1677 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1679 // update hypotheses
1680 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1681 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1682 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1684 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1685 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1687 // care of submeshes
1688 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1689 int newID = newSubmesh->GetId();
1690 if ( newID != oldID ) {
1691 _mapSubMesh [ newID ] = newSubmesh;
1692 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1693 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1694 _mapSubMesh. erase(oldID);
1695 _mapSubMesh_i. erase(oldID);
1696 _mapSubMeshIor.erase(oldID);
1697 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1702 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1703 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1704 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1706 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1708 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1709 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1710 ds->SetShape( newShape );
1715 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1716 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1718 // Remove groups and submeshes basing on removed sub-shapes
1720 TopTools_MapOfShape newShapeMap;
1721 TopoDS_Iterator shapeIt( newShape );
1722 for ( ; shapeIt.More(); shapeIt.Next() )
1723 newShapeMap.Add( shapeIt.Value() );
1725 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1726 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1728 if ( newShapeMap.Contains( shapeIt.Value() ))
1730 TopTools_IndexedMapOfShape oldShapeMap;
1731 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1732 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1734 const TopoDS_Shape& oldShape = oldShapeMap(i);
1735 int oldInd = meshDS->ShapeToIndex( oldShape );
1737 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1738 if ( i_smIor != _mapSubMeshIor.end() ) {
1739 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1742 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1743 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1745 // check if a group bases on oldInd shape
1746 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1747 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1748 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1749 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1751 RemoveGroup( i_grp->second ); // several groups can base on same shape
1752 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1757 // Reassign hypotheses and update groups after setting the new shape to mesh
1759 // collect anassigned hypotheses
1760 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1761 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1762 TShapeHypList assignedHyps;
1763 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1765 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1766 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1767 if ( !hyps.empty() ) {
1768 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1769 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1770 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1773 // collect shapes supporting groups
1774 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1775 TShapeTypeList groupData;
1776 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1777 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1778 for ( ; grIt != groups.end(); ++grIt )
1780 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1782 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1784 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1785 _impl->ShapeToMesh( newShape );
1787 // reassign hypotheses
1788 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1789 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1791 TIndexedShape& geom = indS_hyps->first;
1792 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1793 int oldID = geom._index;
1794 int newID = meshDS->ShapeToIndex( geom._shape );
1797 if ( oldID == 1 ) { // main shape
1799 geom._shape = newShape;
1801 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1802 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1803 // care of submeshes
1804 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1805 if ( newID != oldID ) {
1806 _mapSubMesh [ newID ] = newSubmesh;
1807 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1808 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1809 _mapSubMesh. erase(oldID);
1810 _mapSubMesh_i. erase(oldID);
1811 _mapSubMeshIor.erase(oldID);
1812 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1816 TShapeTypeList::iterator geomType = groupData.begin();
1817 for ( ; geomType != groupData.end(); ++geomType )
1819 const TIndexedShape& geom = geomType->first;
1820 int oldID = geom._index;
1821 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1824 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1825 CORBA::String_var name = groupSO->GetName();
1827 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1829 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1830 group_i->changeLocalId( newID );
1833 break; // everything has been updated
1836 } // loop on group data
1840 CORBA::Long newNbEntities = NbNodes() + NbElements();
1841 list< SALOMEDS::SObject_var > soToUpdateIcons;
1842 if ( newNbEntities != nbEntities )
1844 // Add all SObjects with icons
1845 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1847 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1848 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1849 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1851 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1852 i_gr != _mapGroups.end(); ++i_gr ) // groups
1853 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1856 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1857 for ( ; so != soToUpdateIcons.end(); ++so )
1858 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1861 //=============================================================================
1863 * \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 );
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 //================================================================================
2234 * \brief Return true if the mesh has been edited since a last total re-compute
2235 * and those modifications may prevent successful partial re-compute
2237 //================================================================================
2239 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2241 Unexpect aCatch(SALOME_SalomeException);
2242 return _impl->HasModificationsToDiscard();
2245 //=============================================================================
2249 //=============================================================================
2250 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2252 Unexpect aCatch(SALOME_SalomeException);
2253 _impl->SetAutoColor(theAutoColor);
2256 //=============================================================================
2260 //=============================================================================
2261 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2263 Unexpect aCatch(SALOME_SalomeException);
2264 return _impl->GetAutoColor();
2268 //=============================================================================
2270 * Export in different formats
2272 //=============================================================================
2274 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2276 return _impl->HasDuplicatedGroupNamesMED();
2279 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2281 TCollection_AsciiString aFullName ((char*)file);
2282 OSD_Path aPath (aFullName);
2283 OSD_File aFile (aPath);
2284 if (aFile.Exists()) {
2285 // existing filesystem node
2286 if (aFile.KindOfFile() == OSD_FILE) {
2287 if (aFile.IsWriteable()) {
2292 if (aFile.Failed()) {
2293 TCollection_AsciiString msg ("File ");
2294 msg += aFullName + " cannot be replaced.";
2295 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2298 TCollection_AsciiString msg ("File ");
2299 msg += aFullName + " cannot be overwritten.";
2300 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2303 TCollection_AsciiString msg ("Location ");
2304 msg += aFullName + " is not a file.";
2305 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2308 // nonexisting file; check if it can be created
2310 aFile.Build(OSD_WriteOnly, OSD_Protection());
2311 if (aFile.Failed()) {
2312 TCollection_AsciiString msg ("You cannot create the file ");
2313 msg += aFullName + ". Check the directory existance and access rights.";
2314 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2322 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2323 CORBA::Boolean auto_groups,
2324 SMESH::MED_VERSION theVersion,
2325 CORBA::Boolean overwrite)
2326 throw(SALOME::SALOME_Exception)
2328 Unexpect aCatch(SALOME_SalomeException);
2331 PrepareForWriting(file, overwrite);
2332 const char* aMeshName = "Mesh";
2333 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2334 if ( !aStudy->_is_nil() ) {
2335 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2336 if ( !aMeshSO->_is_nil() ) {
2337 aMeshName = aMeshSO->GetName();
2338 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2339 if ( !aStudy->GetProperties()->IsLocked() )
2341 SALOMEDS::GenericAttribute_var anAttr;
2342 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2343 SALOMEDS::AttributeExternalFileDef_var aFileName;
2344 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2345 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2346 ASSERT(!aFileName->_is_nil());
2347 aFileName->SetValue(file);
2348 SALOMEDS::AttributeFileType_var aFileType;
2349 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2350 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2351 ASSERT(!aFileType->_is_nil());
2352 aFileType->SetValue("FICHIERMED");
2356 // Update Python script
2357 // set name of mesh before export
2358 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2360 // check names of groups
2363 TPythonDump() << _this() << ".ExportToMEDX( '"
2364 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2366 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2369 void SMESH_Mesh_i::ExportToMED (const char* file,
2370 CORBA::Boolean auto_groups,
2371 SMESH::MED_VERSION theVersion)
2372 throw(SALOME::SALOME_Exception)
2374 ExportToMEDX(file,auto_groups,theVersion,true);
2377 void SMESH_Mesh_i::ExportMED (const char* file,
2378 CORBA::Boolean auto_groups)
2379 throw(SALOME::SALOME_Exception)
2381 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2384 void SMESH_Mesh_i::ExportDAT (const char *file)
2385 throw(SALOME::SALOME_Exception)
2387 Unexpect aCatch(SALOME_SalomeException);
2389 // Update Python script
2390 // check names of groups
2392 TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
2395 PrepareForWriting(file);
2396 _impl->ExportDAT(file);
2399 void SMESH_Mesh_i::ExportUNV (const char *file)
2400 throw(SALOME::SALOME_Exception)
2402 Unexpect aCatch(SALOME_SalomeException);
2404 // Update Python script
2405 // check names of groups
2407 TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
2410 PrepareForWriting(file);
2411 _impl->ExportUNV(file);
2414 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2415 throw(SALOME::SALOME_Exception)
2417 Unexpect aCatch(SALOME_SalomeException);
2419 // Update Python script
2420 // check names of groups
2422 TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
2425 PrepareForWriting(file);
2426 _impl->ExportSTL(file, isascii);
2429 //=============================================================================
2433 //=============================================================================
2435 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2437 Unexpect aCatch(SALOME_SalomeException);
2438 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2439 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2440 return aMesh._retn();
2443 //=============================================================================
2447 //=============================================================================
2448 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2450 Unexpect aCatch(SALOME_SalomeException);
2451 return _impl->NbNodes();
2454 //=============================================================================
2458 //=============================================================================
2459 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2461 Unexpect aCatch(SALOME_SalomeException);
2462 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2465 //=============================================================================
2469 //=============================================================================
2470 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2472 Unexpect aCatch(SALOME_SalomeException);
2473 return _impl->Nb0DElements();
2476 //=============================================================================
2480 //=============================================================================
2481 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2483 Unexpect aCatch(SALOME_SalomeException);
2484 return _impl->NbEdges();
2487 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2488 throw(SALOME::SALOME_Exception)
2490 Unexpect aCatch(SALOME_SalomeException);
2491 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2494 //=============================================================================
2498 //=============================================================================
2499 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2501 Unexpect aCatch(SALOME_SalomeException);
2502 return _impl->NbFaces();
2505 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2507 Unexpect aCatch(SALOME_SalomeException);
2508 return _impl->NbTriangles();
2511 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2513 Unexpect aCatch(SALOME_SalomeException);
2514 return _impl->NbQuadrangles();
2517 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2519 Unexpect aCatch(SALOME_SalomeException);
2520 return _impl->NbPolygons();
2523 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2524 throw(SALOME::SALOME_Exception)
2526 Unexpect aCatch(SALOME_SalomeException);
2527 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2530 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2531 throw(SALOME::SALOME_Exception)
2533 Unexpect aCatch(SALOME_SalomeException);
2534 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2537 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2538 throw(SALOME::SALOME_Exception)
2540 Unexpect aCatch(SALOME_SalomeException);
2541 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2544 //=============================================================================
2548 //=============================================================================
2549 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2551 Unexpect aCatch(SALOME_SalomeException);
2552 return _impl->NbVolumes();
2555 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2557 Unexpect aCatch(SALOME_SalomeException);
2558 return _impl->NbTetras();
2561 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2563 Unexpect aCatch(SALOME_SalomeException);
2564 return _impl->NbHexas();
2567 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2569 Unexpect aCatch(SALOME_SalomeException);
2570 return _impl->NbPyramids();
2573 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2575 Unexpect aCatch(SALOME_SalomeException);
2576 return _impl->NbPrisms();
2579 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2581 Unexpect aCatch(SALOME_SalomeException);
2582 return _impl->NbPolyhedrons();
2585 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2586 throw(SALOME::SALOME_Exception)
2588 Unexpect aCatch(SALOME_SalomeException);
2589 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2592 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2593 throw(SALOME::SALOME_Exception)
2595 Unexpect aCatch(SALOME_SalomeException);
2596 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2599 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2600 throw(SALOME::SALOME_Exception)
2602 Unexpect aCatch(SALOME_SalomeException);
2603 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2606 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2607 throw(SALOME::SALOME_Exception)
2609 Unexpect aCatch(SALOME_SalomeException);
2610 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2613 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2614 throw(SALOME::SALOME_Exception)
2616 Unexpect aCatch(SALOME_SalomeException);
2617 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2620 //=============================================================================
2624 //=============================================================================
2625 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2627 Unexpect aCatch(SALOME_SalomeException);
2628 return _mapSubMesh_i.size();
2631 //=============================================================================
2635 //=============================================================================
2636 char* SMESH_Mesh_i::Dump()
2640 return CORBA::string_dup( os.str().c_str() );
2643 //=============================================================================
2647 //=============================================================================
2648 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2650 // SMESH::long_array_var aResult = new SMESH::long_array();
2651 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2652 // int aMinId = aSMESHDS_Mesh->MinElementID();
2653 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2655 // aResult->length(aMaxId - aMinId + 1);
2657 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2658 // aResult[i++] = id;
2660 // return aResult._retn();
2662 return GetElementsId();
2665 //=============================================================================
2669 //=============================================================================
2671 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2672 throw (SALOME::SALOME_Exception)
2674 Unexpect aCatch(SALOME_SalomeException);
2675 MESSAGE("SMESH_Mesh_i::GetElementsId");
2676 SMESH::long_array_var aResult = new SMESH::long_array();
2677 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2679 if ( aSMESHDS_Mesh == NULL )
2680 return aResult._retn();
2682 long nbElements = NbElements();
2683 aResult->length( nbElements );
2684 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2685 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2686 aResult[i] = anIt->next()->GetID();
2688 return aResult._retn();
2692 //=============================================================================
2696 //=============================================================================
2698 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2699 throw (SALOME::SALOME_Exception)
2701 Unexpect aCatch(SALOME_SalomeException);
2702 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2703 SMESH::long_array_var aResult = new SMESH::long_array();
2704 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2706 if ( aSMESHDS_Mesh == NULL )
2707 return aResult._retn();
2709 long nbElements = NbElements();
2711 // No sense in returning ids of elements along with ids of nodes:
2712 // when theElemType == SMESH::ALL, return node ids only if
2713 // there are no elements
2714 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2715 return GetNodesId();
2717 aResult->length( nbElements );
2721 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2722 while ( i < nbElements && anIt->more() ) {
2723 const SMDS_MeshElement* anElem = anIt->next();
2724 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2725 aResult[i++] = anElem->GetID();
2728 aResult->length( i );
2730 return aResult._retn();
2733 //=============================================================================
2737 //=============================================================================
2739 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2740 throw (SALOME::SALOME_Exception)
2742 Unexpect aCatch(SALOME_SalomeException);
2743 MESSAGE("SMESH_subMesh_i::GetNodesId");
2744 SMESH::long_array_var aResult = new SMESH::long_array();
2745 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2747 if ( aSMESHDS_Mesh == NULL )
2748 return aResult._retn();
2750 long nbNodes = NbNodes();
2751 aResult->length( nbNodes );
2752 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2753 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2754 aResult[i] = anIt->next()->GetID();
2756 return aResult._retn();
2759 //=============================================================================
2763 //=============================================================================
2765 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2766 throw (SALOME::SALOME_Exception)
2768 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2771 //=============================================================================
2775 //=============================================================================
2777 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2778 throw (SALOME::SALOME_Exception)
2780 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2782 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2784 return ( SMESH::EntityType ) e->GetEntityType();
2787 //=============================================================================
2789 * Returns ID of elements for given submesh
2791 //=============================================================================
2792 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2793 throw (SALOME::SALOME_Exception)
2795 SMESH::long_array_var aResult = new SMESH::long_array();
2797 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2798 if(!SM) return aResult._retn();
2800 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2801 if(!SDSM) return aResult._retn();
2803 aResult->length(SDSM->NbElements());
2805 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2807 while ( eIt->more() ) {
2808 aResult[i++] = eIt->next()->GetID();
2811 return aResult._retn();
2815 //=============================================================================
2817 * Returns ID of nodes for given submesh
2818 * If param all==true - returns all nodes, else -
2819 * returns only nodes on shapes.
2821 //=============================================================================
2822 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2823 throw (SALOME::SALOME_Exception)
2825 SMESH::long_array_var aResult = new SMESH::long_array();
2827 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2828 if(!SM) return aResult._retn();
2830 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2831 if(!SDSM) return aResult._retn();
2834 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2835 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2836 while ( nIt->more() ) {
2837 const SMDS_MeshNode* elem = nIt->next();
2838 theElems.insert( elem->GetID() );
2841 else { // all nodes of submesh elements
2842 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2843 while ( eIt->more() ) {
2844 const SMDS_MeshElement* anElem = eIt->next();
2845 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2846 while ( nIt->more() ) {
2847 const SMDS_MeshElement* elem = nIt->next();
2848 theElems.insert( elem->GetID() );
2853 aResult->length(theElems.size());
2854 set<int>::iterator itElem;
2856 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2857 aResult[i++] = *itElem;
2859 return aResult._retn();
2863 //=============================================================================
2865 * Returns type of elements for given submesh
2867 //=============================================================================
2868 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2869 throw (SALOME::SALOME_Exception)
2871 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2872 if(!SM) return SMESH::ALL;
2874 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2875 if(!SDSM) return SMESH::ALL;
2877 if(SDSM->NbElements()==0)
2878 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2880 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2881 const SMDS_MeshElement* anElem = eIt->next();
2882 return ( SMESH::ElementType ) anElem->GetType();
2886 //=============================================================================
2890 //=============================================================================
2892 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2894 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2896 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2901 //=============================================================================
2903 * Get XYZ coordinates of node as list of double
2904 * If there is not node for given ID - returns empty list
2906 //=============================================================================
2908 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2910 SMESH::double_array_var aResult = new SMESH::double_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();
2922 aResult[0] = aNode->X();
2923 aResult[1] = aNode->Y();
2924 aResult[2] = aNode->Z();
2925 return aResult._retn();
2929 //=============================================================================
2931 * For given node returns list of IDs of inverse elements
2932 * If there is not node for given ID - returns empty list
2934 //=============================================================================
2936 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2938 SMESH::long_array_var aResult = new SMESH::long_array();
2939 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2940 if ( aSMESHDS_Mesh == NULL )
2941 return aResult._retn();
2944 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2946 return aResult._retn();
2948 // find inverse elements
2949 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2950 TColStd_SequenceOfInteger IDs;
2951 while(eIt->more()) {
2952 const SMDS_MeshElement* elem = eIt->next();
2953 IDs.Append(elem->GetID());
2955 if(IDs.Length()>0) {
2956 aResult->length(IDs.Length());
2958 for(; i<=IDs.Length(); i++) {
2959 aResult[i-1] = IDs.Value(i);
2962 return aResult._retn();
2965 //=============================================================================
2967 * \brief Return position of a node on shape
2969 //=============================================================================
2971 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
2973 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
2974 aNodePosition->shapeID = 0;
2975 aNodePosition->shapeType = GEOM::SHAPE;
2977 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
2978 if ( !mesh ) return aNodePosition;
2980 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
2982 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
2984 aNodePosition->shapeID = pos->GetShapeId();
2985 switch ( pos->GetTypeOfPosition() ) {
2987 aNodePosition->shapeType = GEOM::EDGE;
2988 aNodePosition->params.length(1);
2989 aNodePosition->params[0] =
2990 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
2993 aNodePosition->shapeType = GEOM::FACE;
2994 aNodePosition->params.length(2);
2995 aNodePosition->params[0] =
2996 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
2997 aNodePosition->params[1] =
2998 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
3000 case SMDS_TOP_VERTEX:
3001 aNodePosition->shapeType = GEOM::VERTEX;
3003 case SMDS_TOP_3DSPACE:
3004 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3005 aNodePosition->shapeType = GEOM::SOLID;
3006 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3007 aNodePosition->shapeType = GEOM::SHELL;
3013 return aNodePosition;
3016 //=============================================================================
3018 * If given element is node returns IDs of shape from position
3019 * If there is not node for given ID - returns -1
3021 //=============================================================================
3023 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3025 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3026 if ( aSMESHDS_Mesh == NULL )
3030 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3032 SMDS_PositionPtr pos = aNode->GetPosition();
3036 return pos->GetShapeId();
3043 //=============================================================================
3045 * For given element returns ID of result shape after
3046 * ::FindShape() from SMESH_MeshEditor
3047 * If there is not element for given ID - returns -1
3049 //=============================================================================
3051 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3053 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3054 if ( aSMESHDS_Mesh == NULL )
3057 // try to find element
3058 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3062 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3063 ::SMESH_MeshEditor aMeshEditor(_impl);
3064 int index = aMeshEditor.FindShape( elem );
3072 //=============================================================================
3074 * Returns number of nodes for given element
3075 * If there is not element for given ID - returns -1
3077 //=============================================================================
3079 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3081 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3082 if ( aSMESHDS_Mesh == NULL ) return -1;
3083 // try to find element
3084 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3085 if(!elem) return -1;
3086 return elem->NbNodes();
3090 //=============================================================================
3092 * Returns ID of node by given index for given element
3093 * If there is not element for given ID - returns -1
3094 * If there is not node for given index - returns -2
3096 //=============================================================================
3098 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3100 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3101 if ( aSMESHDS_Mesh == NULL ) return -1;
3102 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3103 if(!elem) return -1;
3104 if( index>=elem->NbNodes() || index<0 ) return -1;
3105 return elem->GetNode(index)->GetID();
3108 //=============================================================================
3110 * Returns IDs of nodes of given element
3112 //=============================================================================
3114 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3116 SMESH::long_array_var aResult = new SMESH::long_array();
3117 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3119 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3121 aResult->length( elem->NbNodes() );
3122 for ( int i = 0; i < elem->NbNodes(); ++i )
3123 aResult[ i ] = elem->GetNode( i )->GetID();
3126 return aResult._retn();
3129 //=============================================================================
3131 * Returns true if given node is medium node
3132 * in given quadratic element
3134 //=============================================================================
3136 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3138 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3139 if ( aSMESHDS_Mesh == NULL ) return false;
3141 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3142 if(!aNode) return false;
3143 // try to find element
3144 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3145 if(!elem) return false;
3147 return elem->IsMediumNode(aNode);
3151 //=============================================================================
3153 * Returns true if given node is medium node
3154 * in one of quadratic elements
3156 //=============================================================================
3158 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3159 SMESH::ElementType theElemType)
3161 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3162 if ( aSMESHDS_Mesh == NULL ) return false;
3165 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3166 if(!aNode) return false;
3168 SMESH_MesherHelper aHelper( *(_impl) );
3170 SMDSAbs_ElementType aType;
3171 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3172 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3173 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3174 else aType = SMDSAbs_All;
3176 return aHelper.IsMedium(aNode,aType);
3180 //=============================================================================
3182 * Returns number of edges for given element
3184 //=============================================================================
3186 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3188 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3189 if ( aSMESHDS_Mesh == NULL ) return -1;
3190 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3191 if(!elem) return -1;
3192 return elem->NbEdges();
3196 //=============================================================================
3198 * Returns number of faces for given element
3200 //=============================================================================
3202 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3204 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3205 if ( aSMESHDS_Mesh == NULL ) return -1;
3206 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3207 if(!elem) return -1;
3208 return elem->NbFaces();
3211 //=======================================================================
3212 //function : GetElemFaceNodes
3213 //purpose : Returns nodes of given face (counted from zero) for given element.
3214 //=======================================================================
3216 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3217 CORBA::Short faceIndex)
3219 SMESH::long_array_var aResult = new SMESH::long_array();
3220 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3222 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3224 SMDS_VolumeTool vtool( elem );
3225 if ( faceIndex < vtool.NbFaces() )
3227 aResult->length( vtool.NbFaceNodes( faceIndex ));
3228 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3229 for ( int i = 0; i < aResult->length(); ++i )
3230 aResult[ i ] = nn[ i ]->GetID();
3234 return aResult._retn();
3237 //=======================================================================
3238 //function : FindElementByNodes
3239 //purpose : Returns an element based on all given nodes.
3240 //=======================================================================
3242 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3244 CORBA::Long elemID(0);
3245 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3247 vector< const SMDS_MeshNode * > nn( nodes.length() );
3248 for ( int i = 0; i < nodes.length(); ++i )
3249 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3252 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3253 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3254 _impl->NbFaces( ORDER_QUADRATIC ) ||
3255 _impl->NbVolumes( ORDER_QUADRATIC )))
3256 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3258 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3263 //=============================================================================
3265 * Returns true if given element is polygon
3267 //=============================================================================
3269 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3271 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3272 if ( aSMESHDS_Mesh == NULL ) return false;
3273 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3274 if(!elem) return false;
3275 return elem->IsPoly();
3279 //=============================================================================
3281 * Returns true if given element is quadratic
3283 //=============================================================================
3285 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3287 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3288 if ( aSMESHDS_Mesh == NULL ) return false;
3289 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3290 if(!elem) return false;
3291 return elem->IsQuadratic();
3295 //=============================================================================
3297 * Returns bary center for given element
3299 //=============================================================================
3301 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3303 SMESH::double_array_var aResult = new SMESH::double_array();
3304 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3305 if ( aSMESHDS_Mesh == NULL )
3306 return aResult._retn();
3308 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3310 return aResult._retn();
3312 if(elem->GetType()==SMDSAbs_Volume) {
3313 SMDS_VolumeTool aTool;
3314 if(aTool.Set(elem)) {
3316 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3321 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3323 double x=0., y=0., z=0.;
3324 for(; anIt->more(); ) {
3326 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3340 return aResult._retn();
3344 //=============================================================================
3346 * Create and publish group servants if any groups were imported or created anyhow
3348 //=============================================================================
3350 void SMESH_Mesh_i::CreateGroupServants()
3352 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3354 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3355 while ( groupIt->more() )
3357 ::SMESH_Group* group = groupIt->next();
3358 int anId = group->GetGroupDS()->GetID();
3360 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3361 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3364 SMESH_GroupBase_i* aGroupImpl;
3366 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3367 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3369 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3370 shape = groupOnGeom->GetShape();
3373 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3376 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3377 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3378 aGroupImpl->Register();
3380 SMESH::SMESH_GroupBase_var groupVar =
3381 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3382 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3384 // register CORBA object for persistence
3385 int nextId = _gen_i->RegisterObject( groupVar );
3386 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3388 // publishing of the groups in the study
3389 if ( !aStudy->_is_nil() ) {
3390 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3391 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3396 //=============================================================================
3398 * \brief Return groups cantained in _mapGroups by their IDs
3400 //=============================================================================
3402 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3404 int nbGroups = groupIDs.size();
3405 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3406 aList->length( nbGroups );
3408 list<int>::const_iterator ids = groupIDs.begin();
3409 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3411 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3412 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3413 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3415 aList->length( nbGroups );
3416 return aList._retn();
3419 //=============================================================================
3421 * \brief Return information about imported file
3423 //=============================================================================
3425 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3427 SALOME_MED::MedFileInfo_var res( myFileInfo );
3428 if ( !res.operator->() ) {
3429 res = new SALOME_MED::MedFileInfo;
3431 res->fileSize = res->major = res->minor = res->release = -1;
3436 //=============================================================================
3438 * \brief Check and correct names of mesh groups
3440 //=============================================================================
3442 void SMESH_Mesh_i::checkGroupNames()
3444 int nbGrp = NbGroups();
3448 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3449 if ( aStudy->_is_nil() )
3450 return; // nothing to do
3452 SMESH::ListOfGroups* grpList = 0;
3453 // avoid dump of "GetGroups"
3455 // store python dump into a local variable inside local scope
3456 SMESH::TPythonDump pDump; // do not delete this line of code
3457 grpList = GetGroups();
3460 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3461 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3464 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3465 if ( aGrpSO->_is_nil() )
3467 // correct name of the mesh group if necessary
3468 const char* guiName = aGrpSO->GetName();
3469 if ( strcmp(guiName, aGrp->GetName()) )
3470 aGrp->SetName( guiName );
3474 //=============================================================================
3476 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3478 //=============================================================================
3479 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3481 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3482 CORBA::string_dup(theParameters));
3485 //=============================================================================
3487 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3489 //=============================================================================
3490 char* SMESH_Mesh_i::GetParameters()
3492 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3493 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3496 //=============================================================================
3498 * \brief Returns list of notebook variables used for last Mesh operation
3500 //=============================================================================
3501 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3503 SMESH::string_array_var aResult = new SMESH::string_array();
3504 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3506 char *aParameters = GetParameters();
3507 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3508 if(!aStudy->_is_nil()) {
3509 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3510 if(aSections->length() > 0) {
3511 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3512 aResult->length(aVars.length());
3513 for(int i = 0;i < aVars.length();i++)
3514 aResult[i] = CORBA::string_dup( aVars[i]);
3518 return aResult._retn();
3521 //=============================================================================
3523 * \brief Returns statistic of mesh elements
3525 //=============================================================================
3526 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3528 SMESH::long_array_var aRes = new SMESH::long_array();
3529 aRes->length(SMESH::Entity_Last);
3530 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3532 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3534 return aRes._retn();
3535 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3536 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3537 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3538 return aRes._retn();
3541 //=============================================================================
3543 * \brief Collect statistic of mesh elements given by iterator
3545 //=============================================================================
3546 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3547 SMESH::long_array& theInfo)
3549 if (!theItr) return;
3550 while (theItr->more())
3551 theInfo[ theItr->next()->GetEntityType() ]++;
3554 //=============================================================================
3556 * \brief mapping of mesh dimension into shape type
3558 //=============================================================================
3559 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3561 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3563 case 0: aType = TopAbs_VERTEX; break;
3564 case 1: aType = TopAbs_EDGE; break;
3565 case 2: aType = TopAbs_FACE; break;
3567 default:aType = TopAbs_SOLID; break;
3572 //=============================================================================
3574 * \brief Internal structure used to find concurent submeshes
3576 * It represents a pair < submesh, concurent dimension >, where
3577 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3578 * with another submesh. In other words, it is dimension of a hypothesis assigned
3581 //=============================================================================
3587 int _dim; //!< a dimension the algo can build (concurrent dimension)
3588 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3589 TopTools_MapOfShape _shapeMap;
3590 SMESH_subMesh* _subMesh;
3591 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3594 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3596 const TopoDS_Shape& theShape)
3598 _subMesh = (SMESH_subMesh*)theSubMesh;
3599 SetShape( theDim, theShape );
3603 void SetShape(const int theDim,
3604 const TopoDS_Shape& theShape)
3607 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3608 if (_dim >= _ownDim)
3609 _shapeMap.Add( theShape );
3611 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3612 for( ; anExp.More(); anExp.Next() )
3613 _shapeMap.Add( anExp.Current() );
3617 //! Check sharing of sub shapes
3618 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3619 const TopTools_MapOfShape& theToFind,
3620 const TopAbs_ShapeEnum theType)
3622 bool isShared = false;
3623 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3624 for (; !isShared && anItr.More(); anItr.Next() ) {
3625 const TopoDS_Shape aSubSh = anItr.Key();
3626 // check for case when concurrent dimensions are same
3627 isShared = theToFind.Contains( aSubSh );
3628 // check for subshape with concurrent dimension
3629 TopExp_Explorer anExp( aSubSh, theType );
3630 for ( ; !isShared && anExp.More(); anExp.Next() )
3631 isShared = theToFind.Contains( anExp.Current() );
3636 //! check algorithms
3637 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3638 const SMESHDS_Hypothesis* theA2)
3640 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3641 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3642 return false; // one of the hypothesis is not algorithm
3643 // check algorithm names (should be equal)
3644 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3648 //! Check if subshape hypotheses are concurrent
3649 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3651 if ( _subMesh == theOther->_subMesh )
3652 return false; // same subshape - should not be
3654 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3655 // any of the two submeshes is not on COMPOUND shape )
3656 // -> no concurrency
3657 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3658 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3659 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3662 // bool checkSubShape = ( _dim >= theOther->_dim )
3663 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3664 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3665 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3666 if ( !checkSubShape )
3669 // check algorithms to be same
3670 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3671 return true; // different algorithms
3673 // check hypothesises for concurrence (skip first as algorithm)
3675 // pointers should be same, becase it is referenes from mesh hypothesis partition
3676 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3677 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3678 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3679 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3681 // the submeshes are concurrent if their algorithms has different parameters
3682 return nbSame != theOther->_hypothesises.size() - 1;
3685 }; // end of SMESH_DimHyp
3687 typedef list<SMESH_DimHyp*> TDimHypList;
3689 static void addDimHypInstance(const int theDim,
3690 const TopoDS_Shape& theShape,
3691 const SMESH_Algo* theAlgo,
3692 const SMESH_subMesh* theSubMesh,
3693 const list <const SMESHDS_Hypothesis*>& theHypList,
3694 TDimHypList* theDimHypListArr )
3696 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3697 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3698 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3699 listOfdimHyp.push_back( dimHyp );
3702 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3703 dimHyp->_hypothesises.push_front(theAlgo);
3704 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3705 for( ; hypIt != theHypList.end(); hypIt++ )
3706 dimHyp->_hypothesises.push_back( *hypIt );
3709 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3710 const TDimHypList& theListOfDimHyp,
3711 TListOfInt& theListOfConcurr )
3713 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3714 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3715 const SMESH_DimHyp* curDimHyp = *rIt;
3716 if ( curDimHyp == theDimHyp )
3717 break; // meet own dimHyp pointer in same dimension
3718 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3719 if ( find( theListOfConcurr.begin(),
3720 theListOfConcurr.end(),
3721 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3722 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3726 static void unionLists(TListOfInt& theListOfId,
3727 TListOfListOfInt& theListOfListOfId,
3730 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3731 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3733 continue; //skip already treated lists
3734 // check if other list has any same submesh object
3735 TListOfInt& otherListOfId = *it;
3736 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3737 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3740 // union two lists (from source into target)
3741 TListOfInt::iterator it2 = otherListOfId.begin();
3742 for ( ; it2 != otherListOfId.end(); it2++ ) {
3743 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3744 theListOfId.push_back(*it2);
3746 // clear source list
3747 otherListOfId.clear();
3751 //! free memory allocated for dimension-hypothesis objects
3752 static void removeDimHyps( TDimHypList* theArrOfList )
3754 for (int i = 0; i < 4; i++ ) {
3755 TDimHypList& listOfdimHyp = theArrOfList[i];
3756 TDimHypList::const_iterator it = listOfdimHyp.begin();
3757 for ( ; it != listOfdimHyp.end(); it++ )
3762 //=============================================================================
3764 * \brief Return submesh objects list in meshing order
3766 //=============================================================================
3768 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3770 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3772 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3774 return aResult._retn();
3776 ::SMESH_Mesh& mesh = GetImpl();
3777 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3778 if ( !anOrder.size() ) {
3780 // collect submeshes detecting concurrent algorithms and hypothesises
3781 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3783 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3784 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3785 ::SMESH_subMesh* sm = (*i_sm).second;
3787 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3789 // list of assigned hypothesises
3790 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3791 // Find out dimensions where the submesh can be concurrent.
3792 // We define the dimensions by algo of each of hypotheses in hypList
3793 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3794 for( ; hypIt != hypList.end(); hypIt++ ) {
3795 SMESH_Algo* anAlgo = 0;
3796 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3797 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3798 // hyp it-self is algo
3799 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3801 // try to find algorithm with help of subshapes
3802 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3803 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3804 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3807 continue; // no assigned algorithm to current submesh
3809 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3810 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3812 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3813 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3814 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3816 } // end iterations on submesh
3818 // iterate on created dimension-hypotheses and check for concurrents
3819 for ( int i = 0; i < 4; i++ ) {
3820 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3821 // check for concurrents in own and other dimensions (step-by-step)
3822 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3823 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3824 const SMESH_DimHyp* dimHyp = *dhIt;
3825 TListOfInt listOfConcurr;
3826 // looking for concurrents and collect into own list
3827 for ( int j = i; j < 4; j++ )
3828 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3829 // check if any concurrents found
3830 if ( listOfConcurr.size() > 0 ) {
3831 // add own submesh to list of concurrent
3832 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3833 anOrder.push_back( listOfConcurr );
3838 removeDimHyps(dimHypListArr);
3840 // now, minimise the number of concurrent groups
3841 // Here we assume that lists of submhes can has same submesh
3842 // in case of multi-dimension algorithms, as result
3843 // list with common submesh have to be union into one list
3845 TListOfListOfInt::iterator listIt = anOrder.begin();
3846 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3847 unionLists( *listIt, anOrder, listIndx + 1 );
3849 // convert submesh ids into interface instances
3850 // and dump command into python
3851 convertMeshOrder( anOrder, aResult, true );
3853 return aResult._retn();
3856 //=============================================================================
3858 * \brief find common submeshes with given submesh
3859 * \param theSubMeshList list of already collected submesh to check
3860 * \param theSubMesh given submesh to intersect with other
3861 * \param theCommonSubMeshes collected common submeshes
3863 //=============================================================================
3865 static void findCommonSubMesh
3866 (list<const SMESH_subMesh*>& theSubMeshList,
3867 const SMESH_subMesh* theSubMesh,
3868 set<const SMESH_subMesh*>& theCommon )
3872 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
3873 for ( ; it != theSubMeshList.end(); it++ )
3874 theSubMesh->FindIntersection( *it, theCommon );
3875 theSubMeshList.push_back( theSubMesh );
3876 //theCommon.insert( theSubMesh );
3879 //=============================================================================
3881 * \brief Set submesh object order
3882 * \param theSubMeshArray submesh array order
3884 //=============================================================================
3886 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
3889 ::SMESH_Mesh& mesh = GetImpl();
3891 TPythonDump aPythonDump; // prevent dump of called methods
3892 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
3894 TListOfListOfInt subMeshOrder;
3895 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
3897 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
3898 TListOfInt subMeshIds;
3899 aPythonDump << "[ ";
3900 // Collect subMeshes which should be clear
3901 // do it list-by-list, because modification of submesh order
3902 // take effect between concurrent submeshes only
3903 set<const SMESH_subMesh*> subMeshToClear;
3904 list<const SMESH_subMesh*> subMeshList;
3905 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
3907 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
3909 aPythonDump << ", ";
3910 aPythonDump << subMesh;
3911 subMeshIds.push_back( subMesh->GetId() );
3912 // detect common parts of submeshes
3913 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
3914 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
3916 aPythonDump << " ]";
3917 subMeshOrder.push_back( subMeshIds );
3919 // clear collected submeshes
3920 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
3921 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
3922 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
3924 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
3925 // ClearSubMesh( *clrIt );
3928 aPythonDump << " ])";
3930 mesh.SetMeshOrder( subMeshOrder );
3936 //=============================================================================
3938 * \brief Convert submesh ids into submesh interfaces
3940 //=============================================================================
3942 void SMESH_Mesh_i::convertMeshOrder
3943 (const TListOfListOfInt& theIdsOrder,
3944 SMESH::submesh_array_array& theResOrder,
3945 const bool theIsDump)
3947 int nbSet = theIdsOrder.size();
3948 TPythonDump aPythonDump; // prevent dump of called methods
3950 aPythonDump << "[ ";
3951 theResOrder.length(nbSet);
3952 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
3954 for( ; it != theIdsOrder.end(); it++ ) {
3955 // translate submesh identificators into submesh objects
3956 // takeing into account real number of concurrent lists
3957 const TListOfInt& aSubOrder = (*it);
3958 if (!aSubOrder.size())
3961 aPythonDump << "[ ";
3962 // convert shape indeces into interfaces
3963 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
3964 aResSubSet->length(aSubOrder.size());
3965 TListOfInt::const_iterator subIt = aSubOrder.begin();
3966 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
3967 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
3969 SMESH::SMESH_subMesh_var subMesh =
3970 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
3973 aPythonDump << ", ";
3974 aPythonDump << subMesh;
3976 aResSubSet[ j++ ] = subMesh;
3979 aPythonDump << " ]";
3980 theResOrder[ listIndx++ ] = aResSubSet;
3982 // correct number of lists
3983 theResOrder.length( listIndx );
3986 // finilise python dump
3987 aPythonDump << " ]";
3988 aPythonDump << " = " << _this() << ".GetMeshOrder()";