1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
23 // File : SMESH_Mesh_i.cxx
24 // Author : Paul RASCLE, EDF
27 #include "SMESH_Mesh_i.hxx"
29 #include "SMESH_Filter_i.hxx"
30 #include "SMESH_Gen_i.hxx"
31 #include "SMESH_Group_i.hxx"
32 #include "SMESH_MEDMesh_i.hxx"
33 #include "SMESH_MeshEditor_i.hxx"
34 #include "SMESH_PythonDump.hxx"
35 #include "SMESH_subMesh_i.hxx"
37 #include "DriverMED_R_SMESHDS_Mesh.h"
38 #include "DriverMED_W_SMESHDS_Mesh.h"
39 #include "SMDS_VolumeTool.hxx"
40 #include "SMDS_ElemIterator.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_GroupOnGeom.hxx"
44 #include "SMESH_Group.hxx"
45 #include "SMESH_MeshEditor.hxx"
46 #include "SMESH_MesherHelper.hxx"
47 #include "SMDS_EdgePosition.hxx"
48 #include "SMDS_FacePosition.hxx"
51 #include "SALOME_NamingService.hxx"
52 #include "Utils_CorbaException.hxx"
53 #include "Utils_ExceptHandlers.hxx"
54 #include "Utils_SINGLETON.hxx"
55 #include "utilities.h"
56 #include "GEOMImpl_Types.hxx"
59 #include <BRep_Builder.hxx>
60 #include <OSD_Directory.hxx>
61 #include <OSD_File.hxx>
62 #include <OSD_Path.hxx>
63 #include <OSD_Protection.hxx>
64 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
65 #include <TColStd_MapOfInteger.hxx>
66 #include <TColStd_SequenceOfInteger.hxx>
67 #include <TCollection_AsciiString.hxx>
69 #include <TopExp_Explorer.hxx>
70 #include <TopoDS_Compound.hxx>
79 static int MYDEBUG = 0;
81 static int MYDEBUG = 0;
85 using SMESH::TPythonDump;
87 int SMESH_Mesh_i::myIdGenerator = 0;
91 //=============================================================================
95 //=============================================================================
97 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
100 : SALOME::GenericObj_i( thePOA )
102 MESSAGE("SMESH_Mesh_i");
105 _id = myIdGenerator++;
109 //=============================================================================
113 //=============================================================================
115 SMESH_Mesh_i::~SMESH_Mesh_i()
117 INFOS("~SMESH_Mesh_i");
118 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
119 for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
120 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
122 // this method is colled from destructor of group (PAL6331)
123 //_impl->RemoveGroup( aGroup->GetLocalID() );
132 //=============================================================================
136 * Associates <this> mesh with <theShape> and puts a reference
137 * to <theShape> into the current study;
138 * the previous shape is substituted by the new one.
140 //=============================================================================
142 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
143 throw (SALOME::SALOME_Exception)
145 Unexpect aCatch(SALOME_SalomeException);
147 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
149 catch(SALOME_Exception & S_ex) {
150 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
152 // to track changes of GEOM groups
153 addGeomGroupData( theShapeObject, _this() );
156 //================================================================================
158 * \brief return true if mesh has a shape to build a shape on
160 //================================================================================
162 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
163 throw (SALOME::SALOME_Exception)
165 Unexpect aCatch(SALOME_SalomeException);
168 res = _impl->HasShapeToMesh();
170 catch(SALOME_Exception & S_ex) {
171 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
176 //=======================================================================
177 //function : GetShapeToMesh
179 //=======================================================================
181 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
182 throw (SALOME::SALOME_Exception)
184 Unexpect aCatch(SALOME_SalomeException);
185 GEOM::GEOM_Object_var aShapeObj;
187 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
189 aShapeObj = _gen_i->ShapeToGeomObject( S );
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 return aShapeObj._retn();
197 //================================================================================
199 * \brief Remove all nodes and elements
201 //================================================================================
203 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
205 Unexpect aCatch(SALOME_SalomeException);
208 CheckGeomGroupModif(); // issue 20145
210 catch(SALOME_Exception & S_ex) {
211 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
213 TPythonDump() << _this() << ".Clear()";
216 //================================================================================
218 * \brief Remove all nodes and elements for indicated shape
220 //================================================================================
222 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
223 throw (SALOME::SALOME_Exception)
225 Unexpect aCatch(SALOME_SalomeException);
227 _impl->ClearSubMesh( ShapeID );
229 catch(SALOME_Exception & S_ex) {
230 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
234 //=============================================================================
238 //=============================================================================
240 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
242 SMESH::DriverMED_ReadStatus res;
245 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
246 res = SMESH::DRS_OK; break;
247 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
248 res = SMESH::DRS_EMPTY; break;
249 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
250 res = SMESH::DRS_WARN_RENUMBER; break;
251 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
252 res = SMESH::DRS_WARN_SKIP_ELEM; break;
253 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
255 res = SMESH::DRS_FAIL; break;
260 //=============================================================================
264 * Imports mesh data from MED file
266 //=============================================================================
268 SMESH::DriverMED_ReadStatus
269 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
270 throw ( SALOME::SALOME_Exception )
272 Unexpect aCatch(SALOME_SalomeException);
275 status = _impl->MEDToMesh( theFileName, theMeshName );
277 catch( SALOME_Exception& S_ex ) {
278 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
281 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
284 CreateGroupServants();
286 int major, minor, release;
287 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
288 major = minor = release = -1;
289 myFileInfo = new SALOME_MED::MedFileInfo();
290 myFileInfo->fileName = theFileName;
291 myFileInfo->fileSize = 0;
294 if ( ::_stati64( theFileName, &d ) != -1 )
297 if ( ::stat64( theFileName, &d ) != -1 )
299 myFileInfo->fileSize = d.st_size;
300 myFileInfo->major = major;
301 myFileInfo->minor = minor;
302 myFileInfo->release = release;
304 return ConvertDriverMEDReadStatus(status);
307 //================================================================================
309 * \brief Return string representation of a MED file version comprising nbDigits
311 //================================================================================
313 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
315 std::string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
317 return CORBA::string_dup( ver.c_str() );
320 //=============================================================================
324 * Imports mesh data from MED file
326 //=============================================================================
328 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
329 throw ( SALOME::SALOME_Exception )
331 // Read mesh with name = <theMeshName> into SMESH_Mesh
332 _impl->UNVToMesh( theFileName );
334 CreateGroupServants();
339 //=============================================================================
343 * Imports mesh data from STL file
345 //=============================================================================
346 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
347 throw ( SALOME::SALOME_Exception )
349 // Read mesh with name = <theMeshName> into SMESH_Mesh
350 _impl->STLToMesh( theFileName );
355 //=============================================================================
359 * Imports mesh data from MED file
361 //=============================================================================
363 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
365 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
366 // int status = _impl->MEDToMesh( theFileName, theMeshName );
367 // CreateGroupServants();
372 //=============================================================================
376 //=============================================================================
378 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
380 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
381 (SMESH_Hypothesis::Hypothesis_Status theStatus)
384 RETURNCASE( HYP_OK );
385 RETURNCASE( HYP_MISSING );
386 RETURNCASE( HYP_CONCURENT );
387 RETURNCASE( HYP_BAD_PARAMETER );
388 RETURNCASE( HYP_HIDDEN_ALGO );
389 RETURNCASE( HYP_HIDING_ALGO );
390 RETURNCASE( HYP_UNKNOWN_FATAL );
391 RETURNCASE( HYP_INCOMPATIBLE );
392 RETURNCASE( HYP_NOTCONFORM );
393 RETURNCASE( HYP_ALREADY_EXIST );
394 RETURNCASE( HYP_BAD_DIM );
395 RETURNCASE( HYP_BAD_SUBSHAPE );
396 RETURNCASE( HYP_BAD_GEOMETRY );
397 RETURNCASE( HYP_NEED_SHAPE );
400 return SMESH::HYP_UNKNOWN_FATAL;
403 //=============================================================================
407 * calls internal addHypothesis() and then adds a reference to <anHyp> under
408 * the SObject actually having a reference to <aSubShape>.
409 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
411 //=============================================================================
413 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
414 SMESH::SMESH_Hypothesis_ptr anHyp)
415 throw(SALOME::SALOME_Exception)
417 Unexpect aCatch(SALOME_SalomeException);
418 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
420 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
421 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
422 aSubShapeObject, anHyp );
424 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
426 // Update Python script
427 if(_impl->HasShapeToMesh()) {
428 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
429 << aSubShapeObject << ", " << anHyp << " )";
432 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
435 return ConvertHypothesisStatus(status);
438 //=============================================================================
442 //=============================================================================
444 SMESH_Hypothesis::Hypothesis_Status
445 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
446 SMESH::SMESH_Hypothesis_ptr anHyp)
448 if(MYDEBUG) MESSAGE("addHypothesis");
450 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
451 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
454 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
455 if (CORBA::is_nil(myHyp))
456 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
459 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
462 TopoDS_Shape myLocSubShape;
463 //use PseudoShape in case if mesh has no shape
465 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
467 myLocSubShape = _impl->GetShapeToMesh();
469 int hypId = myHyp->GetId();
470 status = _impl->AddHypothesis(myLocSubShape, hypId);
471 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
472 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
473 // assure there is a corresponding submesh
474 if ( !_impl->IsMainShape( myLocSubShape )) {
475 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
476 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
477 createSubMesh( aSubShapeObject );
481 catch(SALOME_Exception & S_ex)
483 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
488 //=============================================================================
492 //=============================================================================
494 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
495 SMESH::SMESH_Hypothesis_ptr anHyp)
496 throw(SALOME::SALOME_Exception)
498 Unexpect aCatch(SALOME_SalomeException);
499 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
501 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
502 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
503 aSubShapeObject, anHyp );
505 // Update Python script
506 // Update Python script
507 if(_impl->HasShapeToMesh()) {
508 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
509 << aSubShapeObject << ", " << anHyp << " )";
512 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
516 return ConvertHypothesisStatus(status);
519 //=============================================================================
523 //=============================================================================
525 SMESH_Hypothesis::Hypothesis_Status
526 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
527 SMESH::SMESH_Hypothesis_ptr anHyp)
529 if(MYDEBUG) MESSAGE("removeHypothesis()");
530 // **** proposer liste de subShape (selection multiple)
532 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
533 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
535 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
536 if (CORBA::is_nil(myHyp))
537 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
539 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
542 TopoDS_Shape myLocSubShape;
543 //use PseudoShape in case if mesh has no shape
545 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
547 myLocSubShape = _impl->GetShapeToMesh();
549 int hypId = myHyp->GetId();
550 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
551 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
552 // _mapHypo.erase( hypId );
554 catch(SALOME_Exception & S_ex)
556 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
561 //=============================================================================
565 //=============================================================================
567 SMESH::ListOfHypothesis *
568 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
569 throw(SALOME::SALOME_Exception)
571 Unexpect aCatch(SALOME_SalomeException);
572 if (MYDEBUG) MESSAGE("GetHypothesisList");
573 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
574 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
576 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
579 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
580 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
581 myLocSubShape = _impl->GetShapeToMesh();
582 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
583 int i = 0, n = aLocalList.size();
586 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
587 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
588 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
589 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
594 catch(SALOME_Exception & S_ex) {
595 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
598 return aList._retn();
601 //=============================================================================
605 //=============================================================================
606 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
607 const char* theName )
608 throw(SALOME::SALOME_Exception)
610 Unexpect aCatch(SALOME_SalomeException);
611 MESSAGE("SMESH_Mesh_i::GetSubMesh");
612 if (CORBA::is_nil(aSubShapeObject))
613 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
616 SMESH::SMESH_subMesh_var subMesh;
617 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
619 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
621 //Get or Create the SMESH_subMesh object implementation
623 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
624 subMesh = getSubMesh( subMeshId );
626 // create a new subMesh object servant if there is none for the shape
627 if ( subMesh->_is_nil() )
628 subMesh = createSubMesh( aSubShapeObject );
629 if ( _gen_i->CanPublishInStudy( subMesh )) {
630 SALOMEDS::SObject_var aSO =
631 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
632 subMesh, aSubShapeObject, theName );
633 if ( !aSO->_is_nil()) {
634 // Update Python script
635 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
636 << aSubShapeObject << ", '" << theName << "' )";
640 catch(SALOME_Exception & S_ex) {
641 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
643 return subMesh._retn();
646 //=============================================================================
650 //=============================================================================
652 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
653 throw (SALOME::SALOME_Exception)
655 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
656 if ( theSubMesh->_is_nil() )
659 GEOM::GEOM_Object_var aSubShapeObject;
660 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
661 if ( !aStudy->_is_nil() ) {
662 // Remove submesh's SObject
663 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
664 if ( !anSO->_is_nil() ) {
665 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
666 SALOMEDS::SObject_var anObj, aRef;
667 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
668 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
670 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
671 // aSubShapeObject = theSubMesh->GetSubShape();
673 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
675 // Update Python script
676 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
680 removeSubMesh( theSubMesh, aSubShapeObject.in() );
683 //=============================================================================
687 //=============================================================================
688 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
689 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
691 switch (theElemType) {
696 CASE2STRING( VOLUME );
702 //=============================================================================
706 //=============================================================================
708 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
709 const char* theName )
710 throw(SALOME::SALOME_Exception)
712 Unexpect aCatch(SALOME_SalomeException);
713 SMESH::SMESH_Group_var aNewGroup =
714 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
716 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
717 SALOMEDS::SObject_var aSO =
718 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
719 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
720 if ( !aSO->_is_nil()) {
721 // Update Python script
722 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
723 << ElementTypeString(theElemType) << ", '" << theName << "' )";
726 return aNewGroup._retn();
730 //=============================================================================
734 //=============================================================================
735 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
737 GEOM::GEOM_Object_ptr theGeomObj)
738 throw(SALOME::SALOME_Exception)
740 Unexpect aCatch(SALOME_SalomeException);
741 SMESH::SMESH_GroupOnGeom_var aNewGroup;
743 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
744 if ( !aShape.IsNull() )
746 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
747 ( createGroup( theElemType, theName, aShape ));
749 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
750 SALOMEDS::SObject_var aSO =
751 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
752 aNewGroup, theGeomObj, theName);
753 if ( !aSO->_is_nil()) {
754 // Update Python script
755 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
756 << ElementTypeString(theElemType) << ", '" << theName << "', "
757 << theGeomObj << " )";
762 return aNewGroup._retn();
765 //=============================================================================
769 //=============================================================================
771 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
772 throw (SALOME::SALOME_Exception)
774 if ( theGroup->_is_nil() )
777 SMESH_GroupBase_i* aGroup =
778 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
782 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
783 if ( !aStudy->_is_nil() ) {
784 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
786 if ( !aGroupSO->_is_nil() ) {
787 // Update Python script
788 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
790 // Remove group's SObject
791 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
795 // Remove the group from SMESH data structures
796 removeGroup( aGroup->GetLocalID() );
799 //=============================================================================
800 /*! RemoveGroupWithContents
801 * Remove group with its contents
803 //=============================================================================
804 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
805 throw (SALOME::SALOME_Exception)
807 if ( theGroup->_is_nil() )
810 SMESH_GroupBase_i* aGroup =
811 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
815 SMESH::long_array_var anIds = aGroup->GetListOfID();
816 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
818 // Update Python script
819 TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
822 if ( aGroup->GetType() == SMESH::NODE )
823 aMeshEditor->RemoveNodes( anIds );
825 aMeshEditor->RemoveElements( anIds );
828 RemoveGroup( theGroup );
830 // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
831 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
832 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
836 //================================================================================
838 * \brief Get the list of groups existing in the mesh
839 * \retval SMESH::ListOfGroups * - list of groups
841 //================================================================================
843 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
845 Unexpect aCatch(SALOME_SalomeException);
846 if (MYDEBUG) MESSAGE("GetGroups");
848 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
851 TPythonDump aPythonDump;
852 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
856 aList->length( _mapGroups.size() );
858 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
859 for ( ; it != _mapGroups.end(); it++ ) {
860 if ( CORBA::is_nil( it->second )) continue;
861 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
863 if (i > 1) aPythonDump << ", ";
864 aPythonDump << it->second;
868 catch(SALOME_Exception & S_ex) {
869 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
872 // Update Python script
873 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
874 aPythonDump << " ] = " << _this() << ".GetGroups()";
876 return aList._retn();
878 //=============================================================================
880 * Get number of groups existing in the mesh
882 //=============================================================================
884 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
886 Unexpect aCatch(SALOME_SalomeException);
887 return _mapGroups.size();
890 //=============================================================================
892 * New group is created. All mesh elements that are
893 * present in initial groups are added to the new one
895 //=============================================================================
896 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
897 SMESH::SMESH_GroupBase_ptr theGroup2,
898 const char* theName )
899 throw (SALOME::SALOME_Exception)
903 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
904 theGroup1->GetType() != theGroup2->GetType() )
905 return SMESH::SMESH_Group::_nil();
908 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
909 if ( aResGrp->_is_nil() )
910 return SMESH::SMESH_Group::_nil();
912 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
913 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
915 TColStd_MapOfInteger aResMap;
917 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
918 aResMap.Add( anIds1[ i1 ] );
920 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
921 aResMap.Add( anIds2[ i2 ] );
923 SMESH::long_array_var aResIds = new SMESH::long_array;
924 aResIds->length( aResMap.Extent() );
927 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
928 for( ; anIter.More(); anIter.Next() )
929 aResIds[ resI++ ] = anIter.Key();
931 aResGrp->Add( aResIds );
933 // Clear python lines, created by CreateGroup() and Add()
934 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
935 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
936 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
938 // Update Python script
939 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
940 << theGroup1 << ", " << theGroup2 << ", '"
943 return aResGrp._retn();
947 return SMESH::SMESH_Group::_nil();
951 //=============================================================================
953 \brief Union list of groups. New group is created. All mesh elements that are
954 present in initial groups are added to the new one.
955 \param theGroups list of groups
956 \param theName name of group to be created
957 \return pointer on the group
959 //=============================================================================
960 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
961 const char* theName )
962 throw (SALOME::SALOME_Exception)
965 return SMESH::SMESH_Group::_nil();
969 NCollection_Map< int > anIds;
970 SMESH::ElementType aType = SMESH::ALL;
971 for ( int g = 0, n = theGroups.length(); g < n; g++ )
973 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
974 if ( CORBA::is_nil( aGrp ) )
978 SMESH::ElementType aCurrType = aGrp->GetType();
979 if ( aType == SMESH::ALL )
983 if ( aType != aCurrType )
984 return SMESH::SMESH_Group::_nil();
988 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
989 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
991 int aCurrId = aCurrIds[ i ];
992 anIds.Add( aCurrId );
997 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
998 if ( aResGrp->_is_nil() )
999 return SMESH::SMESH_Group::_nil();
1001 // Create array of identifiers
1002 SMESH::long_array_var aResIds = new SMESH::long_array;
1003 aResIds->length( anIds.Extent() );
1005 NCollection_Map< int >::Iterator anIter( anIds );
1006 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1008 aResIds[ i ] = anIter.Value();
1010 aResGrp->Add( aResIds );
1012 // Clear python lines, created by CreateGroup() and Add()
1013 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1014 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1015 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1017 // Update Python script
1019 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1020 << &theGroups << ", '" << theName << "' )";
1022 return aResGrp._retn();
1026 return SMESH::SMESH_Group::_nil();
1030 //=============================================================================
1032 * New group is created. All mesh elements that are
1033 * present in both initial groups are added to the new one.
1035 //=============================================================================
1036 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1037 SMESH::SMESH_GroupBase_ptr theGroup2,
1038 const char* theName )
1039 throw (SALOME::SALOME_Exception)
1041 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1042 theGroup1->GetType() != theGroup2->GetType() )
1043 return SMESH::SMESH_Group::_nil();
1045 // Create Intersection
1046 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1047 if ( aResGrp->_is_nil() )
1050 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1051 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1053 TColStd_MapOfInteger aMap1;
1055 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1056 aMap1.Add( anIds1[ i1 ] );
1058 TColStd_SequenceOfInteger aSeq;
1060 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1061 if ( aMap1.Contains( anIds2[ i2 ] ) )
1062 aSeq.Append( anIds2[ i2 ] );
1064 SMESH::long_array_var aResIds = new SMESH::long_array;
1065 aResIds->length( aSeq.Length() );
1067 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1068 aResIds[ resI ] = aSeq( resI + 1 );
1070 aResGrp->Add( aResIds );
1072 // Clear python lines, created by CreateGroup() and Add()
1073 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1074 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1075 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1077 // Update Python script
1078 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1079 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1081 return aResGrp._retn();
1084 //=============================================================================
1086 \brief Intersect list of groups. New group is created. All mesh elements that
1087 are present in all initial groups simultaneously are added to the new one.
1088 \param theGroups list of groups
1089 \param theName name of group to be created
1090 \return pointer on the group
1092 //=============================================================================
1093 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1094 const SMESH::ListOfGroups& theGroups, const char* theName )
1095 throw (SALOME::SALOME_Exception)
1098 return SMESH::SMESH_Group::_nil();
1102 NCollection_DataMap< int, int > anIdToCount;
1103 SMESH::ElementType aType = SMESH::ALL;
1104 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1106 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1107 if ( CORBA::is_nil( aGrp ) )
1111 SMESH::ElementType aCurrType = aGrp->GetType();
1112 if ( aType == SMESH::ALL )
1116 if ( aType != aCurrType )
1117 return SMESH::SMESH_Group::_nil();
1120 // calculates number of occurance ids in groups
1121 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1122 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1124 int aCurrId = aCurrIds[ i ];
1125 if ( !anIdToCount.IsBound( aCurrId ) )
1126 anIdToCount.Bind( aCurrId, 1 );
1128 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1132 // create map of ids
1133 int nbGrp = theGroups.length();
1134 NCollection_Map< int > anIds;
1135 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1136 for ( ; anIter.More(); anIter.Next() )
1138 int aCurrId = anIter.Key();
1139 int aCurrNb = anIter.Value();
1140 if ( aCurrNb == nbGrp )
1141 anIds.Add( aCurrId );
1145 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1146 if ( aResGrp->_is_nil() )
1147 return SMESH::SMESH_Group::_nil();
1149 // Create array of identifiers
1150 SMESH::long_array_var aResIds = new SMESH::long_array;
1151 aResIds->length( anIds.Extent() );
1153 NCollection_Map< int >::Iterator aListIter( anIds );
1154 for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1156 aResIds[ i ] = aListIter.Value();
1158 aResGrp->Add( aResIds );
1160 // Clear python lines, created by CreateGroup() and Add()
1161 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1162 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1163 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1165 // Update Python script
1167 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1168 << &theGroups << ", '" << theName << "' )";
1170 return aResGrp._retn();
1174 return SMESH::SMESH_Group::_nil();
1178 //=============================================================================
1180 * New group is created. All mesh elements that are present in
1181 * main group but do not present in tool group are added to the new one
1183 //=============================================================================
1184 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1185 SMESH::SMESH_GroupBase_ptr theGroup2,
1186 const char* theName )
1187 throw (SALOME::SALOME_Exception)
1189 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1190 theGroup1->GetType() != theGroup2->GetType() )
1191 return SMESH::SMESH_Group::_nil();
1194 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1195 if ( aResGrp->_is_nil() )
1198 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1199 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1201 TColStd_MapOfInteger aMap2;
1203 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1204 aMap2.Add( anIds2[ i2 ] );
1206 TColStd_SequenceOfInteger aSeq;
1207 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1208 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1209 aSeq.Append( anIds1[ i1 ] );
1211 SMESH::long_array_var aResIds = new SMESH::long_array;
1212 aResIds->length( aSeq.Length() );
1214 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1215 aResIds[ resI ] = aSeq( resI + 1 );
1217 aResGrp->Add( aResIds );
1219 // Clear python lines, created by CreateGroup() and Add()
1220 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1221 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1222 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1224 // Update Python script
1225 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1226 << theGroup1 << ", " << theGroup2 << ", '"
1227 << theName << "' )";
1229 return aResGrp._retn();
1232 //=============================================================================
1234 \brief Cut lists of groups. New group is created. All mesh elements that are
1235 present in main groups but do not present in tool groups are added to the new one
1236 \param theMainGroups list of main groups
1237 \param theToolGroups list of tool groups
1238 \param theName name of group to be created
1239 \return pointer on the group
1241 //=============================================================================
1242 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1243 const SMESH::ListOfGroups& theMainGroups,
1244 const SMESH::ListOfGroups& theToolGroups,
1245 const char* theName )
1246 throw (SALOME::SALOME_Exception)
1249 return SMESH::SMESH_Group::_nil();
1253 NCollection_Map< int > aToolIds;
1254 SMESH::ElementType aType = SMESH::ALL;
1256 // iterate through tool groups
1257 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1259 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1260 if ( CORBA::is_nil( aGrp ) )
1264 SMESH::ElementType aCurrType = aGrp->GetType();
1265 if ( aType == SMESH::ALL )
1269 if ( aType != aCurrType )
1270 return SMESH::SMESH_Group::_nil();
1274 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1275 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1277 int aCurrId = aCurrIds[ i ];
1278 aToolIds.Add( aCurrId );
1282 NCollection_Map< int > anIds; // result
1284 // Iterate through main group
1285 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1287 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1288 if ( CORBA::is_nil( aGrp ) )
1292 SMESH::ElementType aCurrType = aGrp->GetType();
1293 if ( aType == SMESH::ALL )
1297 if ( aType != aCurrType )
1298 return SMESH::SMESH_Group::_nil();
1302 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1303 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1305 int aCurrId = aCurrIds[ i ];
1306 if ( !aToolIds.Contains( aCurrId ) )
1307 anIds.Add( aCurrId );
1312 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1313 if ( aResGrp->_is_nil() )
1314 return SMESH::SMESH_Group::_nil();
1316 // Create array of identifiers
1317 SMESH::long_array_var aResIds = new SMESH::long_array;
1318 aResIds->length( anIds.Extent() );
1320 NCollection_Map< int >::Iterator anIter( anIds );
1321 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1323 aResIds[ i ] = anIter.Value();
1325 aResGrp->Add( aResIds );
1327 // Clear python lines, created by CreateGroup() and Add()
1328 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1329 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1330 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1332 // Update Python script
1334 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1335 << &theMainGroups << ", " << &theToolGroups << ", '"
1336 << theName << "' )";
1338 return aResGrp._retn();
1342 return SMESH::SMESH_Group::_nil();
1346 //=============================================================================
1348 \brief Create groups of entities from existing groups of superior dimensions
1350 1) extract all nodes from each group,
1351 2) combine all elements of specified dimension laying on these nodes.
1352 \param theGroups list of source groups
1353 \param theElemType dimension of elements
1354 \param theName name of new group
1355 \return pointer on new group
1357 //=============================================================================
1358 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1359 const SMESH::ListOfGroups& theGroups,
1360 SMESH::ElementType theElemType,
1361 const char* theName )
1362 throw (SALOME::SALOME_Exception)
1364 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1366 if ( !theName || !aMeshDS )
1367 return SMESH::SMESH_Group::_nil();
1369 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1373 // Create map of nodes from all groups
1375 NCollection_Map< int > aNodeMap;
1377 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1379 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1380 if ( CORBA::is_nil( aGrp ) )
1383 SMESH::ElementType aType = aGrp->GetType();
1384 if ( aType == SMESH::ALL )
1386 else if ( aType == SMESH::NODE )
1388 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1389 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1391 int aCurrId = aCurrIds[ i ];
1392 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1394 aNodeMap.Add( aNode->GetID() );
1399 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1400 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1402 int aCurrId = aCurrIds[ i ];
1403 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1406 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1407 while( aNodeIter->more() )
1409 const SMDS_MeshNode* aNode =
1410 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1412 aNodeMap.Add( aNode->GetID() );
1418 // Get result identifiers
1420 NCollection_Map< int > aResultIds;
1421 if ( theElemType == SMESH::NODE )
1423 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1424 for ( ; aNodeIter.More(); aNodeIter.Next() )
1425 aResultIds.Add( aNodeIter.Value() );
1429 // Create list of elements of given dimension constructed on the nodes
1430 NCollection_Map< int > anElemList;
1431 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1432 for ( ; aNodeIter.More(); aNodeIter.Next() )
1434 const SMDS_MeshElement* aNode =
1435 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1439 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1440 while( anElemIter->more() )
1442 const SMDS_MeshElement* anElem =
1443 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1444 if ( anElem && anElem->GetType() == anElemType )
1445 anElemList.Add( anElem->GetID() );
1449 // check whether all nodes of elements are present in nodes map
1450 NCollection_Map< int >::Iterator anIter( anElemList );
1451 for ( ; anIter.More(); anIter.Next() )
1453 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1458 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1459 while( aNodeIter->more() )
1461 const SMDS_MeshNode* aNode =
1462 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1463 if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1470 aResultIds.Add( anElem->GetID() );
1476 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1477 if ( aResGrp->_is_nil() )
1478 return SMESH::SMESH_Group::_nil();
1480 // Create array of identifiers
1481 SMESH::long_array_var aResIds = new SMESH::long_array;
1482 aResIds->length( aResultIds.Extent() );
1484 NCollection_Map< int >::Iterator aResIter( aResultIds );
1485 for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1486 aResIds[ i ] = aResIter.Value();
1487 aResGrp->Add( aResIds );
1489 // Remove strings corresponding to group creation
1490 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1491 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1492 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1494 // Update Python script
1496 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1497 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1499 return aResGrp._retn();
1503 return SMESH::SMESH_Group::_nil();
1507 //================================================================================
1509 * \brief Remember GEOM group data
1511 //================================================================================
1513 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1514 CORBA::Object_ptr theSmeshObj)
1516 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1519 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1520 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1521 if ( groupSO->_is_nil() )
1524 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1525 GEOM::GEOM_IGroupOperations_var groupOp =
1526 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1527 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1530 _geomGroupData.push_back( TGeomGroupData() );
1531 TGeomGroupData & groupData = _geomGroupData.back();
1533 CORBA::String_var entry = groupSO->GetID();
1534 groupData._groupEntry = entry.in();
1536 for ( int i = 0; i < ids->length(); ++i )
1537 groupData._indices.insert( ids[i] );
1539 groupData._smeshObject = theSmeshObj;
1542 //================================================================================
1544 * Remove GEOM group data relating to removed smesh object
1546 //================================================================================
1548 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1550 list<TGeomGroupData>::iterator
1551 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1552 for ( ; data != dataEnd; ++data ) {
1553 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1554 _geomGroupData.erase( data );
1560 //================================================================================
1562 * \brief Return new group contents if it has been changed and update group data
1564 //================================================================================
1566 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1568 TopoDS_Shape newShape;
1571 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1572 if ( study->_is_nil() ) return newShape; // means "not changed"
1573 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1574 if ( !groupSO->_is_nil() )
1576 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1577 if ( CORBA::is_nil( groupObj )) return newShape;
1578 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1580 // get indices of group items
1581 set<int> curIndices;
1582 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1583 GEOM::GEOM_IGroupOperations_var groupOp =
1584 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1585 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1586 for ( int i = 0; i < ids->length(); ++i )
1587 curIndices.insert( ids[i] );
1589 if ( groupData._indices == curIndices )
1590 return newShape; // group not changed
1593 groupData._indices = curIndices;
1595 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1596 if ( !geomClient ) return newShape;
1597 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1598 geomClient->RemoveShapeFromBuffer( groupIOR );
1599 newShape = _gen_i->GeomObjectToShape( geomGroup );
1602 if ( newShape.IsNull() ) {
1603 // geom group becomes empty - return empty compound
1604 TopoDS_Compound compound;
1605 BRep_Builder().MakeCompound(compound);
1606 newShape = compound;
1612 //=============================================================================
1614 * \brief Storage of shape and index used in CheckGeomGroupModif()
1616 //=============================================================================
1617 struct TIndexedShape {
1619 TopoDS_Shape _shape;
1620 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1623 //=============================================================================
1625 * \brief Update objects depending on changed geom groups
1627 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1628 * issue 0020210: Update of a smesh group after modification of the associated geom group
1630 //=============================================================================
1632 void SMESH_Mesh_i::CheckGeomGroupModif()
1634 if ( !_impl->HasShapeToMesh() ) return;
1636 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1637 if ( study->_is_nil() ) return;
1639 CORBA::Long nbEntities = NbNodes() + NbElements();
1641 // Check if group contents changed
1643 typedef map< string, TopoDS_Shape > TEntry2Geom;
1644 TEntry2Geom newGroupContents;
1646 list<TGeomGroupData>::iterator
1647 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1648 for ( ; data != dataEnd; ++data )
1650 pair< TEntry2Geom::iterator, bool > it_new =
1651 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1652 bool processedGroup = !it_new.second;
1653 TopoDS_Shape& newShape = it_new.first->second;
1654 if ( !processedGroup )
1655 newShape = newGroupShape( *data );
1656 if ( newShape.IsNull() )
1657 continue; // no changes
1659 if ( processedGroup ) { // update group indices
1660 list<TGeomGroupData>::iterator data2 = data;
1661 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1662 data->_indices = data2->_indices;
1665 // Update SMESH objects according to new GEOM group contents
1667 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1668 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1670 int oldID = submesh->GetId();
1671 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1673 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1675 // update hypotheses
1676 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1677 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1678 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1680 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1681 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1683 // care of submeshes
1684 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1685 int newID = newSubmesh->GetId();
1686 if ( newID != oldID ) {
1687 _mapSubMesh [ newID ] = newSubmesh;
1688 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1689 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1690 _mapSubMesh. erase(oldID);
1691 _mapSubMesh_i. erase(oldID);
1692 _mapSubMeshIor.erase(oldID);
1693 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1698 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1699 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1700 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1702 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1704 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1705 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1706 ds->SetShape( newShape );
1711 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1712 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1714 // Remove groups and submeshes basing on removed sub-shapes
1716 TopTools_MapOfShape newShapeMap;
1717 TopoDS_Iterator shapeIt( newShape );
1718 for ( ; shapeIt.More(); shapeIt.Next() )
1719 newShapeMap.Add( shapeIt.Value() );
1721 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1722 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1724 if ( newShapeMap.Contains( shapeIt.Value() ))
1726 TopTools_IndexedMapOfShape oldShapeMap;
1727 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1728 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1730 const TopoDS_Shape& oldShape = oldShapeMap(i);
1731 int oldInd = meshDS->ShapeToIndex( oldShape );
1733 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1734 if ( i_smIor != _mapSubMeshIor.end() ) {
1735 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1738 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1739 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1741 // check if a group bases on oldInd shape
1742 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1743 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1744 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1745 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1747 RemoveGroup( i_grp->second ); // several groups can base on same shape
1748 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1753 // Reassign hypotheses and update groups after setting the new shape to mesh
1755 // collect anassigned hypotheses
1756 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1757 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1758 TShapeHypList assignedHyps;
1759 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1761 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1762 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1763 if ( !hyps.empty() ) {
1764 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1765 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1766 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1769 // collect shapes supporting groups
1770 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1771 TShapeTypeList groupData;
1772 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1773 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1774 for ( ; grIt != groups.end(); ++grIt )
1776 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1778 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1780 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1781 _impl->ShapeToMesh( newShape );
1783 // reassign hypotheses
1784 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1785 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1787 TIndexedShape& geom = indS_hyps->first;
1788 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1789 int oldID = geom._index;
1790 int newID = meshDS->ShapeToIndex( geom._shape );
1793 if ( oldID == 1 ) { // main shape
1795 geom._shape = newShape;
1797 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1798 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1799 // care of submeshes
1800 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1801 if ( newID != oldID ) {
1802 _mapSubMesh [ newID ] = newSubmesh;
1803 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1804 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1805 _mapSubMesh. erase(oldID);
1806 _mapSubMesh_i. erase(oldID);
1807 _mapSubMeshIor.erase(oldID);
1808 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1812 TShapeTypeList::iterator geomType = groupData.begin();
1813 for ( ; geomType != groupData.end(); ++geomType )
1815 const TIndexedShape& geom = geomType->first;
1816 int oldID = geom._index;
1817 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1820 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1821 CORBA::String_var name = groupSO->GetName();
1823 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1825 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1826 group_i->changeLocalId( newID );
1829 break; // everything has been updated
1832 } // loop on group data
1836 CORBA::Long newNbEntities = NbNodes() + NbElements();
1837 list< SALOMEDS::SObject_var > soToUpdateIcons;
1838 if ( newNbEntities != nbEntities )
1840 // Add all SObjects with icons
1841 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1843 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1844 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1845 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1847 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1848 i_gr != _mapGroups.end(); ++i_gr ) // groups
1849 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1852 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1853 for ( ; so != soToUpdateIcons.end(); ++so )
1854 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1857 //=============================================================================
1859 * \brief Create standalone group instead if group on geometry
1862 //=============================================================================
1864 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1866 SMESH::SMESH_Group_var aGroup;
1867 if ( theGroup->_is_nil() )
1868 return aGroup._retn();
1870 Unexpect aCatch(SALOME_SalomeException);
1872 SMESH_GroupBase_i* aGroupToRem =
1873 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1875 return aGroup._retn();
1877 int anId = aGroupToRem->GetLocalID();
1878 if ( !_impl->ConvertToStandalone( anId ) )
1879 return aGroup._retn();
1880 removeGeomGroupData( theGroup );
1882 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1884 // remove old instance of group from own map
1885 _mapGroups.erase( anId );
1887 SALOMEDS::StudyBuilder_var builder;
1888 SALOMEDS::SObject_var aGroupSO;
1889 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1890 if ( !aStudy->_is_nil() ) {
1891 builder = aStudy->NewBuilder();
1892 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1893 if ( !aGroupSO->_is_nil() ) {
1895 // remove reference to geometry
1896 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1897 for ( ; chItr->More(); chItr->Next() )
1898 // Remove group's child SObject
1899 builder->RemoveObject( chItr->Value() );
1901 // Update Python script
1902 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1903 << aGroupSO << " )";
1907 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1908 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1909 aGroupImpl->Register();
1910 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1912 // remember new group in own map
1913 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1914 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1916 // register CORBA object for persistence
1917 //int nextId = _gen_i->RegisterObject( aGroup );
1918 //if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1919 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1921 return aGroup._retn();
1924 //=============================================================================
1928 //=============================================================================
1930 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1932 if(MYDEBUG) MESSAGE( "createSubMesh" );
1933 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1935 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1936 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1937 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1938 SMESH::SMESH_subMesh_var subMesh
1939 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1941 _mapSubMesh[subMeshId] = mySubMesh;
1942 _mapSubMesh_i[subMeshId] = subMeshServant;
1943 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1945 // register CORBA object for persistence
1946 int nextId = _gen_i->RegisterObject( subMesh );
1947 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1949 // to track changes of GEOM groups
1950 addGeomGroupData( theSubShapeObject, subMesh );
1952 return subMesh._retn();
1955 //=======================================================================
1956 //function : getSubMesh
1958 //=======================================================================
1960 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1962 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1963 if ( it == _mapSubMeshIor.end() )
1964 return SMESH::SMESH_subMesh::_nil();
1966 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
1970 //=============================================================================
1974 //=============================================================================
1976 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
1977 GEOM::GEOM_Object_ptr theSubShapeObject )
1979 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
1980 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
1983 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
1985 CORBA::Long shapeId = theSubMesh->GetId();
1986 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
1988 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
1991 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
1992 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
1993 for ( ; hyp != hyps.end(); ++hyp )
1994 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2001 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2002 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2003 removeHypothesis( theSubShapeObject, aHypList[i] );
2006 catch( const SALOME::SALOME_Exception& ) {
2007 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2009 removeGeomGroupData( theSubShapeObject );
2011 int subMeshId = theSubMesh->GetId();
2013 _mapSubMesh.erase(subMeshId);
2014 _mapSubMesh_i.erase(subMeshId);
2015 _mapSubMeshIor.erase(subMeshId);
2016 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2019 //=============================================================================
2023 //=============================================================================
2025 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2026 const char* theName,
2027 const TopoDS_Shape& theShape )
2030 SMESH::SMESH_GroupBase_var aGroup;
2031 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2032 SMESH_GroupBase_i* aGroupImpl;
2033 if ( !theShape.IsNull() )
2034 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2036 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2038 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2039 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2040 aGroupImpl->Register();
2041 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2043 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2044 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2046 // register CORBA object for persistence
2047 int nextId = _gen_i->RegisterObject( aGroup );
2048 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2050 // to track changes of GEOM groups
2051 if ( !theShape.IsNull() ) {
2052 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2053 addGeomGroupData( geom, aGroup );
2056 return aGroup._retn();
2059 //=============================================================================
2061 * SMESH_Mesh_i::removeGroup
2063 * Should be called by ~SMESH_Group_i()
2065 //=============================================================================
2067 void SMESH_Mesh_i::removeGroup( const int theId )
2069 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2070 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2071 removeGeomGroupData( _mapGroups[theId] );
2072 _mapGroups.erase( theId );
2073 _impl->RemoveGroup( theId );
2078 //=============================================================================
2082 //=============================================================================
2084 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2085 throw(SALOME::SALOME_Exception)
2087 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2089 SMESH::log_array_var aLog;
2091 list < SMESHDS_Command * >logDS = _impl->GetLog();
2092 aLog = new SMESH::log_array;
2094 int lg = logDS.size();
2097 list < SMESHDS_Command * >::iterator its = logDS.begin();
2098 while(its != logDS.end()){
2099 SMESHDS_Command *com = *its;
2100 int comType = com->GetType();
2102 int lgcom = com->GetNumber();
2104 const list < int >&intList = com->GetIndexes();
2105 int inum = intList.size();
2107 list < int >::const_iterator ii = intList.begin();
2108 const list < double >&coordList = com->GetCoords();
2109 int rnum = coordList.size();
2111 list < double >::const_iterator ir = coordList.begin();
2112 aLog[indexLog].commandType = comType;
2113 aLog[indexLog].number = lgcom;
2114 aLog[indexLog].coords.length(rnum);
2115 aLog[indexLog].indexes.length(inum);
2116 for(int i = 0; i < rnum; i++){
2117 aLog[indexLog].coords[i] = *ir;
2118 //MESSAGE(" "<<i<<" "<<ir.Value());
2121 for(int i = 0; i < inum; i++){
2122 aLog[indexLog].indexes[i] = *ii;
2123 //MESSAGE(" "<<i<<" "<<ii.Value());
2132 catch(SALOME_Exception & S_ex){
2133 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2135 return aLog._retn();
2139 //=============================================================================
2143 //=============================================================================
2145 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2147 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2151 //=============================================================================
2155 //=============================================================================
2157 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2159 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2163 //=============================================================================
2167 //=============================================================================
2169 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2174 //=============================================================================
2178 //=============================================================================
2180 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2182 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2186 //=============================================================================
2190 //=============================================================================
2192 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2194 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2198 //=============================================================================
2200 * Return mesh editor
2202 //=============================================================================
2204 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2206 // Create MeshEditor
2207 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2208 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2210 // Update Python script
2211 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2213 return aMesh._retn();
2216 //=============================================================================
2218 * Return mesh edition previewer
2220 //=============================================================================
2222 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2224 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2225 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2226 return aMesh._retn();
2229 //=============================================================================
2233 //=============================================================================
2234 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2236 Unexpect aCatch(SALOME_SalomeException);
2237 _impl->SetAutoColor(theAutoColor);
2240 //=============================================================================
2244 //=============================================================================
2245 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2247 Unexpect aCatch(SALOME_SalomeException);
2248 return _impl->GetAutoColor();
2252 //=============================================================================
2254 * Export in different formats
2256 //=============================================================================
2258 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2260 return _impl->HasDuplicatedGroupNamesMED();
2263 void SMESH_Mesh_i::PrepareForWriting (const char* file)
2265 TCollection_AsciiString aFullName ((char*)file);
2266 OSD_Path aPath (aFullName);
2267 OSD_File aFile (aPath);
2268 if (aFile.Exists()) {
2269 // existing filesystem node
2270 if (aFile.KindOfFile() == OSD_FILE) {
2271 if (aFile.IsWriteable()) {
2274 if (aFile.Failed()) {
2275 TCollection_AsciiString msg ("File ");
2276 msg += aFullName + " cannot be replaced.";
2277 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2280 TCollection_AsciiString msg ("File ");
2281 msg += aFullName + " cannot be overwritten.";
2282 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2285 TCollection_AsciiString msg ("Location ");
2286 msg += aFullName + " is not a file.";
2287 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2290 // nonexisting file; check if it can be created
2292 aFile.Build(OSD_WriteOnly, OSD_Protection());
2293 if (aFile.Failed()) {
2294 TCollection_AsciiString msg ("You cannot create the file ");
2295 msg += aFullName + ". Check the directory existance and access rights.";
2296 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2304 void SMESH_Mesh_i::ExportToMED (const char* file,
2305 CORBA::Boolean auto_groups,
2306 SMESH::MED_VERSION theVersion)
2307 throw(SALOME::SALOME_Exception)
2309 Unexpect aCatch(SALOME_SalomeException);
2312 PrepareForWriting(file);
2313 const char* aMeshName = "Mesh";
2314 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2315 if ( !aStudy->_is_nil() ) {
2316 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2317 if ( !aMeshSO->_is_nil() ) {
2318 aMeshName = aMeshSO->GetName();
2319 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2320 if ( !aStudy->GetProperties()->IsLocked() )
2322 SALOMEDS::GenericAttribute_var anAttr;
2323 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2324 SALOMEDS::AttributeExternalFileDef_var aFileName;
2325 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2326 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2327 ASSERT(!aFileName->_is_nil());
2328 aFileName->SetValue(file);
2329 SALOMEDS::AttributeFileType_var aFileType;
2330 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2331 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2332 ASSERT(!aFileType->_is_nil());
2333 aFileType->SetValue("FICHIERMED");
2337 // Update Python script
2338 // set name of mesh before export
2339 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2341 // check names of groups
2344 TPythonDump() << _this() << ".ExportToMED( '"
2345 << file << "', " << auto_groups << ", " << theVersion << " )";
2347 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2350 void SMESH_Mesh_i::ExportMED (const char* file,
2351 CORBA::Boolean auto_groups)
2352 throw(SALOME::SALOME_Exception)
2354 ExportToMED(file,auto_groups,SMESH::MED_V2_1);
2357 void SMESH_Mesh_i::ExportDAT (const char *file)
2358 throw(SALOME::SALOME_Exception)
2360 Unexpect aCatch(SALOME_SalomeException);
2362 // Update Python script
2363 // check names of groups
2365 TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
2368 PrepareForWriting(file);
2369 _impl->ExportDAT(file);
2372 void SMESH_Mesh_i::ExportUNV (const char *file)
2373 throw(SALOME::SALOME_Exception)
2375 Unexpect aCatch(SALOME_SalomeException);
2377 // Update Python script
2378 // check names of groups
2380 TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
2383 PrepareForWriting(file);
2384 _impl->ExportUNV(file);
2387 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2388 throw(SALOME::SALOME_Exception)
2390 Unexpect aCatch(SALOME_SalomeException);
2392 // Update Python script
2393 // check names of groups
2395 TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
2398 PrepareForWriting(file);
2399 _impl->ExportSTL(file, isascii);
2402 //=============================================================================
2406 //=============================================================================
2408 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2410 Unexpect aCatch(SALOME_SalomeException);
2411 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2412 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2413 return aMesh._retn();
2416 //=============================================================================
2420 //=============================================================================
2421 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2423 Unexpect aCatch(SALOME_SalomeException);
2424 return _impl->NbNodes();
2427 //=============================================================================
2431 //=============================================================================
2432 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2434 Unexpect aCatch(SALOME_SalomeException);
2435 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2438 //=============================================================================
2442 //=============================================================================
2443 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2445 Unexpect aCatch(SALOME_SalomeException);
2446 return _impl->Nb0DElements();
2449 //=============================================================================
2453 //=============================================================================
2454 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2456 Unexpect aCatch(SALOME_SalomeException);
2457 return _impl->NbEdges();
2460 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2461 throw(SALOME::SALOME_Exception)
2463 Unexpect aCatch(SALOME_SalomeException);
2464 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2467 //=============================================================================
2471 //=============================================================================
2472 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2474 Unexpect aCatch(SALOME_SalomeException);
2475 return _impl->NbFaces();
2478 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2480 Unexpect aCatch(SALOME_SalomeException);
2481 return _impl->NbTriangles();
2484 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2486 Unexpect aCatch(SALOME_SalomeException);
2487 return _impl->NbQuadrangles();
2490 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2492 Unexpect aCatch(SALOME_SalomeException);
2493 return _impl->NbPolygons();
2496 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2497 throw(SALOME::SALOME_Exception)
2499 Unexpect aCatch(SALOME_SalomeException);
2500 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2503 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2504 throw(SALOME::SALOME_Exception)
2506 Unexpect aCatch(SALOME_SalomeException);
2507 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2510 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2511 throw(SALOME::SALOME_Exception)
2513 Unexpect aCatch(SALOME_SalomeException);
2514 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2517 //=============================================================================
2521 //=============================================================================
2522 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2524 Unexpect aCatch(SALOME_SalomeException);
2525 return _impl->NbVolumes();
2528 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2530 Unexpect aCatch(SALOME_SalomeException);
2531 return _impl->NbTetras();
2534 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2536 Unexpect aCatch(SALOME_SalomeException);
2537 return _impl->NbHexas();
2540 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2542 Unexpect aCatch(SALOME_SalomeException);
2543 return _impl->NbPyramids();
2546 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2548 Unexpect aCatch(SALOME_SalomeException);
2549 return _impl->NbPrisms();
2552 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2554 Unexpect aCatch(SALOME_SalomeException);
2555 return _impl->NbPolyhedrons();
2558 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2559 throw(SALOME::SALOME_Exception)
2561 Unexpect aCatch(SALOME_SalomeException);
2562 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2565 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2566 throw(SALOME::SALOME_Exception)
2568 Unexpect aCatch(SALOME_SalomeException);
2569 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2572 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2573 throw(SALOME::SALOME_Exception)
2575 Unexpect aCatch(SALOME_SalomeException);
2576 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2579 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2580 throw(SALOME::SALOME_Exception)
2582 Unexpect aCatch(SALOME_SalomeException);
2583 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2586 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2587 throw(SALOME::SALOME_Exception)
2589 Unexpect aCatch(SALOME_SalomeException);
2590 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2593 //=============================================================================
2597 //=============================================================================
2598 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2600 Unexpect aCatch(SALOME_SalomeException);
2601 return _mapSubMesh_i.size();
2604 //=============================================================================
2608 //=============================================================================
2609 char* SMESH_Mesh_i::Dump()
2611 std::ostringstream os;
2613 return CORBA::string_dup( os.str().c_str() );
2616 //=============================================================================
2620 //=============================================================================
2621 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2623 // SMESH::long_array_var aResult = new SMESH::long_array();
2624 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2625 // int aMinId = aSMESHDS_Mesh->MinElementID();
2626 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2628 // aResult->length(aMaxId - aMinId + 1);
2630 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2631 // aResult[i++] = id;
2633 // return aResult._retn();
2635 return GetElementsId();
2638 //=============================================================================
2642 //=============================================================================
2644 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2645 throw (SALOME::SALOME_Exception)
2647 Unexpect aCatch(SALOME_SalomeException);
2648 MESSAGE("SMESH_Mesh_i::GetElementsId");
2649 SMESH::long_array_var aResult = new SMESH::long_array();
2650 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2652 if ( aSMESHDS_Mesh == NULL )
2653 return aResult._retn();
2655 long nbElements = NbElements();
2656 aResult->length( nbElements );
2657 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2658 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2659 aResult[i] = anIt->next()->GetID();
2661 return aResult._retn();
2665 //=============================================================================
2669 //=============================================================================
2671 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2672 throw (SALOME::SALOME_Exception)
2674 Unexpect aCatch(SALOME_SalomeException);
2675 MESSAGE("SMESH_subMesh_i::GetElementsByType");
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();
2684 // No sense in returning ids of elements along with ids of nodes:
2685 // when theElemType == SMESH::ALL, return node ids only if
2686 // there are no elements
2687 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2688 return GetNodesId();
2690 aResult->length( nbElements );
2694 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2695 while ( i < nbElements && anIt->more() ) {
2696 const SMDS_MeshElement* anElem = anIt->next();
2697 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2698 aResult[i++] = anElem->GetID();
2701 aResult->length( i );
2703 return aResult._retn();
2706 //=============================================================================
2710 //=============================================================================
2712 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2713 throw (SALOME::SALOME_Exception)
2715 Unexpect aCatch(SALOME_SalomeException);
2716 MESSAGE("SMESH_subMesh_i::GetNodesId");
2717 SMESH::long_array_var aResult = new SMESH::long_array();
2718 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2720 if ( aSMESHDS_Mesh == NULL )
2721 return aResult._retn();
2723 long nbNodes = NbNodes();
2724 aResult->length( nbNodes );
2725 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2726 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2727 aResult[i] = anIt->next()->GetID();
2729 return aResult._retn();
2732 //=============================================================================
2736 //=============================================================================
2738 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2739 throw (SALOME::SALOME_Exception)
2741 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2745 //=============================================================================
2747 * Returns ID of elements for given submesh
2749 //=============================================================================
2750 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2751 throw (SALOME::SALOME_Exception)
2753 SMESH::long_array_var aResult = new SMESH::long_array();
2755 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2756 if(!SM) return aResult._retn();
2758 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2759 if(!SDSM) return aResult._retn();
2761 aResult->length(SDSM->NbElements());
2763 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2765 while ( eIt->more() ) {
2766 aResult[i++] = eIt->next()->GetID();
2769 return aResult._retn();
2773 //=============================================================================
2775 * Returns ID of nodes for given submesh
2776 * If param all==true - returns all nodes, else -
2777 * returns only nodes on shapes.
2779 //=============================================================================
2780 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2781 throw (SALOME::SALOME_Exception)
2783 SMESH::long_array_var aResult = new SMESH::long_array();
2785 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2786 if(!SM) return aResult._retn();
2788 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2789 if(!SDSM) return aResult._retn();
2792 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2793 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2794 while ( nIt->more() ) {
2795 const SMDS_MeshNode* elem = nIt->next();
2796 theElems.insert( elem->GetID() );
2799 else { // all nodes of submesh elements
2800 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2801 while ( eIt->more() ) {
2802 const SMDS_MeshElement* anElem = eIt->next();
2803 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2804 while ( nIt->more() ) {
2805 const SMDS_MeshElement* elem = nIt->next();
2806 theElems.insert( elem->GetID() );
2811 aResult->length(theElems.size());
2812 set<int>::iterator itElem;
2814 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2815 aResult[i++] = *itElem;
2817 return aResult._retn();
2821 //=============================================================================
2823 * Returns type of elements for given submesh
2825 //=============================================================================
2826 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2827 throw (SALOME::SALOME_Exception)
2829 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2830 if(!SM) return SMESH::ALL;
2832 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2833 if(!SDSM) return SMESH::ALL;
2835 if(SDSM->NbElements()==0)
2836 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2838 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2839 const SMDS_MeshElement* anElem = eIt->next();
2840 return ( SMESH::ElementType ) anElem->GetType();
2844 //=============================================================================
2848 //=============================================================================
2850 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2852 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2854 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2859 //=============================================================================
2861 * Get XYZ coordinates of node as list of double
2862 * If there is not node for given ID - returns empty list
2864 //=============================================================================
2866 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2868 SMESH::double_array_var aResult = new SMESH::double_array();
2869 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2870 if ( aSMESHDS_Mesh == NULL )
2871 return aResult._retn();
2874 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2876 return aResult._retn();
2880 aResult[0] = aNode->X();
2881 aResult[1] = aNode->Y();
2882 aResult[2] = aNode->Z();
2883 return aResult._retn();
2887 //=============================================================================
2889 * For given node returns list of IDs of inverse elements
2890 * If there is not node for given ID - returns empty list
2892 //=============================================================================
2894 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2896 SMESH::long_array_var aResult = new SMESH::long_array();
2897 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2898 if ( aSMESHDS_Mesh == NULL )
2899 return aResult._retn();
2902 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2904 return aResult._retn();
2906 // find inverse elements
2907 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2908 TColStd_SequenceOfInteger IDs;
2909 while(eIt->more()) {
2910 const SMDS_MeshElement* elem = eIt->next();
2911 IDs.Append(elem->GetID());
2913 if(IDs.Length()>0) {
2914 aResult->length(IDs.Length());
2916 for(; i<=IDs.Length(); i++) {
2917 aResult[i-1] = IDs.Value(i);
2920 return aResult._retn();
2923 //=============================================================================
2925 * \brief Return position of a node on shape
2927 //=============================================================================
2929 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
2931 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
2932 aNodePosition->shapeID = 0;
2933 aNodePosition->shapeType = GEOM::SHAPE;
2935 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
2936 if ( !mesh ) return aNodePosition;
2938 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
2940 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
2942 aNodePosition->shapeID = pos->GetShapeId();
2943 switch ( pos->GetTypeOfPosition() ) {
2945 aNodePosition->shapeType = GEOM::EDGE;
2946 aNodePosition->params.length(1);
2947 aNodePosition->params[0] =
2948 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
2951 aNodePosition->shapeType = GEOM::FACE;
2952 aNodePosition->params.length(2);
2953 aNodePosition->params[0] =
2954 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
2955 aNodePosition->params[1] =
2956 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
2958 case SMDS_TOP_VERTEX:
2959 aNodePosition->shapeType = GEOM::VERTEX;
2961 case SMDS_TOP_3DSPACE:
2962 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
2963 aNodePosition->shapeType = GEOM::SOLID;
2964 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
2965 aNodePosition->shapeType = GEOM::SHELL;
2971 return aNodePosition;
2974 //=============================================================================
2976 * If given element is node returns IDs of shape from position
2977 * If there is not node for given ID - returns -1
2979 //=============================================================================
2981 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
2983 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2984 if ( aSMESHDS_Mesh == NULL )
2988 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2990 SMDS_PositionPtr pos = aNode->GetPosition();
2994 return pos->GetShapeId();
3001 //=============================================================================
3003 * For given element returns ID of result shape after
3004 * ::FindShape() from SMESH_MeshEditor
3005 * If there is not element for given ID - returns -1
3007 //=============================================================================
3009 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3011 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3012 if ( aSMESHDS_Mesh == NULL )
3015 // try to find element
3016 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3020 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3021 ::SMESH_MeshEditor aMeshEditor(_impl);
3022 int index = aMeshEditor.FindShape( elem );
3030 //=============================================================================
3032 * Returns number of nodes for given element
3033 * If there is not element for given ID - returns -1
3035 //=============================================================================
3037 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3039 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3040 if ( aSMESHDS_Mesh == NULL ) return -1;
3041 // try to find element
3042 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3043 if(!elem) return -1;
3044 return elem->NbNodes();
3048 //=============================================================================
3050 * Returns ID of node by given index for given element
3051 * If there is not element for given ID - returns -1
3052 * If there is not node for given index - returns -2
3054 //=============================================================================
3056 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3058 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3059 if ( aSMESHDS_Mesh == NULL ) return -1;
3060 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3061 if(!elem) return -1;
3062 if( index>=elem->NbNodes() || index<0 ) return -1;
3063 return elem->GetNode(index)->GetID();
3066 //=============================================================================
3068 * Returns IDs of nodes of given element
3070 //=============================================================================
3072 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3074 SMESH::long_array_var aResult = new SMESH::long_array();
3075 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3077 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3079 aResult->length( elem->NbNodes() );
3080 for ( int i = 0; i < elem->NbNodes(); ++i )
3081 aResult[ i ] = elem->GetNode( i )->GetID();
3084 return aResult._retn();
3087 //=============================================================================
3089 * Returns true if given node is medium node
3090 * in given quadratic element
3092 //=============================================================================
3094 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3096 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3097 if ( aSMESHDS_Mesh == NULL ) return false;
3099 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3100 if(!aNode) return false;
3101 // try to find element
3102 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3103 if(!elem) return false;
3105 return elem->IsMediumNode(aNode);
3109 //=============================================================================
3111 * Returns true if given node is medium node
3112 * in one of quadratic elements
3114 //=============================================================================
3116 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3117 SMESH::ElementType theElemType)
3119 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3120 if ( aSMESHDS_Mesh == NULL ) return false;
3123 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3124 if(!aNode) return false;
3126 SMESH_MesherHelper aHelper( *(_impl) );
3128 SMDSAbs_ElementType aType;
3129 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3130 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3131 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3132 else aType = SMDSAbs_All;
3134 return aHelper.IsMedium(aNode,aType);
3138 //=============================================================================
3140 * Returns number of edges for given element
3142 //=============================================================================
3144 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3146 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3147 if ( aSMESHDS_Mesh == NULL ) return -1;
3148 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3149 if(!elem) return -1;
3150 return elem->NbEdges();
3154 //=============================================================================
3156 * Returns number of faces for given element
3158 //=============================================================================
3160 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3162 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3163 if ( aSMESHDS_Mesh == NULL ) return -1;
3164 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3165 if(!elem) return -1;
3166 return elem->NbFaces();
3170 //=============================================================================
3172 * Returns true if given element is polygon
3174 //=============================================================================
3176 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3178 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3179 if ( aSMESHDS_Mesh == NULL ) return false;
3180 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3181 if(!elem) return false;
3182 return elem->IsPoly();
3186 //=============================================================================
3188 * Returns true if given element is quadratic
3190 //=============================================================================
3192 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3194 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3195 if ( aSMESHDS_Mesh == NULL ) return false;
3196 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3197 if(!elem) return false;
3198 return elem->IsQuadratic();
3202 //=============================================================================
3204 * Returns bary center for given element
3206 //=============================================================================
3208 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3210 SMESH::double_array_var aResult = new SMESH::double_array();
3211 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3212 if ( aSMESHDS_Mesh == NULL )
3213 return aResult._retn();
3215 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3217 return aResult._retn();
3219 if(elem->GetType()==SMDSAbs_Volume) {
3220 SMDS_VolumeTool aTool;
3221 if(aTool.Set(elem)) {
3223 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3228 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3230 double x=0., y=0., z=0.;
3231 for(; anIt->more(); ) {
3233 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3247 return aResult._retn();
3251 //=============================================================================
3253 * Create and publish group servants if any groups were imported or created anyhow
3255 //=============================================================================
3257 void SMESH_Mesh_i::CreateGroupServants()
3259 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3261 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3262 while ( groupIt->more() )
3264 ::SMESH_Group* group = groupIt->next();
3265 int anId = group->GetGroupDS()->GetID();
3267 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3268 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3271 SMESH_GroupBase_i* aGroupImpl;
3273 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3274 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3276 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3277 shape = groupOnGeom->GetShape();
3280 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3283 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3284 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3285 aGroupImpl->Register();
3287 SMESH::SMESH_GroupBase_var groupVar =
3288 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3289 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3291 // register CORBA object for persistence
3292 int nextId = _gen_i->RegisterObject( groupVar );
3293 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3295 // publishing of the groups in the study
3296 if ( !aStudy->_is_nil() ) {
3297 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3298 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3303 //=============================================================================
3305 * \brief Return groups cantained in _mapGroups by their IDs
3307 //=============================================================================
3309 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3311 int nbGroups = groupIDs.size();
3312 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3313 aList->length( nbGroups );
3315 list<int>::const_iterator ids = groupIDs.begin();
3316 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3318 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3319 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3320 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3322 aList->length( nbGroups );
3323 return aList._retn();
3326 //=============================================================================
3328 * \brief Return information about imported file
3330 //=============================================================================
3332 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3334 SALOME_MED::MedFileInfo_var res( myFileInfo );
3335 if ( !res.operator->() ) {
3336 res = new SALOME_MED::MedFileInfo;
3338 res->fileSize = res->major = res->minor = res->release = -1;
3343 //=============================================================================
3345 * \brief Check and correct names of mesh groups
3347 //=============================================================================
3349 void SMESH_Mesh_i::checkGroupNames()
3351 int nbGrp = NbGroups();
3355 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3356 if ( aStudy->_is_nil() )
3357 return; // nothing to do
3359 SMESH::ListOfGroups* grpList = 0;
3360 // avoid dump of "GetGroups"
3362 // store python dump into a local variable inside local scope
3363 SMESH::TPythonDump pDump; // do not delete this line of code
3364 grpList = GetGroups();
3367 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3368 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3371 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3372 if ( aGrpSO->_is_nil() )
3374 // correct name of the mesh group if necessary
3375 const char* guiName = aGrpSO->GetName();
3376 if ( strcmp(guiName, aGrp->GetName()) )
3377 aGrp->SetName( guiName );
3381 //=============================================================================
3383 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3385 //=============================================================================
3386 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3388 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3389 CORBA::string_dup(theParameters));
3392 //=============================================================================
3394 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3396 //=============================================================================
3397 char* SMESH_Mesh_i::GetParameters()
3399 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3400 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3403 //=============================================================================
3405 * \brief Returns list of notebook variables used for last Mesh operation
3407 //=============================================================================
3408 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3410 SMESH::string_array_var aResult = new SMESH::string_array();
3411 /* ouv: temporarily disabled
3412 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3414 char *aParameters = GetParameters();
3415 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3416 if(!aStudy->_is_nil()) {
3417 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3418 if(aSections->length() > 0) {
3419 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3420 aResult->length(aVars.length());
3421 for(int i = 0;i < aVars.length();i++)
3422 aResult[i] = CORBA::string_dup( aVars[i]);
3427 return aResult._retn();
3430 //=============================================================================
3432 * \brief Returns statistic of mesh elements
3434 //=============================================================================
3435 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3437 SMESH::long_array_var aRes = new SMESH::long_array();
3438 aRes->length(SMESH::Entity_Last);
3439 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3441 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3443 return aRes._retn();
3444 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3445 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3446 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3447 return aRes._retn();
3450 //=============================================================================
3452 * \brief Collect statistic of mesh elements given by iterator
3454 //=============================================================================
3455 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3456 SMESH::long_array& theInfo)
3458 if (!theItr) return;
3459 while (theItr->more())
3460 theInfo[ theItr->next()->GetEntityType() ]++;