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 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
526 SMESH::SMESH_Hypothesis_ptr anHyp)
528 if(MYDEBUG) MESSAGE("removeHypothesis()");
529 // **** proposer liste de subShape (selection multiple)
531 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
532 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
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",
540 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
543 TopoDS_Shape myLocSubShape;
544 //use PseudoShape in case if mesh has no shape
546 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
548 myLocSubShape = _impl->GetShapeToMesh();
550 int hypId = myHyp->GetId();
551 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
552 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
553 _mapHypo.erase( hypId );
555 catch(SALOME_Exception & S_ex)
557 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
562 //=============================================================================
566 //=============================================================================
568 SMESH::ListOfHypothesis *
569 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
570 throw(SALOME::SALOME_Exception)
572 Unexpect aCatch(SALOME_SalomeException);
573 if (MYDEBUG) MESSAGE("GetHypothesisList");
574 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
575 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
578 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
581 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
582 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
583 myLocSubShape = _impl->GetShapeToMesh();
584 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
585 int i = 0, n = aLocalList.size();
588 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
589 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
590 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
591 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
596 catch(SALOME_Exception & S_ex) {
597 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
600 return aList._retn();
603 //=============================================================================
607 //=============================================================================
608 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
609 const char* theName )
610 throw(SALOME::SALOME_Exception)
612 Unexpect aCatch(SALOME_SalomeException);
613 MESSAGE("SMESH_Mesh_i::GetSubMesh");
614 if (CORBA::is_nil(aSubShapeObject))
615 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
618 SMESH::SMESH_subMesh_var subMesh;
619 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
621 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
623 //Get or Create the SMESH_subMesh object implementation
625 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
626 subMesh = getSubMesh( subMeshId );
628 // create a new subMesh object servant if there is none for the shape
629 if ( subMesh->_is_nil() )
630 subMesh = createSubMesh( aSubShapeObject );
631 if ( _gen_i->CanPublishInStudy( subMesh )) {
632 SALOMEDS::SObject_var aSO =
633 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
634 subMesh, aSubShapeObject, theName );
635 if ( !aSO->_is_nil()) {
636 // Update Python script
637 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
638 << aSubShapeObject << ", '" << theName << "' )";
642 catch(SALOME_Exception & S_ex) {
643 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
645 return subMesh._retn();
648 //=============================================================================
652 //=============================================================================
654 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
655 throw (SALOME::SALOME_Exception)
657 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
658 if ( theSubMesh->_is_nil() )
661 GEOM::GEOM_Object_var aSubShapeObject;
662 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
663 if ( !aStudy->_is_nil() ) {
664 // Remove submesh's SObject
665 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
666 if ( !anSO->_is_nil() ) {
667 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
668 SALOMEDS::SObject_var anObj, aRef;
669 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
670 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
672 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
674 // Update Python script
675 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
679 removeSubMesh( theSubMesh, aSubShapeObject.in() );
682 //=============================================================================
686 //=============================================================================
687 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
688 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
690 switch (theElemType) {
695 CASE2STRING( VOLUME );
701 //=============================================================================
705 //=============================================================================
707 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
708 const char* theName )
709 throw(SALOME::SALOME_Exception)
711 Unexpect aCatch(SALOME_SalomeException);
712 SMESH::SMESH_Group_var aNewGroup =
713 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
715 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
716 SALOMEDS::SObject_var aSO =
717 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
718 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
719 if ( !aSO->_is_nil()) {
720 // Update Python script
721 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
722 << ElementTypeString(theElemType) << ", '" << theName << "' )";
725 return aNewGroup._retn();
729 //=============================================================================
733 //=============================================================================
734 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
736 GEOM::GEOM_Object_ptr theGeomObj)
737 throw(SALOME::SALOME_Exception)
739 Unexpect aCatch(SALOME_SalomeException);
740 SMESH::SMESH_GroupOnGeom_var aNewGroup;
742 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
743 if ( !aShape.IsNull() )
745 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
746 ( createGroup( theElemType, theName, aShape ));
748 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
749 SALOMEDS::SObject_var aSO =
750 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
751 aNewGroup, theGeomObj, theName);
752 if ( !aSO->_is_nil()) {
753 // Update Python script
754 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
755 << ElementTypeString(theElemType) << ", '" << theName << "', "
756 << theGeomObj << " )";
761 return aNewGroup._retn();
764 //=============================================================================
768 //=============================================================================
770 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
771 throw (SALOME::SALOME_Exception)
773 if ( theGroup->_is_nil() )
776 SMESH_GroupBase_i* aGroup =
777 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
781 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
782 if ( !aStudy->_is_nil() ) {
783 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
785 if ( !aGroupSO->_is_nil() ) {
786 // Update Python script
787 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
789 // Remove group's SObject
790 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
794 // Remove the group from SMESH data structures
795 removeGroup( aGroup->GetLocalID() );
798 //=============================================================================
799 /*! RemoveGroupWithContents
800 * Remove group with its contents
802 //=============================================================================
803 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
804 throw (SALOME::SALOME_Exception)
806 if ( theGroup->_is_nil() )
809 SMESH_GroupBase_i* aGroup =
810 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
814 SMESH::long_array_var anIds = aGroup->GetListOfID();
815 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
817 // Update Python script
818 TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
821 if ( aGroup->GetType() == SMESH::NODE )
822 aMeshEditor->RemoveNodes( anIds );
824 aMeshEditor->RemoveElements( anIds );
827 RemoveGroup( theGroup );
829 // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
830 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
831 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
835 //================================================================================
837 * \brief Get the list of groups existing in the mesh
838 * \retval SMESH::ListOfGroups * - list of groups
840 //================================================================================
842 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
844 Unexpect aCatch(SALOME_SalomeException);
845 if (MYDEBUG) MESSAGE("GetGroups");
847 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
850 TPythonDump aPythonDump;
851 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
855 aList->length( _mapGroups.size() );
857 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
858 for ( ; it != _mapGroups.end(); it++ ) {
859 if ( CORBA::is_nil( it->second )) continue;
860 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
862 if (i > 1) aPythonDump << ", ";
863 aPythonDump << it->second;
867 catch(SALOME_Exception & S_ex) {
868 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
871 // Update Python script
872 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
873 aPythonDump << " ] = " << _this() << ".GetGroups()";
875 return aList._retn();
877 //=============================================================================
879 * Get number of groups existing in the mesh
881 //=============================================================================
883 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
885 Unexpect aCatch(SALOME_SalomeException);
886 return _mapGroups.size();
889 //=============================================================================
891 * New group is created. All mesh elements that are
892 * present in initial groups are added to the new one
894 //=============================================================================
895 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
896 SMESH::SMESH_GroupBase_ptr theGroup2,
897 const char* theName )
898 throw (SALOME::SALOME_Exception)
902 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
903 theGroup1->GetType() != theGroup2->GetType() )
904 return SMESH::SMESH_Group::_nil();
907 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
908 if ( aResGrp->_is_nil() )
909 return SMESH::SMESH_Group::_nil();
911 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
912 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
914 TColStd_MapOfInteger aResMap;
916 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
917 aResMap.Add( anIds1[ i1 ] );
919 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
920 aResMap.Add( anIds2[ i2 ] );
922 SMESH::long_array_var aResIds = new SMESH::long_array;
923 aResIds->length( aResMap.Extent() );
926 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
927 for( ; anIter.More(); anIter.Next() )
928 aResIds[ resI++ ] = anIter.Key();
930 aResGrp->Add( aResIds );
932 // Clear python lines, created by CreateGroup() and Add()
933 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
934 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
935 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
937 // Update Python script
938 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
939 << theGroup1 << ", " << theGroup2 << ", '"
942 return aResGrp._retn();
946 return SMESH::SMESH_Group::_nil();
950 //=============================================================================
952 \brief Union list of groups. New group is created. All mesh elements that are
953 present in initial groups are added to the new one.
954 \param theGroups list of groups
955 \param theName name of group to be created
956 \return pointer on the group
958 //=============================================================================
959 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
960 const char* theName )
961 throw (SALOME::SALOME_Exception)
964 return SMESH::SMESH_Group::_nil();
969 SMESH::ElementType aType = SMESH::ALL;
970 for ( int g = 0, n = theGroups.length(); g < n; g++ )
972 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
973 if ( CORBA::is_nil( aGrp ) )
977 SMESH::ElementType aCurrType = aGrp->GetType();
978 if ( aType == SMESH::ALL )
982 if ( aType != aCurrType )
983 return SMESH::SMESH_Group::_nil();
987 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
988 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
990 int aCurrId = aCurrIds[ i ];
991 anIds.push_back( aCurrId );
996 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
997 if ( aResGrp->_is_nil() )
998 return SMESH::SMESH_Group::_nil();
1000 // Create array of identifiers
1001 SMESH::long_array_var aResIds = new SMESH::long_array;
1002 aResIds->length( anIds.size() );
1004 //NCollection_Map< int >::Iterator anIter( anIds );
1005 for ( int i = 0; i<anIds.size(); i++ )
1007 aResIds[ i ] = anIds[i];
1009 aResGrp->Add( aResIds );
1011 // Clear python lines, created by CreateGroup() and Add()
1012 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1013 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1014 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1016 // Update Python script
1018 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1019 << &theGroups << ", '" << theName << "' )";
1021 return aResGrp._retn();
1025 return SMESH::SMESH_Group::_nil();
1029 //=============================================================================
1031 * New group is created. All mesh elements that are
1032 * present in both initial groups are added to the new one.
1034 //=============================================================================
1035 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1036 SMESH::SMESH_GroupBase_ptr theGroup2,
1037 const char* theName )
1038 throw (SALOME::SALOME_Exception)
1040 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1041 theGroup1->GetType() != theGroup2->GetType() )
1042 return SMESH::SMESH_Group::_nil();
1044 // Create Intersection
1045 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1046 if ( aResGrp->_is_nil() )
1049 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1050 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1052 TColStd_MapOfInteger aMap1;
1054 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1055 aMap1.Add( anIds1[ i1 ] );
1057 TColStd_SequenceOfInteger aSeq;
1059 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1060 if ( aMap1.Contains( anIds2[ i2 ] ) )
1061 aSeq.Append( anIds2[ i2 ] );
1063 SMESH::long_array_var aResIds = new SMESH::long_array;
1064 aResIds->length( aSeq.Length() );
1066 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1067 aResIds[ resI ] = aSeq( resI + 1 );
1069 aResGrp->Add( aResIds );
1071 // Clear python lines, created by CreateGroup() and Add()
1072 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1073 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1074 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1076 // Update Python script
1077 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1078 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1080 return aResGrp._retn();
1083 //=============================================================================
1085 \brief Intersect list of groups. New group is created. All mesh elements that
1086 are present in all initial groups simultaneously are added to the new one.
1087 \param theGroups list of groups
1088 \param theName name of group to be created
1089 \return pointer on the group
1091 //=============================================================================
1092 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1093 const SMESH::ListOfGroups& theGroups, const char* theName )
1094 throw (SALOME::SALOME_Exception)
1097 return SMESH::SMESH_Group::_nil();
1101 NCollection_DataMap< int, int > anIdToCount;
1102 SMESH::ElementType aType = SMESH::ALL;
1103 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1105 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1106 if ( CORBA::is_nil( aGrp ) )
1110 SMESH::ElementType aCurrType = aGrp->GetType();
1111 if ( aType == SMESH::ALL )
1115 if ( aType != aCurrType )
1116 return SMESH::SMESH_Group::_nil();
1119 // calculates number of occurance ids in groups
1120 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1121 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1123 int aCurrId = aCurrIds[ i ];
1124 if ( !anIdToCount.IsBound( aCurrId ) )
1125 anIdToCount.Bind( aCurrId, 1 );
1127 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1131 // create map of ids
1132 int nbGrp = theGroups.length();
1133 vector< int > anIds;
1134 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1135 for ( ; anIter.More(); anIter.Next() )
1137 int aCurrId = anIter.Key();
1138 int aCurrNb = anIter.Value();
1139 if ( aCurrNb == nbGrp )
1140 anIds.push_back( aCurrId );
1144 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1145 if ( aResGrp->_is_nil() )
1146 return SMESH::SMESH_Group::_nil();
1148 // Create array of identifiers
1149 SMESH::long_array_var aResIds = new SMESH::long_array;
1150 aResIds->length( anIds.size() );
1152 //NCollection_Map< int >::Iterator aListIter( anIds );
1153 for ( int i = 0; i<anIds.size(); i++ )
1155 aResIds[ i ] = anIds[i];
1157 aResGrp->Add( aResIds );
1159 // Clear python lines, created by CreateGroup() and Add()
1160 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1161 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1162 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1164 // Update Python script
1166 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1167 << &theGroups << ", '" << theName << "' )";
1169 return aResGrp._retn();
1173 return SMESH::SMESH_Group::_nil();
1177 //=============================================================================
1179 * New group is created. All mesh elements that are present in
1180 * main group but do not present in tool group are added to the new one
1182 //=============================================================================
1183 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1184 SMESH::SMESH_GroupBase_ptr theGroup2,
1185 const char* theName )
1186 throw (SALOME::SALOME_Exception)
1188 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1189 theGroup1->GetType() != theGroup2->GetType() )
1190 return SMESH::SMESH_Group::_nil();
1193 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1194 if ( aResGrp->_is_nil() )
1197 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1198 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1200 TColStd_MapOfInteger aMap2;
1202 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1203 aMap2.Add( anIds2[ i2 ] );
1205 TColStd_SequenceOfInteger aSeq;
1206 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1207 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1208 aSeq.Append( anIds1[ i1 ] );
1210 SMESH::long_array_var aResIds = new SMESH::long_array;
1211 aResIds->length( aSeq.Length() );
1213 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1214 aResIds[ resI ] = aSeq( resI + 1 );
1216 aResGrp->Add( aResIds );
1218 // Clear python lines, created by CreateGroup() and Add()
1219 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1220 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1221 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1223 // Update Python script
1224 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1225 << theGroup1 << ", " << theGroup2 << ", '"
1226 << theName << "' )";
1228 return aResGrp._retn();
1231 //=============================================================================
1233 \brief Cut lists of groups. New group is created. All mesh elements that are
1234 present in main groups but do not present in tool groups are added to the new one
1235 \param theMainGroups list of main groups
1236 \param theToolGroups list of tool groups
1237 \param theName name of group to be created
1238 \return pointer on the group
1240 //=============================================================================
1241 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1242 const SMESH::ListOfGroups& theMainGroups,
1243 const SMESH::ListOfGroups& theToolGroups,
1244 const char* theName )
1245 throw (SALOME::SALOME_Exception)
1248 return SMESH::SMESH_Group::_nil();
1252 set< int > aToolIds;
1253 SMESH::ElementType aType = SMESH::ALL;
1255 // iterate through tool groups
1256 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1258 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1259 if ( CORBA::is_nil( aGrp ) )
1263 SMESH::ElementType aCurrType = aGrp->GetType();
1264 if ( aType == SMESH::ALL )
1268 if ( aType != aCurrType )
1269 return SMESH::SMESH_Group::_nil();
1273 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1274 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1276 int aCurrId = aCurrIds[ i ];
1277 aToolIds.insert( aCurrId );
1281 vector< int > anIds; // result
1283 // Iterate through main group
1284 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1286 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1287 if ( CORBA::is_nil( aGrp ) )
1291 SMESH::ElementType aCurrType = aGrp->GetType();
1292 if ( aType == SMESH::ALL )
1296 if ( aType != aCurrType )
1297 return SMESH::SMESH_Group::_nil();
1301 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1302 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1304 int aCurrId = aCurrIds[ i ];
1305 if ( !aToolIds.count( aCurrId ) )
1306 anIds.push_back( aCurrId );
1311 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1312 if ( aResGrp->_is_nil() )
1313 return SMESH::SMESH_Group::_nil();
1315 // Create array of identifiers
1316 SMESH::long_array_var aResIds = new SMESH::long_array;
1317 aResIds->length( anIds.size() );
1319 for (int i=0; i<anIds.size(); i++ )
1321 aResIds[ i ] = anIds[i];
1323 aResGrp->Add( aResIds );
1325 // Clear python lines, created by CreateGroup() and Add()
1326 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1327 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1328 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1330 // Update Python script
1332 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1333 << &theMainGroups << ", " << &theToolGroups << ", '"
1334 << theName << "' )";
1336 return aResGrp._retn();
1340 return SMESH::SMESH_Group::_nil();
1344 //=============================================================================
1346 \brief Create groups of entities from existing groups of superior dimensions
1348 1) extract all nodes from each group,
1349 2) combine all elements of specified dimension laying on these nodes.
1350 \param theGroups list of source groups
1351 \param theElemType dimension of elements
1352 \param theName name of new group
1353 \return pointer on new group
1355 //=============================================================================
1356 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1357 const SMESH::ListOfGroups& theGroups,
1358 SMESH::ElementType theElemType,
1359 const char* theName )
1360 throw (SALOME::SALOME_Exception)
1362 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1364 if ( !theName || !aMeshDS )
1365 return SMESH::SMESH_Group::_nil();
1367 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1371 // Create map of nodes from all groups
1373 set< int > aNodeMap;
1375 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1377 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1378 if ( CORBA::is_nil( aGrp ) )
1381 SMESH::ElementType aType = aGrp->GetType();
1382 if ( aType == SMESH::ALL )
1384 else if ( aType == SMESH::NODE )
1386 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1387 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1389 int aCurrId = aCurrIds[ i ];
1390 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1392 aNodeMap.insert( aNode->GetID() );
1397 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1398 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1400 int aCurrId = aCurrIds[ i ];
1401 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1404 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1405 while( aNodeIter->more() )
1407 const SMDS_MeshNode* aNode =
1408 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1410 aNodeMap.insert( aNode->GetID() );
1416 // Get result identifiers
1418 vector< int > aResultIds;
1419 if ( theElemType == SMESH::NODE )
1421 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1422 set<int>::iterator iter = aNodeMap.begin();
1423 for ( ; iter != aNodeMap.end(); iter++ )
1424 aResultIds.push_back( *iter);
1428 // Create list of elements of given dimension constructed on the nodes
1429 vector< int > anElemList;
1430 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1431 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1432 set<int>::iterator iter = aNodeMap.begin();
1433 for ( ; iter != aNodeMap.end(); iter++ )
1435 const SMDS_MeshElement* aNode =
1436 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1440 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1441 while( anElemIter->more() )
1443 const SMDS_MeshElement* anElem =
1444 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1445 if ( anElem && anElem->GetType() == anElemType )
1446 anElemList.push_back( anElem->GetID() );
1450 // check whether all nodes of elements are present in nodes map
1451 //NCollection_Map< int >::Iterator anIter( anElemList );
1452 //for ( ; anIter.More(); anIter.Next() )
1453 for (int i=0; i< anElemList.size(); i++)
1455 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1460 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1461 while( aNodeIter->more() )
1463 const SMDS_MeshNode* aNode =
1464 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1465 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1472 aResultIds.push_back( anElem->GetID() );
1478 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1479 if ( aResGrp->_is_nil() )
1480 return SMESH::SMESH_Group::_nil();
1482 // Create array of identifiers
1483 SMESH::long_array_var aResIds = new SMESH::long_array;
1484 aResIds->length( aResultIds.size() );
1486 //NCollection_Map< int >::Iterator aResIter( aResultIds );
1487 //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1488 for (int i=0; i< aResultIds.size(); i++)
1489 aResIds[ i ] = aResultIds[i];
1490 aResGrp->Add( aResIds );
1492 // Remove strings corresponding to group creation
1493 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1494 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1495 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1497 // Update Python script
1499 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1500 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1502 return aResGrp._retn();
1506 return SMESH::SMESH_Group::_nil();
1510 //================================================================================
1512 * \brief Remember GEOM group data
1514 //================================================================================
1516 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1517 CORBA::Object_ptr theSmeshObj)
1519 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1522 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1523 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1524 if ( groupSO->_is_nil() )
1527 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1528 GEOM::GEOM_IGroupOperations_var groupOp =
1529 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1530 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1533 _geomGroupData.push_back( TGeomGroupData() );
1534 TGeomGroupData & groupData = _geomGroupData.back();
1536 CORBA::String_var entry = groupSO->GetID();
1537 groupData._groupEntry = entry.in();
1539 for ( int i = 0; i < ids->length(); ++i )
1540 groupData._indices.insert( ids[i] );
1542 groupData._smeshObject = theSmeshObj;
1545 //================================================================================
1547 * Remove GEOM group data relating to removed smesh object
1549 //================================================================================
1551 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1553 list<TGeomGroupData>::iterator
1554 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1555 for ( ; data != dataEnd; ++data ) {
1556 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1557 _geomGroupData.erase( data );
1563 //================================================================================
1565 * \brief Return new group contents if it has been changed and update group data
1567 //================================================================================
1569 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1571 TopoDS_Shape newShape;
1574 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1575 if ( study->_is_nil() ) return newShape; // means "not changed"
1576 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1577 if ( !groupSO->_is_nil() )
1579 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1580 if ( CORBA::is_nil( groupObj )) return newShape;
1581 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1583 // get indices of group items
1584 set<int> curIndices;
1585 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1586 GEOM::GEOM_IGroupOperations_var groupOp =
1587 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1588 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1589 for ( int i = 0; i < ids->length(); ++i )
1590 curIndices.insert( ids[i] );
1592 if ( groupData._indices == curIndices )
1593 return newShape; // group not changed
1596 groupData._indices = curIndices;
1598 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1599 if ( !geomClient ) return newShape;
1600 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1601 geomClient->RemoveShapeFromBuffer( groupIOR );
1602 newShape = _gen_i->GeomObjectToShape( geomGroup );
1605 if ( newShape.IsNull() ) {
1606 // geom group becomes empty - return empty compound
1607 TopoDS_Compound compound;
1608 BRep_Builder().MakeCompound(compound);
1609 newShape = compound;
1615 //=============================================================================
1617 * \brief Storage of shape and index used in CheckGeomGroupModif()
1619 //=============================================================================
1620 struct TIndexedShape {
1622 TopoDS_Shape _shape;
1623 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1626 //=============================================================================
1628 * \brief Update objects depending on changed geom groups
1630 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1631 * issue 0020210: Update of a smesh group after modification of the associated geom group
1633 //=============================================================================
1635 void SMESH_Mesh_i::CheckGeomGroupModif()
1637 if ( !_impl->HasShapeToMesh() ) return;
1639 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1640 if ( study->_is_nil() ) return;
1642 CORBA::Long nbEntities = NbNodes() + NbElements();
1644 // Check if group contents changed
1646 typedef map< string, TopoDS_Shape > TEntry2Geom;
1647 TEntry2Geom newGroupContents;
1649 list<TGeomGroupData>::iterator
1650 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1651 for ( ; data != dataEnd; ++data )
1653 pair< TEntry2Geom::iterator, bool > it_new =
1654 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1655 bool processedGroup = !it_new.second;
1656 TopoDS_Shape& newShape = it_new.first->second;
1657 if ( !processedGroup )
1658 newShape = newGroupShape( *data );
1659 if ( newShape.IsNull() )
1660 continue; // no changes
1662 if ( processedGroup ) { // update group indices
1663 list<TGeomGroupData>::iterator data2 = data;
1664 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1665 data->_indices = data2->_indices;
1668 // Update SMESH objects according to new GEOM group contents
1670 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1671 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1673 int oldID = submesh->GetId();
1674 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1676 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1678 // update hypotheses
1679 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1680 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1681 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1683 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1684 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1686 // care of submeshes
1687 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1688 int newID = newSubmesh->GetId();
1689 if ( newID != oldID ) {
1690 _mapSubMesh [ newID ] = newSubmesh;
1691 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1692 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1693 _mapSubMesh. erase(oldID);
1694 _mapSubMesh_i. erase(oldID);
1695 _mapSubMeshIor.erase(oldID);
1696 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1701 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1702 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1703 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1705 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1707 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1708 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1709 ds->SetShape( newShape );
1714 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1715 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1717 // Remove groups and submeshes basing on removed sub-shapes
1719 TopTools_MapOfShape newShapeMap;
1720 TopoDS_Iterator shapeIt( newShape );
1721 for ( ; shapeIt.More(); shapeIt.Next() )
1722 newShapeMap.Add( shapeIt.Value() );
1724 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1725 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1727 if ( newShapeMap.Contains( shapeIt.Value() ))
1729 TopTools_IndexedMapOfShape oldShapeMap;
1730 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1731 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1733 const TopoDS_Shape& oldShape = oldShapeMap(i);
1734 int oldInd = meshDS->ShapeToIndex( oldShape );
1736 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1737 if ( i_smIor != _mapSubMeshIor.end() ) {
1738 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1741 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1742 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1744 // check if a group bases on oldInd shape
1745 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1746 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1747 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1748 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1750 RemoveGroup( i_grp->second ); // several groups can base on same shape
1751 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1756 // Reassign hypotheses and update groups after setting the new shape to mesh
1758 // collect anassigned hypotheses
1759 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1760 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1761 TShapeHypList assignedHyps;
1762 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1764 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1765 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1766 if ( !hyps.empty() ) {
1767 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1768 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1769 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1772 // collect shapes supporting groups
1773 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1774 TShapeTypeList groupData;
1775 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1776 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1777 for ( ; grIt != groups.end(); ++grIt )
1779 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1781 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1783 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1784 _impl->ShapeToMesh( newShape );
1786 // reassign hypotheses
1787 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1788 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1790 TIndexedShape& geom = indS_hyps->first;
1791 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1792 int oldID = geom._index;
1793 int newID = meshDS->ShapeToIndex( geom._shape );
1796 if ( oldID == 1 ) { // main shape
1798 geom._shape = newShape;
1800 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1801 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1802 // care of submeshes
1803 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1804 if ( newID != oldID ) {
1805 _mapSubMesh [ newID ] = newSubmesh;
1806 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1807 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1808 _mapSubMesh. erase(oldID);
1809 _mapSubMesh_i. erase(oldID);
1810 _mapSubMeshIor.erase(oldID);
1811 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1815 TShapeTypeList::iterator geomType = groupData.begin();
1816 for ( ; geomType != groupData.end(); ++geomType )
1818 const TIndexedShape& geom = geomType->first;
1819 int oldID = geom._index;
1820 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1823 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1824 CORBA::String_var name = groupSO->GetName();
1826 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1828 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1829 group_i->changeLocalId( newID );
1832 break; // everything has been updated
1835 } // loop on group data
1839 CORBA::Long newNbEntities = NbNodes() + NbElements();
1840 list< SALOMEDS::SObject_var > soToUpdateIcons;
1841 if ( newNbEntities != nbEntities )
1843 // Add all SObjects with icons
1844 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1846 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1847 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1848 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1850 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1851 i_gr != _mapGroups.end(); ++i_gr ) // groups
1852 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1855 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1856 for ( ; so != soToUpdateIcons.end(); ++so )
1857 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1860 //=============================================================================
1862 * \brief Create standalone group instead if group on geometry
1865 //=============================================================================
1867 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1869 SMESH::SMESH_Group_var aGroup;
1870 if ( theGroup->_is_nil() )
1871 return aGroup._retn();
1873 Unexpect aCatch(SALOME_SalomeException);
1875 SMESH_GroupBase_i* aGroupToRem =
1876 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1878 return aGroup._retn();
1880 int anId = aGroupToRem->GetLocalID();
1881 if ( !_impl->ConvertToStandalone( anId ) )
1882 return aGroup._retn();
1883 removeGeomGroupData( theGroup );
1885 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1887 // remove old instance of group from own map
1888 _mapGroups.erase( anId );
1890 SALOMEDS::StudyBuilder_var builder;
1891 SALOMEDS::SObject_var aGroupSO;
1892 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1893 if ( !aStudy->_is_nil() ) {
1894 builder = aStudy->NewBuilder();
1895 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1896 if ( !aGroupSO->_is_nil() ) {
1898 // remove reference to geometry
1899 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1900 for ( ; chItr->More(); chItr->Next() )
1901 // Remove group's child SObject
1902 builder->RemoveObject( chItr->Value() );
1904 // Update Python script
1905 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1906 << aGroupSO << " )";
1910 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1911 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1912 aGroupImpl->Register();
1913 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1915 // remember new group in own map
1916 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1917 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1919 // register CORBA object for persistence
1920 //int nextId = _gen_i->RegisterObject( aGroup );
1921 //if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1922 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1924 return aGroup._retn();
1927 //=============================================================================
1931 //=============================================================================
1933 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1935 if(MYDEBUG) MESSAGE( "createSubMesh" );
1936 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1938 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1939 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1940 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1941 SMESH::SMESH_subMesh_var subMesh
1942 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1944 _mapSubMesh[subMeshId] = mySubMesh;
1945 _mapSubMesh_i[subMeshId] = subMeshServant;
1946 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1948 // register CORBA object for persistence
1949 int nextId = _gen_i->RegisterObject( subMesh );
1950 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1952 // to track changes of GEOM groups
1953 addGeomGroupData( theSubShapeObject, subMesh );
1955 return subMesh._retn();
1958 //=======================================================================
1959 //function : getSubMesh
1961 //=======================================================================
1963 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1965 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1966 if ( it == _mapSubMeshIor.end() )
1967 return SMESH::SMESH_subMesh::_nil();
1969 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
1973 //=============================================================================
1977 //=============================================================================
1979 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
1980 GEOM::GEOM_Object_ptr theSubShapeObject )
1982 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
1983 if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
1987 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
1988 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
1989 removeHypothesis( theSubShapeObject, aHypList[i] );
1992 catch( const SALOME::SALOME_Exception& ) {
1993 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
1995 removeGeomGroupData( theSubShapeObject );
1997 int subMeshId = theSubMesh->GetId();
1999 _mapSubMesh.erase(subMeshId);
2000 _mapSubMesh_i.erase(subMeshId);
2001 _mapSubMeshIor.erase(subMeshId);
2002 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2005 //=============================================================================
2009 //=============================================================================
2011 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2012 const char* theName,
2013 const TopoDS_Shape& theShape )
2016 SMESH::SMESH_GroupBase_var aGroup;
2017 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2018 SMESH_GroupBase_i* aGroupImpl;
2019 if ( !theShape.IsNull() )
2020 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2022 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2024 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2025 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2026 aGroupImpl->Register();
2027 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2029 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2030 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2032 // register CORBA object for persistence
2033 int nextId = _gen_i->RegisterObject( aGroup );
2034 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2036 // to track changes of GEOM groups
2037 if ( !theShape.IsNull() ) {
2038 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2039 addGeomGroupData( geom, aGroup );
2042 return aGroup._retn();
2045 //=============================================================================
2047 * SMESH_Mesh_i::removeGroup
2049 * Should be called by ~SMESH_Group_i()
2051 //=============================================================================
2053 void SMESH_Mesh_i::removeGroup( const int theId )
2055 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2056 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2057 removeGeomGroupData( _mapGroups[theId] );
2058 _mapGroups.erase( theId );
2059 _impl->RemoveGroup( theId );
2064 //=============================================================================
2068 //=============================================================================
2070 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2071 throw(SALOME::SALOME_Exception)
2073 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2075 SMESH::log_array_var aLog;
2077 list < SMESHDS_Command * >logDS = _impl->GetLog();
2078 aLog = new SMESH::log_array;
2080 int lg = logDS.size();
2083 list < SMESHDS_Command * >::iterator its = logDS.begin();
2084 while(its != logDS.end()){
2085 SMESHDS_Command *com = *its;
2086 int comType = com->GetType();
2088 int lgcom = com->GetNumber();
2090 const list < int >&intList = com->GetIndexes();
2091 int inum = intList.size();
2093 list < int >::const_iterator ii = intList.begin();
2094 const list < double >&coordList = com->GetCoords();
2095 int rnum = coordList.size();
2097 list < double >::const_iterator ir = coordList.begin();
2098 aLog[indexLog].commandType = comType;
2099 aLog[indexLog].number = lgcom;
2100 aLog[indexLog].coords.length(rnum);
2101 aLog[indexLog].indexes.length(inum);
2102 for(int i = 0; i < rnum; i++){
2103 aLog[indexLog].coords[i] = *ir;
2104 //MESSAGE(" "<<i<<" "<<ir.Value());
2107 for(int i = 0; i < inum; i++){
2108 aLog[indexLog].indexes[i] = *ii;
2109 //MESSAGE(" "<<i<<" "<<ii.Value());
2118 catch(SALOME_Exception & S_ex){
2119 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2121 return aLog._retn();
2125 //=============================================================================
2129 //=============================================================================
2131 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2133 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2137 //=============================================================================
2141 //=============================================================================
2143 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2145 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2149 //=============================================================================
2153 //=============================================================================
2155 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2160 //=============================================================================
2164 //=============================================================================
2166 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2168 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2172 //=============================================================================
2176 //=============================================================================
2178 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2180 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2184 //=============================================================================
2186 * Return mesh editor
2188 //=============================================================================
2190 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2192 // Create MeshEditor
2193 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2194 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2196 // Update Python script
2197 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2199 return aMesh._retn();
2202 //=============================================================================
2204 * Return mesh edition previewer
2206 //=============================================================================
2208 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2210 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2211 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2212 return aMesh._retn();
2215 //=============================================================================
2219 //=============================================================================
2220 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2222 Unexpect aCatch(SALOME_SalomeException);
2223 _impl->SetAutoColor(theAutoColor);
2226 //=============================================================================
2230 //=============================================================================
2231 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2233 Unexpect aCatch(SALOME_SalomeException);
2234 return _impl->GetAutoColor();
2238 //=============================================================================
2240 * Export in different formats
2242 //=============================================================================
2244 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2246 return _impl->HasDuplicatedGroupNamesMED();
2249 void SMESH_Mesh_i::PrepareForWriting (const char* file)
2251 TCollection_AsciiString aFullName ((char*)file);
2252 OSD_Path aPath (aFullName);
2253 OSD_File aFile (aPath);
2254 if (aFile.Exists()) {
2255 // existing filesystem node
2256 if (aFile.KindOfFile() == OSD_FILE) {
2257 if (aFile.IsWriteable()) {
2260 if (aFile.Failed()) {
2261 TCollection_AsciiString msg ("File ");
2262 msg += aFullName + " cannot be replaced.";
2263 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2266 TCollection_AsciiString msg ("File ");
2267 msg += aFullName + " cannot be overwritten.";
2268 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2271 TCollection_AsciiString msg ("Location ");
2272 msg += aFullName + " is not a file.";
2273 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2276 // nonexisting file; check if it can be created
2278 aFile.Build(OSD_WriteOnly, OSD_Protection());
2279 if (aFile.Failed()) {
2280 TCollection_AsciiString msg ("You cannot create the file ");
2281 msg += aFullName + ". Check the directory existance and access rights.";
2282 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2290 void SMESH_Mesh_i::ExportToMED (const char* file,
2291 CORBA::Boolean auto_groups,
2292 SMESH::MED_VERSION theVersion)
2293 throw(SALOME::SALOME_Exception)
2295 Unexpect aCatch(SALOME_SalomeException);
2298 PrepareForWriting(file);
2299 const char* aMeshName = "Mesh";
2300 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2301 if ( !aStudy->_is_nil() ) {
2302 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2303 if ( !aMeshSO->_is_nil() ) {
2304 aMeshName = aMeshSO->GetName();
2305 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2306 if ( !aStudy->GetProperties()->IsLocked() )
2308 SALOMEDS::GenericAttribute_var anAttr;
2309 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2310 SALOMEDS::AttributeExternalFileDef_var aFileName;
2311 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2312 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2313 ASSERT(!aFileName->_is_nil());
2314 aFileName->SetValue(file);
2315 SALOMEDS::AttributeFileType_var aFileType;
2316 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2317 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2318 ASSERT(!aFileType->_is_nil());
2319 aFileType->SetValue("FICHIERMED");
2323 // Update Python script
2324 // set name of mesh before export
2325 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2327 // check names of groups
2330 TPythonDump() << _this() << ".ExportToMED( '"
2331 << file << "', " << auto_groups << ", " << theVersion << " )";
2333 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2336 void SMESH_Mesh_i::ExportMED (const char* file,
2337 CORBA::Boolean auto_groups)
2338 throw(SALOME::SALOME_Exception)
2340 ExportToMED(file,auto_groups,SMESH::MED_V2_1);
2343 void SMESH_Mesh_i::ExportDAT (const char *file)
2344 throw(SALOME::SALOME_Exception)
2346 Unexpect aCatch(SALOME_SalomeException);
2348 // Update Python script
2349 // check names of groups
2351 TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
2354 PrepareForWriting(file);
2355 _impl->ExportDAT(file);
2358 void SMESH_Mesh_i::ExportUNV (const char *file)
2359 throw(SALOME::SALOME_Exception)
2361 Unexpect aCatch(SALOME_SalomeException);
2363 // Update Python script
2364 // check names of groups
2366 TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
2369 PrepareForWriting(file);
2370 _impl->ExportUNV(file);
2373 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2374 throw(SALOME::SALOME_Exception)
2376 Unexpect aCatch(SALOME_SalomeException);
2378 // Update Python script
2379 // check names of groups
2381 TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
2384 PrepareForWriting(file);
2385 _impl->ExportSTL(file, isascii);
2388 //=============================================================================
2392 //=============================================================================
2394 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2396 Unexpect aCatch(SALOME_SalomeException);
2397 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2398 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2399 return aMesh._retn();
2402 //=============================================================================
2406 //=============================================================================
2407 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2409 Unexpect aCatch(SALOME_SalomeException);
2410 return _impl->NbNodes();
2413 //=============================================================================
2417 //=============================================================================
2418 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2420 Unexpect aCatch(SALOME_SalomeException);
2421 return NbEdges() + NbFaces() + NbVolumes();
2424 //=============================================================================
2428 //=============================================================================
2429 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2431 Unexpect aCatch(SALOME_SalomeException);
2432 return _impl->Nb0DElements();
2435 //=============================================================================
2439 //=============================================================================
2440 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2442 Unexpect aCatch(SALOME_SalomeException);
2443 return _impl->NbEdges();
2446 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2447 throw(SALOME::SALOME_Exception)
2449 Unexpect aCatch(SALOME_SalomeException);
2450 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2453 //=============================================================================
2457 //=============================================================================
2458 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2460 Unexpect aCatch(SALOME_SalomeException);
2461 return _impl->NbFaces();
2464 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2466 Unexpect aCatch(SALOME_SalomeException);
2467 return _impl->NbTriangles();
2470 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2472 Unexpect aCatch(SALOME_SalomeException);
2473 return _impl->NbQuadrangles();
2476 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2478 Unexpect aCatch(SALOME_SalomeException);
2479 return _impl->NbPolygons();
2482 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2483 throw(SALOME::SALOME_Exception)
2485 Unexpect aCatch(SALOME_SalomeException);
2486 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2489 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2490 throw(SALOME::SALOME_Exception)
2492 Unexpect aCatch(SALOME_SalomeException);
2493 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2496 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2497 throw(SALOME::SALOME_Exception)
2499 Unexpect aCatch(SALOME_SalomeException);
2500 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2503 //=============================================================================
2507 //=============================================================================
2508 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2510 Unexpect aCatch(SALOME_SalomeException);
2511 return _impl->NbVolumes();
2514 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2516 Unexpect aCatch(SALOME_SalomeException);
2517 return _impl->NbTetras();
2520 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2522 Unexpect aCatch(SALOME_SalomeException);
2523 return _impl->NbHexas();
2526 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2528 Unexpect aCatch(SALOME_SalomeException);
2529 return _impl->NbPyramids();
2532 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2534 Unexpect aCatch(SALOME_SalomeException);
2535 return _impl->NbPrisms();
2538 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2540 Unexpect aCatch(SALOME_SalomeException);
2541 return _impl->NbPolyhedrons();
2544 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2545 throw(SALOME::SALOME_Exception)
2547 Unexpect aCatch(SALOME_SalomeException);
2548 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2551 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2552 throw(SALOME::SALOME_Exception)
2554 Unexpect aCatch(SALOME_SalomeException);
2555 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2558 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2559 throw(SALOME::SALOME_Exception)
2561 Unexpect aCatch(SALOME_SalomeException);
2562 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2565 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2566 throw(SALOME::SALOME_Exception)
2568 Unexpect aCatch(SALOME_SalomeException);
2569 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2572 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2573 throw(SALOME::SALOME_Exception)
2575 Unexpect aCatch(SALOME_SalomeException);
2576 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2579 //=============================================================================
2583 //=============================================================================
2584 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2586 Unexpect aCatch(SALOME_SalomeException);
2587 return _mapSubMesh_i.size();
2590 //=============================================================================
2594 //=============================================================================
2595 char* SMESH_Mesh_i::Dump()
2597 std::ostringstream os;
2599 return CORBA::string_dup( os.str().c_str() );
2602 //=============================================================================
2606 //=============================================================================
2607 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2609 // SMESH::long_array_var aResult = new SMESH::long_array();
2610 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2611 // int aMinId = aSMESHDS_Mesh->MinElementID();
2612 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2614 // aResult->length(aMaxId - aMinId + 1);
2616 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2617 // aResult[i++] = id;
2619 // return aResult._retn();
2621 return GetElementsId();
2624 //=============================================================================
2628 //=============================================================================
2630 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2631 throw (SALOME::SALOME_Exception)
2633 Unexpect aCatch(SALOME_SalomeException);
2634 MESSAGE("SMESH_Mesh_i::GetElementsId");
2635 SMESH::long_array_var aResult = new SMESH::long_array();
2636 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2638 if ( aSMESHDS_Mesh == NULL )
2639 return aResult._retn();
2641 long nbElements = NbElements();
2642 aResult->length( nbElements );
2643 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2644 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2645 aResult[i] = anIt->next()->GetID();
2647 return aResult._retn();
2651 //=============================================================================
2655 //=============================================================================
2657 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2658 throw (SALOME::SALOME_Exception)
2660 Unexpect aCatch(SALOME_SalomeException);
2661 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2662 SMESH::long_array_var aResult = new SMESH::long_array();
2663 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2665 if ( aSMESHDS_Mesh == NULL )
2666 return aResult._retn();
2668 long nbElements = NbElements();
2670 // No sense in returning ids of elements along with ids of nodes:
2671 // when theElemType == SMESH::ALL, return node ids only if
2672 // there are no elements
2673 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2674 return GetNodesId();
2676 aResult->length( nbElements );
2680 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2681 while ( i < nbElements && anIt->more() ) {
2682 const SMDS_MeshElement* anElem = anIt->next();
2683 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2684 aResult[i++] = anElem->GetID();
2687 aResult->length( i );
2689 return aResult._retn();
2692 //=============================================================================
2696 //=============================================================================
2698 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2699 throw (SALOME::SALOME_Exception)
2701 Unexpect aCatch(SALOME_SalomeException);
2702 MESSAGE("SMESH_subMesh_i::GetNodesId");
2703 SMESH::long_array_var aResult = new SMESH::long_array();
2704 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2706 if ( aSMESHDS_Mesh == NULL )
2707 return aResult._retn();
2709 long nbNodes = NbNodes();
2710 aResult->length( nbNodes );
2711 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2712 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2713 aResult[i] = anIt->next()->GetID();
2715 return aResult._retn();
2718 //=============================================================================
2722 //=============================================================================
2724 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2725 throw (SALOME::SALOME_Exception)
2727 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2731 //=============================================================================
2733 * Returns ID of elements for given submesh
2735 //=============================================================================
2736 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2737 throw (SALOME::SALOME_Exception)
2739 SMESH::long_array_var aResult = new SMESH::long_array();
2741 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2742 if(!SM) return aResult._retn();
2744 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2745 if(!SDSM) return aResult._retn();
2747 aResult->length(SDSM->NbElements());
2749 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2751 while ( eIt->more() ) {
2752 aResult[i++] = eIt->next()->GetID();
2755 return aResult._retn();
2759 //=============================================================================
2761 * Returns ID of nodes for given submesh
2762 * If param all==true - returns all nodes, else -
2763 * returns only nodes on shapes.
2765 //=============================================================================
2766 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2767 throw (SALOME::SALOME_Exception)
2769 SMESH::long_array_var aResult = new SMESH::long_array();
2771 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2772 if(!SM) return aResult._retn();
2774 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2775 if(!SDSM) return aResult._retn();
2778 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2779 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2780 while ( nIt->more() ) {
2781 const SMDS_MeshNode* elem = nIt->next();
2782 theElems.insert( elem->GetID() );
2785 else { // all nodes of submesh elements
2786 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2787 while ( eIt->more() ) {
2788 const SMDS_MeshElement* anElem = eIt->next();
2789 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2790 while ( nIt->more() ) {
2791 const SMDS_MeshElement* elem = nIt->next();
2792 theElems.insert( elem->GetID() );
2797 aResult->length(theElems.size());
2798 set<int>::iterator itElem;
2800 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2801 aResult[i++] = *itElem;
2803 return aResult._retn();
2807 //=============================================================================
2809 * Returns type of elements for given submesh
2811 //=============================================================================
2812 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2813 throw (SALOME::SALOME_Exception)
2815 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2816 if(!SM) return SMESH::ALL;
2818 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2819 if(!SDSM) return SMESH::ALL;
2821 if(SDSM->NbElements()==0)
2822 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2824 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2825 const SMDS_MeshElement* anElem = eIt->next();
2826 return ( SMESH::ElementType ) anElem->GetType();
2830 //=============================================================================
2834 //=============================================================================
2836 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2838 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2840 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2845 //=============================================================================
2847 * Get XYZ coordinates of node as list of double
2848 * If there is not node for given ID - returns empty list
2850 //=============================================================================
2852 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2854 SMESH::double_array_var aResult = new SMESH::double_array();
2855 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2856 if ( aSMESHDS_Mesh == NULL )
2857 return aResult._retn();
2860 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2862 return aResult._retn();
2866 aResult[0] = aNode->X();
2867 aResult[1] = aNode->Y();
2868 aResult[2] = aNode->Z();
2869 return aResult._retn();
2873 //=============================================================================
2875 * For given node returns list of IDs of inverse elements
2876 * If there is not node for given ID - returns empty list
2878 //=============================================================================
2880 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2882 SMESH::long_array_var aResult = new SMESH::long_array();
2883 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2884 if ( aSMESHDS_Mesh == NULL )
2885 return aResult._retn();
2888 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2890 return aResult._retn();
2892 // find inverse elements
2893 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2894 TColStd_SequenceOfInteger IDs;
2895 while(eIt->more()) {
2896 const SMDS_MeshElement* elem = eIt->next();
2897 IDs.Append(elem->GetID());
2899 if(IDs.Length()>0) {
2900 aResult->length(IDs.Length());
2902 for(; i<=IDs.Length(); i++) {
2903 aResult[i-1] = IDs.Value(i);
2906 return aResult._retn();
2909 //=============================================================================
2911 * \brief Return position of a node on shape
2913 //=============================================================================
2915 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
2917 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
2918 aNodePosition->shapeID = 0;
2919 aNodePosition->shapeType = GEOM::SHAPE;
2921 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
2922 if ( !mesh ) return aNodePosition;
2924 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
2926 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
2928 aNodePosition->shapeID = pos->GetShapeId();
2929 switch ( pos->GetTypeOfPosition() ) {
2931 aNodePosition->shapeType = GEOM::EDGE;
2932 aNodePosition->params.length(1);
2933 aNodePosition->params[0] =
2934 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
2937 aNodePosition->shapeType = GEOM::FACE;
2938 aNodePosition->params.length(2);
2939 aNodePosition->params[0] =
2940 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
2941 aNodePosition->params[1] =
2942 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
2944 case SMDS_TOP_VERTEX:
2945 aNodePosition->shapeType = GEOM::VERTEX;
2947 case SMDS_TOP_3DSPACE:
2948 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
2949 aNodePosition->shapeType = GEOM::SOLID;
2950 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
2951 aNodePosition->shapeType = GEOM::SHELL;
2957 return aNodePosition;
2960 //=============================================================================
2962 * If given element is node returns IDs of shape from position
2963 * If there is not node for given ID - returns -1
2965 //=============================================================================
2967 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
2969 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2970 if ( aSMESHDS_Mesh == NULL )
2974 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2976 SMDS_PositionPtr pos = aNode->GetPosition();
2980 return pos->GetShapeId();
2987 //=============================================================================
2989 * For given element returns ID of result shape after
2990 * ::FindShape() from SMESH_MeshEditor
2991 * If there is not element for given ID - returns -1
2993 //=============================================================================
2995 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
2997 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2998 if ( aSMESHDS_Mesh == NULL )
3001 // try to find element
3002 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3006 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3007 ::SMESH_MeshEditor aMeshEditor(_impl);
3008 int index = aMeshEditor.FindShape( elem );
3016 //=============================================================================
3018 * Returns number of nodes for given element
3019 * If there is not element for given ID - returns -1
3021 //=============================================================================
3023 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3025 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3026 if ( aSMESHDS_Mesh == NULL ) return -1;
3027 // try to find element
3028 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3029 if(!elem) return -1;
3030 return elem->NbNodes();
3034 //=============================================================================
3036 * Returns ID of node by given index for given element
3037 * If there is not element for given ID - returns -1
3038 * If there is not node for given index - returns -2
3040 //=============================================================================
3042 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3044 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3045 if ( aSMESHDS_Mesh == NULL ) return -1;
3046 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3047 if(!elem) return -1;
3048 if( index>=elem->NbNodes() || index<0 ) return -1;
3049 return elem->GetNode(index)->GetID();
3052 //=============================================================================
3054 * Returns IDs of nodes of given element
3056 //=============================================================================
3058 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3060 SMESH::long_array_var aResult = new SMESH::long_array();
3061 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3063 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3065 aResult->length( elem->NbNodes() );
3066 for ( int i = 0; i < elem->NbNodes(); ++i )
3067 aResult[ i ] = elem->GetNode( i )->GetID();
3070 return aResult._retn();
3073 //=============================================================================
3075 * Returns true if given node is medium node
3076 * in given quadratic element
3078 //=============================================================================
3080 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3082 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3083 if ( aSMESHDS_Mesh == NULL ) return false;
3085 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3086 if(!aNode) return false;
3087 // try to find element
3088 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3089 if(!elem) return false;
3091 return elem->IsMediumNode(aNode);
3095 //=============================================================================
3097 * Returns true if given node is medium node
3098 * in one of quadratic elements
3100 //=============================================================================
3102 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3103 SMESH::ElementType theElemType)
3105 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3106 if ( aSMESHDS_Mesh == NULL ) return false;
3109 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3110 if(!aNode) return false;
3112 SMESH_MesherHelper aHelper( *(_impl) );
3114 SMDSAbs_ElementType aType;
3115 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3116 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3117 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3118 else aType = SMDSAbs_All;
3120 return aHelper.IsMedium(aNode,aType);
3124 //=============================================================================
3126 * Returns number of edges for given element
3128 //=============================================================================
3130 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3132 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3133 if ( aSMESHDS_Mesh == NULL ) return -1;
3134 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3135 if(!elem) return -1;
3136 return elem->NbEdges();
3140 //=============================================================================
3142 * Returns number of faces for given element
3144 //=============================================================================
3146 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3148 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3149 if ( aSMESHDS_Mesh == NULL ) return -1;
3150 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3151 if(!elem) return -1;
3152 return elem->NbFaces();
3156 //=============================================================================
3158 * Returns true if given element is polygon
3160 //=============================================================================
3162 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3164 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3165 if ( aSMESHDS_Mesh == NULL ) return false;
3166 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3167 if(!elem) return false;
3168 return elem->IsPoly();
3172 //=============================================================================
3174 * Returns true if given element is quadratic
3176 //=============================================================================
3178 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3180 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3181 if ( aSMESHDS_Mesh == NULL ) return false;
3182 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3183 if(!elem) return false;
3184 return elem->IsQuadratic();
3188 //=============================================================================
3190 * Returns bary center for given element
3192 //=============================================================================
3194 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3196 SMESH::double_array_var aResult = new SMESH::double_array();
3197 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3198 if ( aSMESHDS_Mesh == NULL )
3199 return aResult._retn();
3201 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3203 return aResult._retn();
3205 if(elem->GetType()==SMDSAbs_Volume) {
3206 SMDS_VolumeTool aTool;
3207 if(aTool.Set(elem)) {
3209 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3214 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3216 double x=0., y=0., z=0.;
3217 for(; anIt->more(); ) {
3219 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3233 return aResult._retn();
3237 //=============================================================================
3239 * Create and publish group servants if any groups were imported or created anyhow
3241 //=============================================================================
3243 void SMESH_Mesh_i::CreateGroupServants()
3245 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3247 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3248 while ( groupIt->more() )
3250 ::SMESH_Group* group = groupIt->next();
3251 int anId = group->GetGroupDS()->GetID();
3253 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3254 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3257 SMESH_GroupBase_i* aGroupImpl;
3259 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3260 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3262 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3263 shape = groupOnGeom->GetShape();
3266 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3269 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3270 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3271 aGroupImpl->Register();
3273 SMESH::SMESH_GroupBase_var groupVar =
3274 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3275 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3277 // register CORBA object for persistence
3278 int nextId = _gen_i->RegisterObject( groupVar );
3279 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3281 // publishing of the groups in the study
3282 if ( !aStudy->_is_nil() ) {
3283 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3284 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3289 //=============================================================================
3291 * \brief Return groups cantained in _mapGroups by their IDs
3293 //=============================================================================
3295 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3297 int nbGroups = groupIDs.size();
3298 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3299 aList->length( nbGroups );
3301 list<int>::const_iterator ids = groupIDs.begin();
3302 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3304 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3305 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3306 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3308 aList->length( nbGroups );
3309 return aList._retn();
3312 //=============================================================================
3314 * \brief Return information about imported file
3316 //=============================================================================
3318 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3320 SALOME_MED::MedFileInfo_var res( myFileInfo );
3321 if ( !res.operator->() ) {
3322 res = new SALOME_MED::MedFileInfo;
3324 res->fileSize = res->major = res->minor = res->release = -1;
3329 //=============================================================================
3331 * \brief Check and correct names of mesh groups
3333 //=============================================================================
3335 void SMESH_Mesh_i::checkGroupNames()
3337 int nbGrp = NbGroups();
3341 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3342 if ( aStudy->_is_nil() )
3343 return; // nothing to do
3345 SMESH::ListOfGroups* grpList = 0;
3346 // avoid dump of "GetGroups"
3348 // store python dump into a local variable inside local scope
3349 SMESH::TPythonDump pDump; // do not delete this line of code
3350 grpList = GetGroups();
3353 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3354 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3357 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3358 if ( aGrpSO->_is_nil() )
3360 // correct name of the mesh group if necessary
3361 const char* guiName = aGrpSO->GetName();
3362 if ( strcmp(guiName, aGrp->GetName()) )
3363 aGrp->SetName( guiName );
3367 //=============================================================================
3369 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3371 //=============================================================================
3372 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3374 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3375 CORBA::string_dup(theParameters));
3378 //=============================================================================
3380 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3382 //=============================================================================
3383 char* SMESH_Mesh_i::GetParameters()
3385 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3386 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3389 //=============================================================================
3391 * \brief Returns list of notebook variables used for last Mesh operation
3393 //=============================================================================
3394 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3396 SMESH::string_array_var aResult = new SMESH::string_array();
3397 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3399 char *aParameters = GetParameters();
3400 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3401 if(!aStudy->_is_nil()) {
3402 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3403 if(aSections->length() > 0) {
3404 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3405 aResult->length(aVars.length());
3406 for(int i = 0;i < aVars.length();i++)
3407 aResult[i] = CORBA::string_dup( aVars[i]);
3411 return aResult._retn();
3414 //=============================================================================
3416 * \brief Returns statistic of mesh elements
3418 //=============================================================================
3419 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3421 SMESH::long_array_var aRes = new SMESH::long_array();
3422 aRes->length(SMESH::Entity_Last);
3423 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3425 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3427 return aRes._retn();
3428 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3429 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3430 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3431 return aRes._retn();
3434 //=============================================================================
3436 * \brief Collect statistic of mesh elements given by iterator
3438 //=============================================================================
3439 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3440 SMESH::long_array& theInfo)
3442 if (!theItr) return;
3443 while (theItr->more())
3444 theInfo[ theItr->next()->GetEntityType() ]++;