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();
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.push_back( 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.size() );
1005 //NCollection_Map< int >::Iterator anIter( anIds );
1006 for ( int i = 0; i<anIds.size(); i++ )
1008 aResIds[ i ] = anIds[i];
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 vector< 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.push_back( 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.size() );
1153 //NCollection_Map< int >::Iterator aListIter( anIds );
1154 for ( int i = 0; i<anIds.size(); i++ )
1156 aResIds[ i ] = anIds[i];
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 set< 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.insert( aCurrId );
1282 vector< 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.count( aCurrId ) )
1307 anIds.push_back( 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.size() );
1320 for (int i=0; i<anIds.size(); i++ )
1322 aResIds[ i ] = anIds[i];
1324 aResGrp->Add( aResIds );
1326 // Clear python lines, created by CreateGroup() and Add()
1327 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1328 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1329 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1331 // Update Python script
1333 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1334 << &theMainGroups << ", " << &theToolGroups << ", '"
1335 << theName << "' )";
1337 return aResGrp._retn();
1341 return SMESH::SMESH_Group::_nil();
1345 //=============================================================================
1347 \brief Create groups of entities from existing groups of superior dimensions
1349 1) extract all nodes from each group,
1350 2) combine all elements of specified dimension laying on these nodes.
1351 \param theGroups list of source groups
1352 \param theElemType dimension of elements
1353 \param theName name of new group
1354 \return pointer on new group
1356 //=============================================================================
1357 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1358 const SMESH::ListOfGroups& theGroups,
1359 SMESH::ElementType theElemType,
1360 const char* theName )
1361 throw (SALOME::SALOME_Exception)
1363 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1365 if ( !theName || !aMeshDS )
1366 return SMESH::SMESH_Group::_nil();
1368 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1372 // Create map of nodes from all groups
1374 set< int > aNodeMap;
1376 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1378 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1379 if ( CORBA::is_nil( aGrp ) )
1382 SMESH::ElementType aType = aGrp->GetType();
1383 if ( aType == SMESH::ALL )
1385 else if ( aType == SMESH::NODE )
1387 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1388 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1390 int aCurrId = aCurrIds[ i ];
1391 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1393 aNodeMap.insert( aNode->GetID() );
1398 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1399 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1401 int aCurrId = aCurrIds[ i ];
1402 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1405 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1406 while( aNodeIter->more() )
1408 const SMDS_MeshNode* aNode =
1409 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1411 aNodeMap.insert( aNode->GetID() );
1417 // Get result identifiers
1419 vector< int > aResultIds;
1420 if ( theElemType == SMESH::NODE )
1422 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1423 set<int>::iterator iter = aNodeMap.begin();
1424 for ( ; iter != aNodeMap.end(); iter++ )
1425 aResultIds.push_back( *iter);
1429 // Create list of elements of given dimension constructed on the nodes
1430 vector< int > anElemList;
1431 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1432 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1433 set<int>::iterator iter = aNodeMap.begin();
1434 for ( ; iter != aNodeMap.end(); iter++ )
1436 const SMDS_MeshElement* aNode =
1437 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1441 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1442 while( anElemIter->more() )
1444 const SMDS_MeshElement* anElem =
1445 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1446 if ( anElem && anElem->GetType() == anElemType )
1447 anElemList.push_back( anElem->GetID() );
1451 // check whether all nodes of elements are present in nodes map
1452 //NCollection_Map< int >::Iterator anIter( anElemList );
1453 //for ( ; anIter.More(); anIter.Next() )
1454 for (int i=0; i< anElemList.size(); i++)
1456 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1461 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1462 while( aNodeIter->more() )
1464 const SMDS_MeshNode* aNode =
1465 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1466 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1473 aResultIds.push_back( anElem->GetID() );
1479 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1480 if ( aResGrp->_is_nil() )
1481 return SMESH::SMESH_Group::_nil();
1483 // Create array of identifiers
1484 SMESH::long_array_var aResIds = new SMESH::long_array;
1485 aResIds->length( aResultIds.size() );
1487 //NCollection_Map< int >::Iterator aResIter( aResultIds );
1488 //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1489 for (int i=0; i< aResultIds.size(); i++)
1490 aResIds[ i ] = aResultIds[i];
1491 aResGrp->Add( aResIds );
1493 // Remove strings corresponding to group creation
1494 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1495 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1496 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1498 // Update Python script
1500 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1501 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1503 return aResGrp._retn();
1507 return SMESH::SMESH_Group::_nil();
1511 //================================================================================
1513 * \brief Remember GEOM group data
1515 //================================================================================
1517 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1518 CORBA::Object_ptr theSmeshObj)
1520 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1523 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1524 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1525 if ( groupSO->_is_nil() )
1528 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1529 GEOM::GEOM_IGroupOperations_var groupOp =
1530 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1531 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1534 _geomGroupData.push_back( TGeomGroupData() );
1535 TGeomGroupData & groupData = _geomGroupData.back();
1537 CORBA::String_var entry = groupSO->GetID();
1538 groupData._groupEntry = entry.in();
1540 for ( int i = 0; i < ids->length(); ++i )
1541 groupData._indices.insert( ids[i] );
1543 groupData._smeshObject = theSmeshObj;
1546 //================================================================================
1548 * Remove GEOM group data relating to removed smesh object
1550 //================================================================================
1552 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1554 list<TGeomGroupData>::iterator
1555 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1556 for ( ; data != dataEnd; ++data ) {
1557 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1558 _geomGroupData.erase( data );
1564 //================================================================================
1566 * \brief Return new group contents if it has been changed and update group data
1568 //================================================================================
1570 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1572 TopoDS_Shape newShape;
1575 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1576 if ( study->_is_nil() ) return newShape; // means "not changed"
1577 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1578 if ( !groupSO->_is_nil() )
1580 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1581 if ( CORBA::is_nil( groupObj )) return newShape;
1582 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1584 // get indices of group items
1585 set<int> curIndices;
1586 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1587 GEOM::GEOM_IGroupOperations_var groupOp =
1588 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1589 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1590 for ( int i = 0; i < ids->length(); ++i )
1591 curIndices.insert( ids[i] );
1593 if ( groupData._indices == curIndices )
1594 return newShape; // group not changed
1597 groupData._indices = curIndices;
1599 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1600 if ( !geomClient ) return newShape;
1601 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1602 geomClient->RemoveShapeFromBuffer( groupIOR );
1603 newShape = _gen_i->GeomObjectToShape( geomGroup );
1606 if ( newShape.IsNull() ) {
1607 // geom group becomes empty - return empty compound
1608 TopoDS_Compound compound;
1609 BRep_Builder().MakeCompound(compound);
1610 newShape = compound;
1616 //=============================================================================
1618 * \brief Storage of shape and index used in CheckGeomGroupModif()
1620 //=============================================================================
1621 struct TIndexedShape {
1623 TopoDS_Shape _shape;
1624 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1627 //=============================================================================
1629 * \brief Update objects depending on changed geom groups
1631 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1632 * issue 0020210: Update of a smesh group after modification of the associated geom group
1634 //=============================================================================
1636 void SMESH_Mesh_i::CheckGeomGroupModif()
1638 if ( !_impl->HasShapeToMesh() ) return;
1640 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1641 if ( study->_is_nil() ) return;
1643 CORBA::Long nbEntities = NbNodes() + NbElements();
1645 // Check if group contents changed
1647 typedef map< string, TopoDS_Shape > TEntry2Geom;
1648 TEntry2Geom newGroupContents;
1650 list<TGeomGroupData>::iterator
1651 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1652 for ( ; data != dataEnd; ++data )
1654 pair< TEntry2Geom::iterator, bool > it_new =
1655 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1656 bool processedGroup = !it_new.second;
1657 TopoDS_Shape& newShape = it_new.first->second;
1658 if ( !processedGroup )
1659 newShape = newGroupShape( *data );
1660 if ( newShape.IsNull() )
1661 continue; // no changes
1663 if ( processedGroup ) { // update group indices
1664 list<TGeomGroupData>::iterator data2 = data;
1665 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1666 data->_indices = data2->_indices;
1669 // Update SMESH objects according to new GEOM group contents
1671 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1672 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1674 int oldID = submesh->GetId();
1675 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1677 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1679 // update hypotheses
1680 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1681 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1682 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1684 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1685 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1687 // care of submeshes
1688 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1689 int newID = newSubmesh->GetId();
1690 if ( newID != oldID ) {
1691 _mapSubMesh [ newID ] = newSubmesh;
1692 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1693 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1694 _mapSubMesh. erase(oldID);
1695 _mapSubMesh_i. erase(oldID);
1696 _mapSubMeshIor.erase(oldID);
1697 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1702 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1703 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1704 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1706 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1708 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1709 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1710 ds->SetShape( newShape );
1715 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1716 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1718 // Remove groups and submeshes basing on removed sub-shapes
1720 TopTools_MapOfShape newShapeMap;
1721 TopoDS_Iterator shapeIt( newShape );
1722 for ( ; shapeIt.More(); shapeIt.Next() )
1723 newShapeMap.Add( shapeIt.Value() );
1725 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1726 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1728 if ( newShapeMap.Contains( shapeIt.Value() ))
1730 TopTools_IndexedMapOfShape oldShapeMap;
1731 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1732 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1734 const TopoDS_Shape& oldShape = oldShapeMap(i);
1735 int oldInd = meshDS->ShapeToIndex( oldShape );
1737 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1738 if ( i_smIor != _mapSubMeshIor.end() ) {
1739 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1742 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1743 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1745 // check if a group bases on oldInd shape
1746 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1747 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1748 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1749 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1751 RemoveGroup( i_grp->second ); // several groups can base on same shape
1752 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1757 // Reassign hypotheses and update groups after setting the new shape to mesh
1759 // collect anassigned hypotheses
1760 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1761 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1762 TShapeHypList assignedHyps;
1763 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1765 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1766 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1767 if ( !hyps.empty() ) {
1768 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1769 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1770 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1773 // collect shapes supporting groups
1774 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1775 TShapeTypeList groupData;
1776 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1777 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1778 for ( ; grIt != groups.end(); ++grIt )
1780 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1782 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1784 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1785 _impl->ShapeToMesh( newShape );
1787 // reassign hypotheses
1788 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1789 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1791 TIndexedShape& geom = indS_hyps->first;
1792 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1793 int oldID = geom._index;
1794 int newID = meshDS->ShapeToIndex( geom._shape );
1797 if ( oldID == 1 ) { // main shape
1799 geom._shape = newShape;
1801 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1802 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1803 // care of submeshes
1804 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1805 if ( newID != oldID ) {
1806 _mapSubMesh [ newID ] = newSubmesh;
1807 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1808 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1809 _mapSubMesh. erase(oldID);
1810 _mapSubMesh_i. erase(oldID);
1811 _mapSubMeshIor.erase(oldID);
1812 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1816 TShapeTypeList::iterator geomType = groupData.begin();
1817 for ( ; geomType != groupData.end(); ++geomType )
1819 const TIndexedShape& geom = geomType->first;
1820 int oldID = geom._index;
1821 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1824 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1825 CORBA::String_var name = groupSO->GetName();
1827 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1829 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1830 group_i->changeLocalId( newID );
1833 break; // everything has been updated
1836 } // loop on group data
1840 CORBA::Long newNbEntities = NbNodes() + NbElements();
1841 list< SALOMEDS::SObject_var > soToUpdateIcons;
1842 if ( newNbEntities != nbEntities )
1844 // Add all SObjects with icons
1845 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1847 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1848 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1849 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1851 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1852 i_gr != _mapGroups.end(); ++i_gr ) // groups
1853 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1856 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1857 for ( ; so != soToUpdateIcons.end(); ++so )
1858 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1861 //=============================================================================
1863 * \brief Create standalone group instead if group on geometry
1866 //=============================================================================
1868 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1870 SMESH::SMESH_Group_var aGroup;
1871 if ( theGroup->_is_nil() )
1872 return aGroup._retn();
1874 Unexpect aCatch(SALOME_SalomeException);
1876 SMESH_GroupBase_i* aGroupToRem =
1877 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1879 return aGroup._retn();
1881 int anId = aGroupToRem->GetLocalID();
1882 if ( !_impl->ConvertToStandalone( anId ) )
1883 return aGroup._retn();
1884 removeGeomGroupData( theGroup );
1886 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1888 // remove old instance of group from own map
1889 _mapGroups.erase( anId );
1891 SALOMEDS::StudyBuilder_var builder;
1892 SALOMEDS::SObject_var aGroupSO;
1893 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1894 if ( !aStudy->_is_nil() ) {
1895 builder = aStudy->NewBuilder();
1896 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1897 if ( !aGroupSO->_is_nil() ) {
1899 // remove reference to geometry
1900 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1901 for ( ; chItr->More(); chItr->Next() )
1902 // Remove group's child SObject
1903 builder->RemoveObject( chItr->Value() );
1905 // Update Python script
1906 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1907 << aGroupSO << " )";
1911 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1912 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1913 aGroupImpl->Register();
1914 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1916 // remember new group in own map
1917 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1918 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1920 // register CORBA object for persistence
1921 //int nextId = _gen_i->RegisterObject( aGroup );
1922 //if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1923 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1925 return aGroup._retn();
1928 //=============================================================================
1932 //=============================================================================
1934 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1936 if(MYDEBUG) MESSAGE( "createSubMesh" );
1937 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1939 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1940 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1941 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1942 SMESH::SMESH_subMesh_var subMesh
1943 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1945 _mapSubMesh[subMeshId] = mySubMesh;
1946 _mapSubMesh_i[subMeshId] = subMeshServant;
1947 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1949 // register CORBA object for persistence
1950 int nextId = _gen_i->RegisterObject( subMesh );
1951 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1953 // to track changes of GEOM groups
1954 addGeomGroupData( theSubShapeObject, subMesh );
1956 return subMesh._retn();
1959 //=======================================================================
1960 //function : getSubMesh
1962 //=======================================================================
1964 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1966 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1967 if ( it == _mapSubMeshIor.end() )
1968 return SMESH::SMESH_subMesh::_nil();
1970 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
1974 //=============================================================================
1978 //=============================================================================
1980 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
1981 GEOM::GEOM_Object_ptr theSubShapeObject )
1983 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
1984 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
1987 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
1989 CORBA::Long shapeId = theSubMesh->GetId();
1990 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
1992 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
1995 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
1996 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
1997 for ( ; hyp != hyps.end(); ++hyp )
1998 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2005 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2006 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2007 removeHypothesis( theSubShapeObject, aHypList[i] );
2010 catch( const SALOME::SALOME_Exception& ) {
2011 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2013 removeGeomGroupData( theSubShapeObject );
2015 int subMeshId = theSubMesh->GetId();
2017 _mapSubMesh.erase(subMeshId);
2018 _mapSubMesh_i.erase(subMeshId);
2019 _mapSubMeshIor.erase(subMeshId);
2020 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2023 //=============================================================================
2027 //=============================================================================
2029 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2030 const char* theName,
2031 const TopoDS_Shape& theShape )
2034 SMESH::SMESH_GroupBase_var aGroup;
2035 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2036 SMESH_GroupBase_i* aGroupImpl;
2037 if ( !theShape.IsNull() )
2038 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2040 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2042 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2043 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2044 aGroupImpl->Register();
2045 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2047 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2048 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2050 // register CORBA object for persistence
2051 int nextId = _gen_i->RegisterObject( aGroup );
2052 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2054 // to track changes of GEOM groups
2055 if ( !theShape.IsNull() ) {
2056 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2057 addGeomGroupData( geom, aGroup );
2060 return aGroup._retn();
2063 //=============================================================================
2065 * SMESH_Mesh_i::removeGroup
2067 * Should be called by ~SMESH_Group_i()
2069 //=============================================================================
2071 void SMESH_Mesh_i::removeGroup( const int theId )
2073 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2074 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2075 removeGeomGroupData( _mapGroups[theId] );
2076 _mapGroups.erase( theId );
2077 _impl->RemoveGroup( theId );
2082 //=============================================================================
2086 //=============================================================================
2088 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2089 throw(SALOME::SALOME_Exception)
2091 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2093 SMESH::log_array_var aLog;
2095 list < SMESHDS_Command * >logDS = _impl->GetLog();
2096 aLog = new SMESH::log_array;
2098 int lg = logDS.size();
2101 list < SMESHDS_Command * >::iterator its = logDS.begin();
2102 while(its != logDS.end()){
2103 SMESHDS_Command *com = *its;
2104 int comType = com->GetType();
2106 int lgcom = com->GetNumber();
2108 const list < int >&intList = com->GetIndexes();
2109 int inum = intList.size();
2111 list < int >::const_iterator ii = intList.begin();
2112 const list < double >&coordList = com->GetCoords();
2113 int rnum = coordList.size();
2115 list < double >::const_iterator ir = coordList.begin();
2116 aLog[indexLog].commandType = comType;
2117 aLog[indexLog].number = lgcom;
2118 aLog[indexLog].coords.length(rnum);
2119 aLog[indexLog].indexes.length(inum);
2120 for(int i = 0; i < rnum; i++){
2121 aLog[indexLog].coords[i] = *ir;
2122 //MESSAGE(" "<<i<<" "<<ir.Value());
2125 for(int i = 0; i < inum; i++){
2126 aLog[indexLog].indexes[i] = *ii;
2127 //MESSAGE(" "<<i<<" "<<ii.Value());
2136 catch(SALOME_Exception & S_ex){
2137 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2139 return aLog._retn();
2143 //=============================================================================
2147 //=============================================================================
2149 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2151 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2155 //=============================================================================
2159 //=============================================================================
2161 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2163 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2167 //=============================================================================
2171 //=============================================================================
2173 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2178 //=============================================================================
2182 //=============================================================================
2184 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2186 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2190 //=============================================================================
2194 //=============================================================================
2196 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2198 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2202 //=============================================================================
2204 * Return mesh editor
2206 //=============================================================================
2208 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2210 // Create MeshEditor
2211 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2212 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2214 // Update Python script
2215 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2217 return aMesh._retn();
2220 //=============================================================================
2222 * Return mesh edition previewer
2224 //=============================================================================
2226 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2228 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2229 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2230 return aMesh._retn();
2233 //=============================================================================
2237 //=============================================================================
2238 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2240 Unexpect aCatch(SALOME_SalomeException);
2241 _impl->SetAutoColor(theAutoColor);
2244 //=============================================================================
2248 //=============================================================================
2249 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2251 Unexpect aCatch(SALOME_SalomeException);
2252 return _impl->GetAutoColor();
2256 //=============================================================================
2258 * Export in different formats
2260 //=============================================================================
2262 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2264 return _impl->HasDuplicatedGroupNamesMED();
2267 void SMESH_Mesh_i::PrepareForWriting (const char* file)
2269 TCollection_AsciiString aFullName ((char*)file);
2270 OSD_Path aPath (aFullName);
2271 OSD_File aFile (aPath);
2272 if (aFile.Exists()) {
2273 // existing filesystem node
2274 if (aFile.KindOfFile() == OSD_FILE) {
2275 if (aFile.IsWriteable()) {
2278 if (aFile.Failed()) {
2279 TCollection_AsciiString msg ("File ");
2280 msg += aFullName + " cannot be replaced.";
2281 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2284 TCollection_AsciiString msg ("File ");
2285 msg += aFullName + " cannot be overwritten.";
2286 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2289 TCollection_AsciiString msg ("Location ");
2290 msg += aFullName + " is not a file.";
2291 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2294 // nonexisting file; check if it can be created
2296 aFile.Build(OSD_WriteOnly, OSD_Protection());
2297 if (aFile.Failed()) {
2298 TCollection_AsciiString msg ("You cannot create the file ");
2299 msg += aFullName + ". Check the directory existance and access rights.";
2300 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2308 void SMESH_Mesh_i::ExportToMED (const char* file,
2309 CORBA::Boolean auto_groups,
2310 SMESH::MED_VERSION theVersion)
2311 throw(SALOME::SALOME_Exception)
2313 Unexpect aCatch(SALOME_SalomeException);
2316 PrepareForWriting(file);
2317 const char* aMeshName = "Mesh";
2318 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2319 if ( !aStudy->_is_nil() ) {
2320 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2321 if ( !aMeshSO->_is_nil() ) {
2322 aMeshName = aMeshSO->GetName();
2323 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2324 if ( !aStudy->GetProperties()->IsLocked() )
2326 SALOMEDS::GenericAttribute_var anAttr;
2327 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2328 SALOMEDS::AttributeExternalFileDef_var aFileName;
2329 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2330 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2331 ASSERT(!aFileName->_is_nil());
2332 aFileName->SetValue(file);
2333 SALOMEDS::AttributeFileType_var aFileType;
2334 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2335 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2336 ASSERT(!aFileType->_is_nil());
2337 aFileType->SetValue("FICHIERMED");
2341 // Update Python script
2342 // set name of mesh before export
2343 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2345 // check names of groups
2348 TPythonDump() << _this() << ".ExportToMED( '"
2349 << file << "', " << auto_groups << ", " << theVersion << " )";
2351 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2354 void SMESH_Mesh_i::ExportMED (const char* file,
2355 CORBA::Boolean auto_groups)
2356 throw(SALOME::SALOME_Exception)
2358 ExportToMED(file,auto_groups,SMESH::MED_V2_1);
2361 void SMESH_Mesh_i::ExportDAT (const char *file)
2362 throw(SALOME::SALOME_Exception)
2364 Unexpect aCatch(SALOME_SalomeException);
2366 // Update Python script
2367 // check names of groups
2369 TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
2372 PrepareForWriting(file);
2373 _impl->ExportDAT(file);
2376 void SMESH_Mesh_i::ExportUNV (const char *file)
2377 throw(SALOME::SALOME_Exception)
2379 Unexpect aCatch(SALOME_SalomeException);
2381 // Update Python script
2382 // check names of groups
2384 TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
2387 PrepareForWriting(file);
2388 _impl->ExportUNV(file);
2391 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2392 throw(SALOME::SALOME_Exception)
2394 Unexpect aCatch(SALOME_SalomeException);
2396 // Update Python script
2397 // check names of groups
2399 TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
2402 PrepareForWriting(file);
2403 _impl->ExportSTL(file, isascii);
2406 //=============================================================================
2410 //=============================================================================
2412 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2414 Unexpect aCatch(SALOME_SalomeException);
2415 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2416 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2417 return aMesh._retn();
2420 //=============================================================================
2424 //=============================================================================
2425 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2427 Unexpect aCatch(SALOME_SalomeException);
2428 return _impl->NbNodes();
2431 //=============================================================================
2435 //=============================================================================
2436 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2438 Unexpect aCatch(SALOME_SalomeException);
2439 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2442 //=============================================================================
2446 //=============================================================================
2447 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2449 Unexpect aCatch(SALOME_SalomeException);
2450 return _impl->Nb0DElements();
2453 //=============================================================================
2457 //=============================================================================
2458 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2460 Unexpect aCatch(SALOME_SalomeException);
2461 return _impl->NbEdges();
2464 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2465 throw(SALOME::SALOME_Exception)
2467 Unexpect aCatch(SALOME_SalomeException);
2468 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2471 //=============================================================================
2475 //=============================================================================
2476 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2478 Unexpect aCatch(SALOME_SalomeException);
2479 return _impl->NbFaces();
2482 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2484 Unexpect aCatch(SALOME_SalomeException);
2485 return _impl->NbTriangles();
2488 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2490 Unexpect aCatch(SALOME_SalomeException);
2491 return _impl->NbQuadrangles();
2494 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2496 Unexpect aCatch(SALOME_SalomeException);
2497 return _impl->NbPolygons();
2500 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2501 throw(SALOME::SALOME_Exception)
2503 Unexpect aCatch(SALOME_SalomeException);
2504 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2507 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2508 throw(SALOME::SALOME_Exception)
2510 Unexpect aCatch(SALOME_SalomeException);
2511 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2514 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2515 throw(SALOME::SALOME_Exception)
2517 Unexpect aCatch(SALOME_SalomeException);
2518 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2521 //=============================================================================
2525 //=============================================================================
2526 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2528 Unexpect aCatch(SALOME_SalomeException);
2529 return _impl->NbVolumes();
2532 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2534 Unexpect aCatch(SALOME_SalomeException);
2535 return _impl->NbTetras();
2538 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2540 Unexpect aCatch(SALOME_SalomeException);
2541 return _impl->NbHexas();
2544 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2546 Unexpect aCatch(SALOME_SalomeException);
2547 return _impl->NbPyramids();
2550 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2552 Unexpect aCatch(SALOME_SalomeException);
2553 return _impl->NbPrisms();
2556 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2558 Unexpect aCatch(SALOME_SalomeException);
2559 return _impl->NbPolyhedrons();
2562 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2563 throw(SALOME::SALOME_Exception)
2565 Unexpect aCatch(SALOME_SalomeException);
2566 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2569 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2570 throw(SALOME::SALOME_Exception)
2572 Unexpect aCatch(SALOME_SalomeException);
2573 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2576 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2577 throw(SALOME::SALOME_Exception)
2579 Unexpect aCatch(SALOME_SalomeException);
2580 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2583 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2584 throw(SALOME::SALOME_Exception)
2586 Unexpect aCatch(SALOME_SalomeException);
2587 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2590 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2591 throw(SALOME::SALOME_Exception)
2593 Unexpect aCatch(SALOME_SalomeException);
2594 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2597 //=============================================================================
2601 //=============================================================================
2602 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2604 Unexpect aCatch(SALOME_SalomeException);
2605 return _mapSubMesh_i.size();
2608 //=============================================================================
2612 //=============================================================================
2613 char* SMESH_Mesh_i::Dump()
2615 std::ostringstream os;
2617 return CORBA::string_dup( os.str().c_str() );
2620 //=============================================================================
2624 //=============================================================================
2625 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2627 // SMESH::long_array_var aResult = new SMESH::long_array();
2628 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2629 // int aMinId = aSMESHDS_Mesh->MinElementID();
2630 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2632 // aResult->length(aMaxId - aMinId + 1);
2634 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2635 // aResult[i++] = id;
2637 // return aResult._retn();
2639 return GetElementsId();
2642 //=============================================================================
2646 //=============================================================================
2648 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2649 throw (SALOME::SALOME_Exception)
2651 Unexpect aCatch(SALOME_SalomeException);
2652 MESSAGE("SMESH_Mesh_i::GetElementsId");
2653 SMESH::long_array_var aResult = new SMESH::long_array();
2654 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2656 if ( aSMESHDS_Mesh == NULL )
2657 return aResult._retn();
2659 long nbElements = NbElements();
2660 aResult->length( nbElements );
2661 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2662 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2663 aResult[i] = anIt->next()->GetID();
2665 return aResult._retn();
2669 //=============================================================================
2673 //=============================================================================
2675 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2676 throw (SALOME::SALOME_Exception)
2678 Unexpect aCatch(SALOME_SalomeException);
2679 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2680 SMESH::long_array_var aResult = new SMESH::long_array();
2681 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2683 if ( aSMESHDS_Mesh == NULL )
2684 return aResult._retn();
2686 long nbElements = NbElements();
2688 // No sense in returning ids of elements along with ids of nodes:
2689 // when theElemType == SMESH::ALL, return node ids only if
2690 // there are no elements
2691 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2692 return GetNodesId();
2694 aResult->length( nbElements );
2698 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2699 while ( i < nbElements && anIt->more() ) {
2700 const SMDS_MeshElement* anElem = anIt->next();
2701 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2702 aResult[i++] = anElem->GetID();
2705 aResult->length( i );
2707 return aResult._retn();
2710 //=============================================================================
2714 //=============================================================================
2716 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2717 throw (SALOME::SALOME_Exception)
2719 Unexpect aCatch(SALOME_SalomeException);
2720 MESSAGE("SMESH_subMesh_i::GetNodesId");
2721 SMESH::long_array_var aResult = new SMESH::long_array();
2722 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2724 if ( aSMESHDS_Mesh == NULL )
2725 return aResult._retn();
2727 long nbNodes = NbNodes();
2728 aResult->length( nbNodes );
2729 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2730 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2731 aResult[i] = anIt->next()->GetID();
2733 return aResult._retn();
2736 //=============================================================================
2740 //=============================================================================
2742 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2743 throw (SALOME::SALOME_Exception)
2745 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2749 //=============================================================================
2751 * Returns ID of elements for given submesh
2753 //=============================================================================
2754 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2755 throw (SALOME::SALOME_Exception)
2757 SMESH::long_array_var aResult = new SMESH::long_array();
2759 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2760 if(!SM) return aResult._retn();
2762 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2763 if(!SDSM) return aResult._retn();
2765 aResult->length(SDSM->NbElements());
2767 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2769 while ( eIt->more() ) {
2770 aResult[i++] = eIt->next()->GetID();
2773 return aResult._retn();
2777 //=============================================================================
2779 * Returns ID of nodes for given submesh
2780 * If param all==true - returns all nodes, else -
2781 * returns only nodes on shapes.
2783 //=============================================================================
2784 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2785 throw (SALOME::SALOME_Exception)
2787 SMESH::long_array_var aResult = new SMESH::long_array();
2789 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2790 if(!SM) return aResult._retn();
2792 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2793 if(!SDSM) return aResult._retn();
2796 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2797 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2798 while ( nIt->more() ) {
2799 const SMDS_MeshNode* elem = nIt->next();
2800 theElems.insert( elem->GetID() );
2803 else { // all nodes of submesh elements
2804 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2805 while ( eIt->more() ) {
2806 const SMDS_MeshElement* anElem = eIt->next();
2807 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2808 while ( nIt->more() ) {
2809 const SMDS_MeshElement* elem = nIt->next();
2810 theElems.insert( elem->GetID() );
2815 aResult->length(theElems.size());
2816 set<int>::iterator itElem;
2818 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2819 aResult[i++] = *itElem;
2821 return aResult._retn();
2825 //=============================================================================
2827 * Returns type of elements for given submesh
2829 //=============================================================================
2830 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2831 throw (SALOME::SALOME_Exception)
2833 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2834 if(!SM) return SMESH::ALL;
2836 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2837 if(!SDSM) return SMESH::ALL;
2839 if(SDSM->NbElements()==0)
2840 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2842 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2843 const SMDS_MeshElement* anElem = eIt->next();
2844 return ( SMESH::ElementType ) anElem->GetType();
2848 //=============================================================================
2852 //=============================================================================
2854 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2856 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2858 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2863 //=============================================================================
2865 * Get XYZ coordinates of node as list of double
2866 * If there is not node for given ID - returns empty list
2868 //=============================================================================
2870 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2872 SMESH::double_array_var aResult = new SMESH::double_array();
2873 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2874 if ( aSMESHDS_Mesh == NULL )
2875 return aResult._retn();
2878 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2880 return aResult._retn();
2884 aResult[0] = aNode->X();
2885 aResult[1] = aNode->Y();
2886 aResult[2] = aNode->Z();
2887 return aResult._retn();
2891 //=============================================================================
2893 * For given node returns list of IDs of inverse elements
2894 * If there is not node for given ID - returns empty list
2896 //=============================================================================
2898 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2900 SMESH::long_array_var aResult = new SMESH::long_array();
2901 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2902 if ( aSMESHDS_Mesh == NULL )
2903 return aResult._retn();
2906 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2908 return aResult._retn();
2910 // find inverse elements
2911 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2912 TColStd_SequenceOfInteger IDs;
2913 while(eIt->more()) {
2914 const SMDS_MeshElement* elem = eIt->next();
2915 IDs.Append(elem->GetID());
2917 if(IDs.Length()>0) {
2918 aResult->length(IDs.Length());
2920 for(; i<=IDs.Length(); i++) {
2921 aResult[i-1] = IDs.Value(i);
2924 return aResult._retn();
2927 //=============================================================================
2929 * \brief Return position of a node on shape
2931 //=============================================================================
2933 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
2935 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
2936 aNodePosition->shapeID = 0;
2937 aNodePosition->shapeType = GEOM::SHAPE;
2939 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
2940 if ( !mesh ) return aNodePosition;
2942 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
2944 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
2946 aNodePosition->shapeID = pos->GetShapeId();
2947 switch ( pos->GetTypeOfPosition() ) {
2949 aNodePosition->shapeType = GEOM::EDGE;
2950 aNodePosition->params.length(1);
2951 aNodePosition->params[0] =
2952 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
2955 aNodePosition->shapeType = GEOM::FACE;
2956 aNodePosition->params.length(2);
2957 aNodePosition->params[0] =
2958 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
2959 aNodePosition->params[1] =
2960 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
2962 case SMDS_TOP_VERTEX:
2963 aNodePosition->shapeType = GEOM::VERTEX;
2965 case SMDS_TOP_3DSPACE:
2966 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
2967 aNodePosition->shapeType = GEOM::SOLID;
2968 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
2969 aNodePosition->shapeType = GEOM::SHELL;
2975 return aNodePosition;
2978 //=============================================================================
2980 * If given element is node returns IDs of shape from position
2981 * If there is not node for given ID - returns -1
2983 //=============================================================================
2985 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
2987 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2988 if ( aSMESHDS_Mesh == NULL )
2992 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2994 SMDS_PositionPtr pos = aNode->GetPosition();
2998 return pos->GetShapeId();
3005 //=============================================================================
3007 * For given element returns ID of result shape after
3008 * ::FindShape() from SMESH_MeshEditor
3009 * If there is not element for given ID - returns -1
3011 //=============================================================================
3013 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3015 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3016 if ( aSMESHDS_Mesh == NULL )
3019 // try to find element
3020 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3024 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3025 ::SMESH_MeshEditor aMeshEditor(_impl);
3026 int index = aMeshEditor.FindShape( elem );
3034 //=============================================================================
3036 * Returns number of nodes for given element
3037 * If there is not element for given ID - returns -1
3039 //=============================================================================
3041 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3043 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3044 if ( aSMESHDS_Mesh == NULL ) return -1;
3045 // try to find element
3046 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3047 if(!elem) return -1;
3048 return elem->NbNodes();
3052 //=============================================================================
3054 * Returns ID of node by given index for given element
3055 * If there is not element for given ID - returns -1
3056 * If there is not node for given index - returns -2
3058 //=============================================================================
3060 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3062 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3063 if ( aSMESHDS_Mesh == NULL ) return -1;
3064 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3065 if(!elem) return -1;
3066 if( index>=elem->NbNodes() || index<0 ) return -1;
3067 return elem->GetNode(index)->GetID();
3070 //=============================================================================
3072 * Returns IDs of nodes of given element
3074 //=============================================================================
3076 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3078 SMESH::long_array_var aResult = new SMESH::long_array();
3079 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3081 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3083 aResult->length( elem->NbNodes() );
3084 for ( int i = 0; i < elem->NbNodes(); ++i )
3085 aResult[ i ] = elem->GetNode( i )->GetID();
3088 return aResult._retn();
3091 //=============================================================================
3093 * Returns true if given node is medium node
3094 * in given quadratic element
3096 //=============================================================================
3098 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3100 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3101 if ( aSMESHDS_Mesh == NULL ) return false;
3103 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3104 if(!aNode) return false;
3105 // try to find element
3106 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3107 if(!elem) return false;
3109 return elem->IsMediumNode(aNode);
3113 //=============================================================================
3115 * Returns true if given node is medium node
3116 * in one of quadratic elements
3118 //=============================================================================
3120 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3121 SMESH::ElementType theElemType)
3123 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3124 if ( aSMESHDS_Mesh == NULL ) return false;
3127 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3128 if(!aNode) return false;
3130 SMESH_MesherHelper aHelper( *(_impl) );
3132 SMDSAbs_ElementType aType;
3133 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3134 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3135 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3136 else aType = SMDSAbs_All;
3138 return aHelper.IsMedium(aNode,aType);
3142 //=============================================================================
3144 * Returns number of edges for given element
3146 //=============================================================================
3148 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3150 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3151 if ( aSMESHDS_Mesh == NULL ) return -1;
3152 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3153 if(!elem) return -1;
3154 return elem->NbEdges();
3158 //=============================================================================
3160 * Returns number of faces for given element
3162 //=============================================================================
3164 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3166 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3167 if ( aSMESHDS_Mesh == NULL ) return -1;
3168 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3169 if(!elem) return -1;
3170 return elem->NbFaces();
3174 //=============================================================================
3176 * Returns true if given element is polygon
3178 //=============================================================================
3180 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3182 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3183 if ( aSMESHDS_Mesh == NULL ) return false;
3184 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3185 if(!elem) return false;
3186 return elem->IsPoly();
3190 //=============================================================================
3192 * Returns true if given element is quadratic
3194 //=============================================================================
3196 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3198 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3199 if ( aSMESHDS_Mesh == NULL ) return false;
3200 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3201 if(!elem) return false;
3202 return elem->IsQuadratic();
3206 //=============================================================================
3208 * Returns bary center for given element
3210 //=============================================================================
3212 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3214 SMESH::double_array_var aResult = new SMESH::double_array();
3215 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3216 if ( aSMESHDS_Mesh == NULL )
3217 return aResult._retn();
3219 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3221 return aResult._retn();
3223 if(elem->GetType()==SMDSAbs_Volume) {
3224 SMDS_VolumeTool aTool;
3225 if(aTool.Set(elem)) {
3227 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3232 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3234 double x=0., y=0., z=0.;
3235 for(; anIt->more(); ) {
3237 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3251 return aResult._retn();
3255 //=============================================================================
3257 * Create and publish group servants if any groups were imported or created anyhow
3259 //=============================================================================
3261 void SMESH_Mesh_i::CreateGroupServants()
3263 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3265 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3266 while ( groupIt->more() )
3268 ::SMESH_Group* group = groupIt->next();
3269 int anId = group->GetGroupDS()->GetID();
3271 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3272 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3275 SMESH_GroupBase_i* aGroupImpl;
3277 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3278 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3280 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3281 shape = groupOnGeom->GetShape();
3284 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3287 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3288 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3289 aGroupImpl->Register();
3291 SMESH::SMESH_GroupBase_var groupVar =
3292 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3293 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3295 // register CORBA object for persistence
3296 int nextId = _gen_i->RegisterObject( groupVar );
3297 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3299 // publishing of the groups in the study
3300 if ( !aStudy->_is_nil() ) {
3301 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3302 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3307 //=============================================================================
3309 * \brief Return groups cantained in _mapGroups by their IDs
3311 //=============================================================================
3313 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3315 int nbGroups = groupIDs.size();
3316 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3317 aList->length( nbGroups );
3319 list<int>::const_iterator ids = groupIDs.begin();
3320 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3322 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3323 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3324 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3326 aList->length( nbGroups );
3327 return aList._retn();
3330 //=============================================================================
3332 * \brief Return information about imported file
3334 //=============================================================================
3336 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3338 SALOME_MED::MedFileInfo_var res( myFileInfo );
3339 if ( !res.operator->() ) {
3340 res = new SALOME_MED::MedFileInfo;
3342 res->fileSize = res->major = res->minor = res->release = -1;
3347 //=============================================================================
3349 * \brief Check and correct names of mesh groups
3351 //=============================================================================
3353 void SMESH_Mesh_i::checkGroupNames()
3355 int nbGrp = NbGroups();
3359 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3360 if ( aStudy->_is_nil() )
3361 return; // nothing to do
3363 SMESH::ListOfGroups* grpList = 0;
3364 // avoid dump of "GetGroups"
3366 // store python dump into a local variable inside local scope
3367 SMESH::TPythonDump pDump; // do not delete this line of code
3368 grpList = GetGroups();
3371 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3372 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3375 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3376 if ( aGrpSO->_is_nil() )
3378 // correct name of the mesh group if necessary
3379 const char* guiName = aGrpSO->GetName();
3380 if ( strcmp(guiName, aGrp->GetName()) )
3381 aGrp->SetName( guiName );
3385 //=============================================================================
3387 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3389 //=============================================================================
3390 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3392 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3393 CORBA::string_dup(theParameters));
3396 //=============================================================================
3398 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3400 //=============================================================================
3401 char* SMESH_Mesh_i::GetParameters()
3403 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3404 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3407 //=============================================================================
3409 * \brief Returns list of notebook variables used for last Mesh operation
3411 //=============================================================================
3412 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3414 SMESH::string_array_var aResult = new SMESH::string_array();
3415 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3417 char *aParameters = GetParameters();
3418 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3419 if(!aStudy->_is_nil()) {
3420 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3421 if(aSections->length() > 0) {
3422 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3423 aResult->length(aVars.length());
3424 for(int i = 0;i < aVars.length();i++)
3425 aResult[i] = CORBA::string_dup( aVars[i]);
3429 return aResult._retn();
3432 //=============================================================================
3434 * \brief Returns statistic of mesh elements
3436 //=============================================================================
3437 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3439 SMESH::long_array_var aRes = new SMESH::long_array();
3440 aRes->length(SMESH::Entity_Last);
3441 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3443 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3445 return aRes._retn();
3446 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3447 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3448 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3449 return aRes._retn();
3452 //=============================================================================
3454 * \brief Collect statistic of mesh elements given by iterator
3456 //=============================================================================
3457 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3458 SMESH::long_array& theInfo)
3460 if (!theItr) return;
3461 while (theItr->more())
3462 theInfo[ theItr->next()->GetEntityType() ]++;