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();
968 NCollection_Map< int > anIds;
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.Add( 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.Extent() );
1004 NCollection_Map< int >::Iterator anIter( anIds );
1005 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1007 aResIds[ i ] = anIter.Value();
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 NCollection_Map< 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.Add( 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.Extent() );
1152 NCollection_Map< int >::Iterator aListIter( anIds );
1153 for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1155 aResIds[ i ] = aListIter.Value();
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 NCollection_Map< 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.Add( aCurrId );
1281 NCollection_Map< 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.Contains( aCurrId ) )
1306 anIds.Add( 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.Extent() );
1319 NCollection_Map< int >::Iterator anIter( anIds );
1320 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1322 aResIds[ i ] = anIter.Value();
1324 aResGrp->Add( aResIds );
1326 // Clear python lines, created by CreateGroup() and Add()
1327 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1328 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1329 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1331 // Update Python script
1333 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1334 << &theMainGroups << ", " << &theToolGroups << ", '"
1335 << theName << "' )";
1337 return aResGrp._retn();
1341 return SMESH::SMESH_Group::_nil();
1345 //=============================================================================
1347 \brief Create groups of entities from existing groups of superior dimensions
1349 1) extract all nodes from each group,
1350 2) combine all elements of specified dimension laying on these nodes.
1351 \param theGroups list of source groups
1352 \param theElemType dimension of elements
1353 \param theName name of new group
1354 \return pointer on new group
1356 //=============================================================================
1357 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1358 const SMESH::ListOfGroups& theGroups,
1359 SMESH::ElementType theElemType,
1360 const char* theName )
1361 throw (SALOME::SALOME_Exception)
1363 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1365 if ( !theName || !aMeshDS )
1366 return SMESH::SMESH_Group::_nil();
1368 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1372 // Create map of nodes from all groups
1374 NCollection_Map< int > aNodeMap;
1376 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1378 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1379 if ( CORBA::is_nil( aGrp ) )
1382 SMESH::ElementType aType = aGrp->GetType();
1383 if ( aType == SMESH::ALL )
1385 else if ( aType == SMESH::NODE )
1387 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1388 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1390 int aCurrId = aCurrIds[ i ];
1391 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1393 aNodeMap.Add( aNode->GetID() );
1398 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1399 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1401 int aCurrId = aCurrIds[ i ];
1402 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1405 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1406 while( aNodeIter->more() )
1408 const SMDS_MeshNode* aNode =
1409 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1411 aNodeMap.Add( aNode->GetID() );
1417 // Get result identifiers
1419 NCollection_Map< int > aResultIds;
1420 if ( theElemType == SMESH::NODE )
1422 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1423 for ( ; aNodeIter.More(); aNodeIter.Next() )
1424 aResultIds.Add( aNodeIter.Value() );
1428 // Create list of elements of given dimension constructed on the nodes
1429 NCollection_Map< int > anElemList;
1430 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1431 for ( ; aNodeIter.More(); aNodeIter.Next() )
1433 const SMDS_MeshElement* aNode =
1434 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1438 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1439 while( anElemIter->more() )
1441 const SMDS_MeshElement* anElem =
1442 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1443 if ( anElem && anElem->GetType() == anElemType )
1444 anElemList.Add( anElem->GetID() );
1448 // check whether all nodes of elements are present in nodes map
1449 NCollection_Map< int >::Iterator anIter( anElemList );
1450 for ( ; anIter.More(); anIter.Next() )
1452 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1457 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1458 while( aNodeIter->more() )
1460 const SMDS_MeshNode* aNode =
1461 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1462 if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1469 aResultIds.Add( anElem->GetID() );
1475 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1476 if ( aResGrp->_is_nil() )
1477 return SMESH::SMESH_Group::_nil();
1479 // Create array of identifiers
1480 SMESH::long_array_var aResIds = new SMESH::long_array;
1481 aResIds->length( aResultIds.Extent() );
1483 NCollection_Map< int >::Iterator aResIter( aResultIds );
1484 for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1485 aResIds[ i ] = aResIter.Value();
1486 aResGrp->Add( aResIds );
1488 // Remove strings corresponding to group creation
1489 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1490 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1491 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1493 // Update Python script
1495 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1496 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1498 return aResGrp._retn();
1502 return SMESH::SMESH_Group::_nil();
1506 //================================================================================
1508 * \brief Remember GEOM group data
1510 //================================================================================
1512 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1513 CORBA::Object_ptr theSmeshObj)
1515 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1518 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1519 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1520 if ( groupSO->_is_nil() )
1523 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1524 GEOM::GEOM_IGroupOperations_var groupOp =
1525 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1526 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1529 _geomGroupData.push_back( TGeomGroupData() );
1530 TGeomGroupData & groupData = _geomGroupData.back();
1532 CORBA::String_var entry = groupSO->GetID();
1533 groupData._groupEntry = entry.in();
1535 for ( int i = 0; i < ids->length(); ++i )
1536 groupData._indices.insert( ids[i] );
1538 groupData._smeshObject = theSmeshObj;
1541 //================================================================================
1543 * Remove GEOM group data relating to removed smesh object
1545 //================================================================================
1547 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1549 list<TGeomGroupData>::iterator
1550 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1551 for ( ; data != dataEnd; ++data ) {
1552 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1553 _geomGroupData.erase( data );
1559 //================================================================================
1561 * \brief Return new group contents if it has been changed and update group data
1563 //================================================================================
1565 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1567 TopoDS_Shape newShape;
1570 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1571 if ( study->_is_nil() ) return newShape; // means "not changed"
1572 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1573 if ( !groupSO->_is_nil() )
1575 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1576 if ( CORBA::is_nil( groupObj )) return newShape;
1577 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1579 // get indices of group items
1580 set<int> curIndices;
1581 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1582 GEOM::GEOM_IGroupOperations_var groupOp =
1583 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1584 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1585 for ( int i = 0; i < ids->length(); ++i )
1586 curIndices.insert( ids[i] );
1588 if ( groupData._indices == curIndices )
1589 return newShape; // group not changed
1592 groupData._indices = curIndices;
1594 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1595 if ( !geomClient ) return newShape;
1596 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1597 geomClient->RemoveShapeFromBuffer( groupIOR );
1598 newShape = _gen_i->GeomObjectToShape( geomGroup );
1601 if ( newShape.IsNull() ) {
1602 // geom group becomes empty - return empty compound
1603 TopoDS_Compound compound;
1604 BRep_Builder().MakeCompound(compound);
1605 newShape = compound;
1611 //=============================================================================
1613 * \brief Storage of shape and index used in CheckGeomGroupModif()
1615 //=============================================================================
1616 struct TIndexedShape {
1618 TopoDS_Shape _shape;
1619 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1622 //=============================================================================
1624 * \brief Update objects depending on changed geom groups
1626 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1627 * issue 0020210: Update of a smesh group after modification of the associated geom group
1629 //=============================================================================
1631 void SMESH_Mesh_i::CheckGeomGroupModif()
1633 if ( !_impl->HasShapeToMesh() ) return;
1635 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1636 if ( study->_is_nil() ) return;
1638 CORBA::Long nbEntities = NbNodes() + NbElements();
1640 // Check if group contents changed
1642 typedef map< string, TopoDS_Shape > TEntry2Geom;
1643 TEntry2Geom newGroupContents;
1645 list<TGeomGroupData>::iterator
1646 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1647 for ( ; data != dataEnd; ++data )
1649 pair< TEntry2Geom::iterator, bool > it_new =
1650 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1651 bool processedGroup = !it_new.second;
1652 TopoDS_Shape& newShape = it_new.first->second;
1653 if ( !processedGroup )
1654 newShape = newGroupShape( *data );
1655 if ( newShape.IsNull() )
1656 continue; // no changes
1658 if ( processedGroup ) { // update group indices
1659 list<TGeomGroupData>::iterator data2 = data;
1660 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1661 data->_indices = data2->_indices;
1664 // Update SMESH objects according to new GEOM group contents
1666 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1667 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1669 int oldID = submesh->GetId();
1670 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1672 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1674 // update hypotheses
1675 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1676 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1677 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1679 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1680 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1682 // care of submeshes
1683 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1684 int newID = newSubmesh->GetId();
1685 if ( newID != oldID ) {
1686 _mapSubMesh [ newID ] = newSubmesh;
1687 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1688 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1689 _mapSubMesh. erase(oldID);
1690 _mapSubMesh_i. erase(oldID);
1691 _mapSubMeshIor.erase(oldID);
1692 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1697 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1698 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1699 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1701 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1703 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1704 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1705 ds->SetShape( newShape );
1710 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1711 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1713 // Remove groups and submeshes basing on removed sub-shapes
1715 TopTools_MapOfShape newShapeMap;
1716 TopoDS_Iterator shapeIt( newShape );
1717 for ( ; shapeIt.More(); shapeIt.Next() )
1718 newShapeMap.Add( shapeIt.Value() );
1720 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1721 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1723 if ( newShapeMap.Contains( shapeIt.Value() ))
1725 TopTools_IndexedMapOfShape oldShapeMap;
1726 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1727 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1729 const TopoDS_Shape& oldShape = oldShapeMap(i);
1730 int oldInd = meshDS->ShapeToIndex( oldShape );
1732 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1733 if ( i_smIor != _mapSubMeshIor.end() ) {
1734 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1737 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1738 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1740 // check if a group bases on oldInd shape
1741 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1742 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1743 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1744 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1746 RemoveGroup( i_grp->second ); // several groups can base on same shape
1747 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1752 // Reassign hypotheses and update groups after setting the new shape to mesh
1754 // collect anassigned hypotheses
1755 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1756 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1757 TShapeHypList assignedHyps;
1758 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1760 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1761 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1762 if ( !hyps.empty() ) {
1763 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1764 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1765 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1768 // collect shapes supporting groups
1769 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1770 TShapeTypeList groupData;
1771 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1772 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1773 for ( ; grIt != groups.end(); ++grIt )
1775 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1777 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1779 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1780 _impl->ShapeToMesh( newShape );
1782 // reassign hypotheses
1783 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1784 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1786 TIndexedShape& geom = indS_hyps->first;
1787 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1788 int oldID = geom._index;
1789 int newID = meshDS->ShapeToIndex( geom._shape );
1792 if ( oldID == 1 ) { // main shape
1794 geom._shape = newShape;
1796 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1797 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1798 // care of submeshes
1799 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1800 if ( newID != oldID ) {
1801 _mapSubMesh [ newID ] = newSubmesh;
1802 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1803 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1804 _mapSubMesh. erase(oldID);
1805 _mapSubMesh_i. erase(oldID);
1806 _mapSubMeshIor.erase(oldID);
1807 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1811 TShapeTypeList::iterator geomType = groupData.begin();
1812 for ( ; geomType != groupData.end(); ++geomType )
1814 const TIndexedShape& geom = geomType->first;
1815 int oldID = geom._index;
1816 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1819 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1820 CORBA::String_var name = groupSO->GetName();
1822 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1824 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1825 group_i->changeLocalId( newID );
1828 break; // everything has been updated
1831 } // loop on group data
1835 CORBA::Long newNbEntities = NbNodes() + NbElements();
1836 list< SALOMEDS::SObject_var > soToUpdateIcons;
1837 if ( newNbEntities != nbEntities )
1839 // Add all SObjects with icons
1840 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1842 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1843 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1844 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1846 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1847 i_gr != _mapGroups.end(); ++i_gr ) // groups
1848 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1851 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1852 for ( ; so != soToUpdateIcons.end(); ++so )
1853 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1856 //=============================================================================
1858 * \brief Create standalone group instead if group on geometry
1861 //=============================================================================
1863 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1865 SMESH::SMESH_Group_var aGroup;
1866 if ( theGroup->_is_nil() )
1867 return aGroup._retn();
1869 Unexpect aCatch(SALOME_SalomeException);
1871 SMESH_GroupBase_i* aGroupToRem =
1872 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1874 return aGroup._retn();
1876 int anId = aGroupToRem->GetLocalID();
1877 if ( !_impl->ConvertToStandalone( anId ) )
1878 return aGroup._retn();
1879 removeGeomGroupData( theGroup );
1881 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1883 // remove old instance of group from own map
1884 _mapGroups.erase( anId );
1886 SALOMEDS::StudyBuilder_var builder;
1887 SALOMEDS::SObject_var aGroupSO;
1888 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1889 if ( !aStudy->_is_nil() ) {
1890 builder = aStudy->NewBuilder();
1891 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1892 if ( !aGroupSO->_is_nil() ) {
1894 // remove reference to geometry
1895 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1896 for ( ; chItr->More(); chItr->Next() )
1897 // Remove group's child SObject
1898 builder->RemoveObject( chItr->Value() );
1900 // Update Python script
1901 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1902 << aGroupSO << " )";
1906 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1907 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1908 aGroupImpl->Register();
1909 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1911 // remember new group in own map
1912 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1913 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1915 // register CORBA object for persistence
1916 //int nextId = _gen_i->RegisterObject( aGroup );
1917 //if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
1918 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1920 return aGroup._retn();
1923 //=============================================================================
1927 //=============================================================================
1929 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1931 if(MYDEBUG) MESSAGE( "createSubMesh" );
1932 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1934 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1935 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1936 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1937 SMESH::SMESH_subMesh_var subMesh
1938 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1940 _mapSubMesh[subMeshId] = mySubMesh;
1941 _mapSubMesh_i[subMeshId] = subMeshServant;
1942 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1944 // register CORBA object for persistence
1945 int nextId = _gen_i->RegisterObject( subMesh );
1946 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1948 // to track changes of GEOM groups
1949 addGeomGroupData( theSubShapeObject, subMesh );
1951 return subMesh._retn();
1954 //=======================================================================
1955 //function : getSubMesh
1957 //=======================================================================
1959 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1961 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1962 if ( it == _mapSubMeshIor.end() )
1963 return SMESH::SMESH_subMesh::_nil();
1965 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
1969 //=============================================================================
1973 //=============================================================================
1975 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
1976 GEOM::GEOM_Object_ptr theSubShapeObject )
1978 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
1979 if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
1983 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
1984 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
1985 removeHypothesis( theSubShapeObject, aHypList[i] );
1988 catch( const SALOME::SALOME_Exception& ) {
1989 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
1991 removeGeomGroupData( theSubShapeObject );
1993 int subMeshId = theSubMesh->GetId();
1995 _mapSubMesh.erase(subMeshId);
1996 _mapSubMesh_i.erase(subMeshId);
1997 _mapSubMeshIor.erase(subMeshId);
1998 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2001 //=============================================================================
2005 //=============================================================================
2007 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2008 const char* theName,
2009 const TopoDS_Shape& theShape )
2012 SMESH::SMESH_GroupBase_var aGroup;
2013 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2014 SMESH_GroupBase_i* aGroupImpl;
2015 if ( !theShape.IsNull() )
2016 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2018 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2020 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2021 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2022 aGroupImpl->Register();
2023 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2025 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2026 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2028 // register CORBA object for persistence
2029 int nextId = _gen_i->RegisterObject( aGroup );
2030 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2032 // to track changes of GEOM groups
2033 if ( !theShape.IsNull() ) {
2034 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2035 addGeomGroupData( geom, aGroup );
2038 return aGroup._retn();
2041 //=============================================================================
2043 * SMESH_Mesh_i::removeGroup
2045 * Should be called by ~SMESH_Group_i()
2047 //=============================================================================
2049 void SMESH_Mesh_i::removeGroup( const int theId )
2051 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2052 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2053 removeGeomGroupData( _mapGroups[theId] );
2054 _mapGroups.erase( theId );
2055 _impl->RemoveGroup( theId );
2060 //=============================================================================
2064 //=============================================================================
2066 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2067 throw(SALOME::SALOME_Exception)
2069 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2071 SMESH::log_array_var aLog;
2073 list < SMESHDS_Command * >logDS = _impl->GetLog();
2074 aLog = new SMESH::log_array;
2076 int lg = logDS.size();
2079 list < SMESHDS_Command * >::iterator its = logDS.begin();
2080 while(its != logDS.end()){
2081 SMESHDS_Command *com = *its;
2082 int comType = com->GetType();
2084 int lgcom = com->GetNumber();
2086 const list < int >&intList = com->GetIndexes();
2087 int inum = intList.size();
2089 list < int >::const_iterator ii = intList.begin();
2090 const list < double >&coordList = com->GetCoords();
2091 int rnum = coordList.size();
2093 list < double >::const_iterator ir = coordList.begin();
2094 aLog[indexLog].commandType = comType;
2095 aLog[indexLog].number = lgcom;
2096 aLog[indexLog].coords.length(rnum);
2097 aLog[indexLog].indexes.length(inum);
2098 for(int i = 0; i < rnum; i++){
2099 aLog[indexLog].coords[i] = *ir;
2100 //MESSAGE(" "<<i<<" "<<ir.Value());
2103 for(int i = 0; i < inum; i++){
2104 aLog[indexLog].indexes[i] = *ii;
2105 //MESSAGE(" "<<i<<" "<<ii.Value());
2114 catch(SALOME_Exception & S_ex){
2115 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2117 return aLog._retn();
2121 //=============================================================================
2125 //=============================================================================
2127 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2129 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2133 //=============================================================================
2137 //=============================================================================
2139 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2141 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2145 //=============================================================================
2149 //=============================================================================
2151 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2156 //=============================================================================
2160 //=============================================================================
2162 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2164 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2168 //=============================================================================
2172 //=============================================================================
2174 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2176 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2180 //=============================================================================
2182 * Return mesh editor
2184 //=============================================================================
2186 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2188 // Create MeshEditor
2189 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2190 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2192 // Update Python script
2193 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2195 return aMesh._retn();
2198 //=============================================================================
2200 * Return mesh edition previewer
2202 //=============================================================================
2204 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2206 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2207 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2208 return aMesh._retn();
2211 //=============================================================================
2215 //=============================================================================
2216 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2218 Unexpect aCatch(SALOME_SalomeException);
2219 _impl->SetAutoColor(theAutoColor);
2222 //=============================================================================
2226 //=============================================================================
2227 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2229 Unexpect aCatch(SALOME_SalomeException);
2230 return _impl->GetAutoColor();
2234 //=============================================================================
2236 * Export in different formats
2238 //=============================================================================
2240 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2242 return _impl->HasDuplicatedGroupNamesMED();
2245 void SMESH_Mesh_i::PrepareForWriting (const char* file)
2247 TCollection_AsciiString aFullName ((char*)file);
2248 OSD_Path aPath (aFullName);
2249 OSD_File aFile (aPath);
2250 if (aFile.Exists()) {
2251 // existing filesystem node
2252 if (aFile.KindOfFile() == OSD_FILE) {
2253 if (aFile.IsWriteable()) {
2256 if (aFile.Failed()) {
2257 TCollection_AsciiString msg ("File ");
2258 msg += aFullName + " cannot be replaced.";
2259 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2262 TCollection_AsciiString msg ("File ");
2263 msg += aFullName + " cannot be overwritten.";
2264 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2267 TCollection_AsciiString msg ("Location ");
2268 msg += aFullName + " is not a file.";
2269 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2272 // nonexisting file; check if it can be created
2274 aFile.Build(OSD_WriteOnly, OSD_Protection());
2275 if (aFile.Failed()) {
2276 TCollection_AsciiString msg ("You cannot create the file ");
2277 msg += aFullName + ". Check the directory existance and access rights.";
2278 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2286 void SMESH_Mesh_i::ExportToMED (const char* file,
2287 CORBA::Boolean auto_groups,
2288 SMESH::MED_VERSION theVersion)
2289 throw(SALOME::SALOME_Exception)
2291 Unexpect aCatch(SALOME_SalomeException);
2294 PrepareForWriting(file);
2295 const char* aMeshName = "Mesh";
2296 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2297 if ( !aStudy->_is_nil() ) {
2298 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2299 if ( !aMeshSO->_is_nil() ) {
2300 aMeshName = aMeshSO->GetName();
2301 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2302 if ( !aStudy->GetProperties()->IsLocked() )
2304 SALOMEDS::GenericAttribute_var anAttr;
2305 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2306 SALOMEDS::AttributeExternalFileDef_var aFileName;
2307 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2308 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2309 ASSERT(!aFileName->_is_nil());
2310 aFileName->SetValue(file);
2311 SALOMEDS::AttributeFileType_var aFileType;
2312 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2313 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2314 ASSERT(!aFileType->_is_nil());
2315 aFileType->SetValue("FICHIERMED");
2319 // Update Python script
2320 // set name of mesh before export
2321 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2323 // check names of groups
2326 TPythonDump() << _this() << ".ExportToMED( '"
2327 << file << "', " << auto_groups << ", " << theVersion << " )";
2329 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2332 void SMESH_Mesh_i::ExportMED (const char* file,
2333 CORBA::Boolean auto_groups)
2334 throw(SALOME::SALOME_Exception)
2336 ExportToMED(file,auto_groups,SMESH::MED_V2_1);
2339 void SMESH_Mesh_i::ExportDAT (const char *file)
2340 throw(SALOME::SALOME_Exception)
2342 Unexpect aCatch(SALOME_SalomeException);
2344 // Update Python script
2345 // check names of groups
2347 TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
2350 PrepareForWriting(file);
2351 _impl->ExportDAT(file);
2354 void SMESH_Mesh_i::ExportUNV (const char *file)
2355 throw(SALOME::SALOME_Exception)
2357 Unexpect aCatch(SALOME_SalomeException);
2359 // Update Python script
2360 // check names of groups
2362 TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
2365 PrepareForWriting(file);
2366 _impl->ExportUNV(file);
2369 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2370 throw(SALOME::SALOME_Exception)
2372 Unexpect aCatch(SALOME_SalomeException);
2374 // Update Python script
2375 // check names of groups
2377 TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
2380 PrepareForWriting(file);
2381 _impl->ExportSTL(file, isascii);
2384 //=============================================================================
2388 //=============================================================================
2390 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2392 Unexpect aCatch(SALOME_SalomeException);
2393 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2394 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2395 return aMesh._retn();
2398 //=============================================================================
2402 //=============================================================================
2403 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2405 Unexpect aCatch(SALOME_SalomeException);
2406 return _impl->NbNodes();
2409 //=============================================================================
2413 //=============================================================================
2414 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2416 Unexpect aCatch(SALOME_SalomeException);
2417 return NbEdges() + NbFaces() + NbVolumes();
2420 //=============================================================================
2424 //=============================================================================
2425 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2427 Unexpect aCatch(SALOME_SalomeException);
2428 return _impl->Nb0DElements();
2431 //=============================================================================
2435 //=============================================================================
2436 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2438 Unexpect aCatch(SALOME_SalomeException);
2439 return _impl->NbEdges();
2442 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2443 throw(SALOME::SALOME_Exception)
2445 Unexpect aCatch(SALOME_SalomeException);
2446 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2449 //=============================================================================
2453 //=============================================================================
2454 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2456 Unexpect aCatch(SALOME_SalomeException);
2457 return _impl->NbFaces();
2460 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2462 Unexpect aCatch(SALOME_SalomeException);
2463 return _impl->NbTriangles();
2466 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2468 Unexpect aCatch(SALOME_SalomeException);
2469 return _impl->NbQuadrangles();
2472 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2474 Unexpect aCatch(SALOME_SalomeException);
2475 return _impl->NbPolygons();
2478 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2479 throw(SALOME::SALOME_Exception)
2481 Unexpect aCatch(SALOME_SalomeException);
2482 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2485 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2486 throw(SALOME::SALOME_Exception)
2488 Unexpect aCatch(SALOME_SalomeException);
2489 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2492 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2493 throw(SALOME::SALOME_Exception)
2495 Unexpect aCatch(SALOME_SalomeException);
2496 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2499 //=============================================================================
2503 //=============================================================================
2504 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2506 Unexpect aCatch(SALOME_SalomeException);
2507 return _impl->NbVolumes();
2510 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2512 Unexpect aCatch(SALOME_SalomeException);
2513 return _impl->NbTetras();
2516 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2518 Unexpect aCatch(SALOME_SalomeException);
2519 return _impl->NbHexas();
2522 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2524 Unexpect aCatch(SALOME_SalomeException);
2525 return _impl->NbPyramids();
2528 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2530 Unexpect aCatch(SALOME_SalomeException);
2531 return _impl->NbPrisms();
2534 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2536 Unexpect aCatch(SALOME_SalomeException);
2537 return _impl->NbPolyhedrons();
2540 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2541 throw(SALOME::SALOME_Exception)
2543 Unexpect aCatch(SALOME_SalomeException);
2544 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2547 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2548 throw(SALOME::SALOME_Exception)
2550 Unexpect aCatch(SALOME_SalomeException);
2551 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2554 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2555 throw(SALOME::SALOME_Exception)
2557 Unexpect aCatch(SALOME_SalomeException);
2558 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2561 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2562 throw(SALOME::SALOME_Exception)
2564 Unexpect aCatch(SALOME_SalomeException);
2565 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2568 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2569 throw(SALOME::SALOME_Exception)
2571 Unexpect aCatch(SALOME_SalomeException);
2572 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2575 //=============================================================================
2579 //=============================================================================
2580 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2582 Unexpect aCatch(SALOME_SalomeException);
2583 return _mapSubMesh_i.size();
2586 //=============================================================================
2590 //=============================================================================
2591 char* SMESH_Mesh_i::Dump()
2593 std::ostringstream os;
2595 return CORBA::string_dup( os.str().c_str() );
2598 //=============================================================================
2602 //=============================================================================
2603 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2605 // SMESH::long_array_var aResult = new SMESH::long_array();
2606 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2607 // int aMinId = aSMESHDS_Mesh->MinElementID();
2608 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2610 // aResult->length(aMaxId - aMinId + 1);
2612 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2613 // aResult[i++] = id;
2615 // return aResult._retn();
2617 return GetElementsId();
2620 //=============================================================================
2624 //=============================================================================
2626 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2627 throw (SALOME::SALOME_Exception)
2629 Unexpect aCatch(SALOME_SalomeException);
2630 MESSAGE("SMESH_Mesh_i::GetElementsId");
2631 SMESH::long_array_var aResult = new SMESH::long_array();
2632 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2634 if ( aSMESHDS_Mesh == NULL )
2635 return aResult._retn();
2637 long nbElements = NbElements();
2638 aResult->length( nbElements );
2639 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2640 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2641 aResult[i] = anIt->next()->GetID();
2643 return aResult._retn();
2647 //=============================================================================
2651 //=============================================================================
2653 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2654 throw (SALOME::SALOME_Exception)
2656 Unexpect aCatch(SALOME_SalomeException);
2657 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2658 SMESH::long_array_var aResult = new SMESH::long_array();
2659 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2661 if ( aSMESHDS_Mesh == NULL )
2662 return aResult._retn();
2664 long nbElements = NbElements();
2666 // No sense in returning ids of elements along with ids of nodes:
2667 // when theElemType == SMESH::ALL, return node ids only if
2668 // there are no elements
2669 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2670 return GetNodesId();
2672 aResult->length( nbElements );
2676 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2677 while ( i < nbElements && anIt->more() ) {
2678 const SMDS_MeshElement* anElem = anIt->next();
2679 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2680 aResult[i++] = anElem->GetID();
2683 aResult->length( i );
2685 return aResult._retn();
2688 //=============================================================================
2692 //=============================================================================
2694 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2695 throw (SALOME::SALOME_Exception)
2697 Unexpect aCatch(SALOME_SalomeException);
2698 MESSAGE("SMESH_subMesh_i::GetNodesId");
2699 SMESH::long_array_var aResult = new SMESH::long_array();
2700 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2702 if ( aSMESHDS_Mesh == NULL )
2703 return aResult._retn();
2705 long nbNodes = NbNodes();
2706 aResult->length( nbNodes );
2707 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2708 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2709 aResult[i] = anIt->next()->GetID();
2711 return aResult._retn();
2714 //=============================================================================
2718 //=============================================================================
2720 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2721 throw (SALOME::SALOME_Exception)
2723 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2727 //=============================================================================
2729 * Returns ID of elements for given submesh
2731 //=============================================================================
2732 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2733 throw (SALOME::SALOME_Exception)
2735 SMESH::long_array_var aResult = new SMESH::long_array();
2737 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2738 if(!SM) return aResult._retn();
2740 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2741 if(!SDSM) return aResult._retn();
2743 aResult->length(SDSM->NbElements());
2745 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2747 while ( eIt->more() ) {
2748 aResult[i++] = eIt->next()->GetID();
2751 return aResult._retn();
2755 //=============================================================================
2757 * Returns ID of nodes for given submesh
2758 * If param all==true - returns all nodes, else -
2759 * returns only nodes on shapes.
2761 //=============================================================================
2762 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2763 throw (SALOME::SALOME_Exception)
2765 SMESH::long_array_var aResult = new SMESH::long_array();
2767 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2768 if(!SM) return aResult._retn();
2770 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2771 if(!SDSM) return aResult._retn();
2774 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2775 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2776 while ( nIt->more() ) {
2777 const SMDS_MeshNode* elem = nIt->next();
2778 theElems.insert( elem->GetID() );
2781 else { // all nodes of submesh elements
2782 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2783 while ( eIt->more() ) {
2784 const SMDS_MeshElement* anElem = eIt->next();
2785 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2786 while ( nIt->more() ) {
2787 const SMDS_MeshElement* elem = nIt->next();
2788 theElems.insert( elem->GetID() );
2793 aResult->length(theElems.size());
2794 set<int>::iterator itElem;
2796 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2797 aResult[i++] = *itElem;
2799 return aResult._retn();
2803 //=============================================================================
2805 * Returns type of elements for given submesh
2807 //=============================================================================
2808 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2809 throw (SALOME::SALOME_Exception)
2811 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2812 if(!SM) return SMESH::ALL;
2814 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2815 if(!SDSM) return SMESH::ALL;
2817 if(SDSM->NbElements()==0)
2818 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2820 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2821 const SMDS_MeshElement* anElem = eIt->next();
2822 return ( SMESH::ElementType ) anElem->GetType();
2826 //=============================================================================
2830 //=============================================================================
2832 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2834 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2836 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2841 //=============================================================================
2843 * Get XYZ coordinates of node as list of double
2844 * If there is not node for given ID - returns empty list
2846 //=============================================================================
2848 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2850 SMESH::double_array_var aResult = new SMESH::double_array();
2851 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2852 if ( aSMESHDS_Mesh == NULL )
2853 return aResult._retn();
2856 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2858 return aResult._retn();
2862 aResult[0] = aNode->X();
2863 aResult[1] = aNode->Y();
2864 aResult[2] = aNode->Z();
2865 return aResult._retn();
2869 //=============================================================================
2871 * For given node returns list of IDs of inverse elements
2872 * If there is not node for given ID - returns empty list
2874 //=============================================================================
2876 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2878 SMESH::long_array_var aResult = new SMESH::long_array();
2879 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2880 if ( aSMESHDS_Mesh == NULL )
2881 return aResult._retn();
2884 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2886 return aResult._retn();
2888 // find inverse elements
2889 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2890 TColStd_SequenceOfInteger IDs;
2891 while(eIt->more()) {
2892 const SMDS_MeshElement* elem = eIt->next();
2893 IDs.Append(elem->GetID());
2895 if(IDs.Length()>0) {
2896 aResult->length(IDs.Length());
2898 for(; i<=IDs.Length(); i++) {
2899 aResult[i-1] = IDs.Value(i);
2902 return aResult._retn();
2905 //=============================================================================
2907 * \brief Return position of a node on shape
2909 //=============================================================================
2911 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
2913 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
2914 aNodePosition->shapeID = 0;
2915 aNodePosition->shapeType = GEOM::SHAPE;
2917 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
2918 if ( !mesh ) return aNodePosition;
2920 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
2922 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
2924 aNodePosition->shapeID = pos->GetShapeId();
2925 switch ( pos->GetTypeOfPosition() ) {
2927 aNodePosition->shapeType = GEOM::EDGE;
2928 aNodePosition->params.length(1);
2929 aNodePosition->params[0] =
2930 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
2933 aNodePosition->shapeType = GEOM::FACE;
2934 aNodePosition->params.length(2);
2935 aNodePosition->params[0] =
2936 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
2937 aNodePosition->params[1] =
2938 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
2940 case SMDS_TOP_VERTEX:
2941 aNodePosition->shapeType = GEOM::VERTEX;
2943 case SMDS_TOP_3DSPACE:
2944 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
2945 aNodePosition->shapeType = GEOM::SOLID;
2946 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
2947 aNodePosition->shapeType = GEOM::SHELL;
2953 return aNodePosition;
2956 //=============================================================================
2958 * If given element is node returns IDs of shape from position
2959 * If there is not node for given ID - returns -1
2961 //=============================================================================
2963 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
2965 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2966 if ( aSMESHDS_Mesh == NULL )
2970 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2972 SMDS_PositionPtr pos = aNode->GetPosition();
2976 return pos->GetShapeId();
2983 //=============================================================================
2985 * For given element returns ID of result shape after
2986 * ::FindShape() from SMESH_MeshEditor
2987 * If there is not element for given ID - returns -1
2989 //=============================================================================
2991 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
2993 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2994 if ( aSMESHDS_Mesh == NULL )
2997 // try to find element
2998 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3002 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3003 ::SMESH_MeshEditor aMeshEditor(_impl);
3004 int index = aMeshEditor.FindShape( elem );
3012 //=============================================================================
3014 * Returns number of nodes for given element
3015 * If there is not element for given ID - returns -1
3017 //=============================================================================
3019 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3021 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3022 if ( aSMESHDS_Mesh == NULL ) return -1;
3023 // try to find element
3024 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3025 if(!elem) return -1;
3026 return elem->NbNodes();
3030 //=============================================================================
3032 * Returns ID of node by given index for given element
3033 * If there is not element for given ID - returns -1
3034 * If there is not node for given index - returns -2
3036 //=============================================================================
3038 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3040 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3041 if ( aSMESHDS_Mesh == NULL ) return -1;
3042 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3043 if(!elem) return -1;
3044 if( index>=elem->NbNodes() || index<0 ) return -1;
3045 return elem->GetNode(index)->GetID();
3048 //=============================================================================
3050 * Returns IDs of nodes of given element
3052 //=============================================================================
3054 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3056 SMESH::long_array_var aResult = new SMESH::long_array();
3057 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3059 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3061 aResult->length( elem->NbNodes() );
3062 for ( int i = 0; i < elem->NbNodes(); ++i )
3063 aResult[ i ] = elem->GetNode( i )->GetID();
3066 return aResult._retn();
3069 //=============================================================================
3071 * Returns true if given node is medium node
3072 * in given quadratic element
3074 //=============================================================================
3076 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3078 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3079 if ( aSMESHDS_Mesh == NULL ) return false;
3081 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3082 if(!aNode) return false;
3083 // try to find element
3084 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3085 if(!elem) return false;
3087 return elem->IsMediumNode(aNode);
3091 //=============================================================================
3093 * Returns true if given node is medium node
3094 * in one of quadratic elements
3096 //=============================================================================
3098 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3099 SMESH::ElementType theElemType)
3101 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3102 if ( aSMESHDS_Mesh == NULL ) return false;
3105 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3106 if(!aNode) return false;
3108 SMESH_MesherHelper aHelper( *(_impl) );
3110 SMDSAbs_ElementType aType;
3111 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3112 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3113 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3114 else aType = SMDSAbs_All;
3116 return aHelper.IsMedium(aNode,aType);
3120 //=============================================================================
3122 * Returns number of edges for given element
3124 //=============================================================================
3126 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3128 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3129 if ( aSMESHDS_Mesh == NULL ) return -1;
3130 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3131 if(!elem) return -1;
3132 return elem->NbEdges();
3136 //=============================================================================
3138 * Returns number of faces for given element
3140 //=============================================================================
3142 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3144 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3145 if ( aSMESHDS_Mesh == NULL ) return -1;
3146 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3147 if(!elem) return -1;
3148 return elem->NbFaces();
3152 //=============================================================================
3154 * Returns true if given element is polygon
3156 //=============================================================================
3158 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3160 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3161 if ( aSMESHDS_Mesh == NULL ) return false;
3162 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3163 if(!elem) return false;
3164 return elem->IsPoly();
3168 //=============================================================================
3170 * Returns true if given element is quadratic
3172 //=============================================================================
3174 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3176 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3177 if ( aSMESHDS_Mesh == NULL ) return false;
3178 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3179 if(!elem) return false;
3180 return elem->IsQuadratic();
3184 //=============================================================================
3186 * Returns bary center for given element
3188 //=============================================================================
3190 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3192 SMESH::double_array_var aResult = new SMESH::double_array();
3193 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3194 if ( aSMESHDS_Mesh == NULL )
3195 return aResult._retn();
3197 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3199 return aResult._retn();
3201 if(elem->GetType()==SMDSAbs_Volume) {
3202 SMDS_VolumeTool aTool;
3203 if(aTool.Set(elem)) {
3205 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3210 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3212 double x=0., y=0., z=0.;
3213 for(; anIt->more(); ) {
3215 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3229 return aResult._retn();
3233 //=============================================================================
3235 * Create and publish group servants if any groups were imported or created anyhow
3237 //=============================================================================
3239 void SMESH_Mesh_i::CreateGroupServants()
3241 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3243 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3244 while ( groupIt->more() )
3246 ::SMESH_Group* group = groupIt->next();
3247 int anId = group->GetGroupDS()->GetID();
3249 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3250 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3253 SMESH_GroupBase_i* aGroupImpl;
3255 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3256 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3258 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3259 shape = groupOnGeom->GetShape();
3262 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3265 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3266 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3267 aGroupImpl->Register();
3269 SMESH::SMESH_GroupBase_var groupVar =
3270 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3271 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3273 // register CORBA object for persistence
3274 int nextId = _gen_i->RegisterObject( groupVar );
3275 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3277 // publishing of the groups in the study
3278 if ( !aStudy->_is_nil() ) {
3279 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3280 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3285 //=============================================================================
3287 * \brief Return groups cantained in _mapGroups by their IDs
3289 //=============================================================================
3291 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3293 int nbGroups = groupIDs.size();
3294 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3295 aList->length( nbGroups );
3297 list<int>::const_iterator ids = groupIDs.begin();
3298 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3300 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3301 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3302 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3304 aList->length( nbGroups );
3305 return aList._retn();
3308 //=============================================================================
3310 * \brief Return information about imported file
3312 //=============================================================================
3314 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3316 SALOME_MED::MedFileInfo_var res( myFileInfo );
3317 if ( !res.operator->() ) {
3318 res = new SALOME_MED::MedFileInfo;
3320 res->fileSize = res->major = res->minor = res->release = -1;
3325 //=============================================================================
3327 * \brief Check and correct names of mesh groups
3329 //=============================================================================
3331 void SMESH_Mesh_i::checkGroupNames()
3333 int nbGrp = NbGroups();
3337 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3338 if ( aStudy->_is_nil() )
3339 return; // nothing to do
3341 SMESH::ListOfGroups* grpList = 0;
3342 // avoid dump of "GetGroups"
3344 // store python dump into a local variable inside local scope
3345 SMESH::TPythonDump pDump; // do not delete this line of code
3346 grpList = GetGroups();
3349 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3350 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3353 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3354 if ( aGrpSO->_is_nil() )
3356 // correct name of the mesh group if necessary
3357 const char* guiName = aGrpSO->GetName();
3358 if ( strcmp(guiName, aGrp->GetName()) )
3359 aGrp->SetName( guiName );
3363 //=============================================================================
3365 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3367 //=============================================================================
3368 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3370 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3371 CORBA::string_dup(theParameters));
3374 //=============================================================================
3376 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3378 //=============================================================================
3379 char* SMESH_Mesh_i::GetParameters()
3381 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3382 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3385 //=============================================================================
3387 * \brief Returns list of notebook variables used for last Mesh operation
3389 //=============================================================================
3390 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3392 SMESH::string_array_var aResult = new SMESH::string_array();
3393 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3395 char *aParameters = GetParameters();
3396 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3397 if(!aStudy->_is_nil()) {
3398 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3399 if(aSections->length() > 0) {
3400 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3401 aResult->length(aVars.length());
3402 for(int i = 0;i < aVars.length();i++)
3403 aResult[i] = CORBA::string_dup( aVars[i]);
3407 return aResult._retn();
3410 //=============================================================================
3412 * \brief Returns statistic of mesh elements
3414 //=============================================================================
3415 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3417 SMESH::long_array_var aRes = new SMESH::long_array();
3418 aRes->length(SMESH::Entity_Last);
3419 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3421 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3423 return aRes._retn();
3424 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3425 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3426 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3427 return aRes._retn();
3430 //=============================================================================
3432 * \brief Collect statistic of mesh elements given by iterator
3434 //=============================================================================
3435 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3436 SMESH::long_array& theInfo)
3438 if (!theItr) return;
3439 while (theItr->more())
3440 theInfo[ theItr->next()->GetEntityType() ]++;