1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
24 // File : SMESH_Mesh_i.cxx
25 // Author : Paul RASCLE, EDF
28 #include "SMESH_Mesh_i.hxx"
30 #include "SMESH_Filter_i.hxx"
31 #include "SMESH_Gen_i.hxx"
32 #include "SMESH_Group_i.hxx"
33 #include "SMESH_MEDMesh_i.hxx"
34 #include "SMESH_MeshEditor_i.hxx"
35 #include "SMESH_PythonDump.hxx"
36 #include "SMESH_subMesh_i.hxx"
38 #include "DriverMED_R_SMESHDS_Mesh.h"
39 #include "DriverMED_W_SMESHDS_Mesh.h"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMDS_ElemIterator.hxx"
42 #include "SMESHDS_Command.hxx"
43 #include "SMESHDS_CommandType.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Group.hxx"
46 #include "SMESH_MeshEditor.hxx"
47 #include "SMESH_MesherHelper.hxx"
48 #include "SMDS_EdgePosition.hxx"
49 #include "SMDS_FacePosition.hxx"
52 #include "SALOME_NamingService.hxx"
53 #include "Utils_CorbaException.hxx"
54 #include "Utils_ExceptHandlers.hxx"
55 #include "Utils_SINGLETON.hxx"
56 #include "utilities.h"
57 #include "GEOMImpl_Types.hxx"
60 #include <BRep_Builder.hxx>
61 #include <OSD_Directory.hxx>
62 #include <OSD_File.hxx>
63 #include <OSD_Path.hxx>
64 #include <OSD_Protection.hxx>
65 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
66 #include <TColStd_MapOfInteger.hxx>
67 #include <TColStd_SequenceOfInteger.hxx>
68 #include <TCollection_AsciiString.hxx>
70 #include <TopExp_Explorer.hxx>
71 #include <TopoDS_Compound.hxx>
72 #include <TopTools_MapOfShape.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
83 static int MYDEBUG = 0;
85 static int MYDEBUG = 0;
89 using SMESH::TPythonDump;
91 int SMESH_Mesh_i::myIdGenerator = 0;
95 //=============================================================================
99 //=============================================================================
101 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
103 CORBA::Long studyId )
104 : SALOME::GenericObj_i( thePOA )
106 MESSAGE("SMESH_Mesh_i");
109 _id = myIdGenerator++;
113 //=============================================================================
117 //=============================================================================
119 SMESH_Mesh_i::~SMESH_Mesh_i()
121 INFOS("~SMESH_Mesh_i");
122 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
123 for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
124 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
126 // this method is colled from destructor of group (PAL6331)
127 //_impl->RemoveGroup( aGroup->GetLocalID() );
136 //=============================================================================
140 * Associates <this> mesh with <theShape> and puts a reference
141 * to <theShape> into the current study;
142 * the previous shape is substituted by the new one.
144 //=============================================================================
146 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
147 throw (SALOME::SALOME_Exception)
149 Unexpect aCatch(SALOME_SalomeException);
151 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
153 catch(SALOME_Exception & S_ex) {
154 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
156 // to track changes of GEOM groups
157 addGeomGroupData( theShapeObject, _this() );
160 //================================================================================
162 * \brief return true if mesh has a shape to build a shape on
164 //================================================================================
166 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
167 throw (SALOME::SALOME_Exception)
169 Unexpect aCatch(SALOME_SalomeException);
172 res = _impl->HasShapeToMesh();
174 catch(SALOME_Exception & S_ex) {
175 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
180 //=======================================================================
181 //function : GetShapeToMesh
183 //=======================================================================
185 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
189 GEOM::GEOM_Object_var aShapeObj;
191 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
193 aShapeObj = _gen_i->ShapeToGeomObject( S );
195 catch(SALOME_Exception & S_ex) {
196 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
198 return aShapeObj._retn();
201 //================================================================================
203 * \brief Remove all nodes and elements
205 //================================================================================
207 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
209 Unexpect aCatch(SALOME_SalomeException);
212 CheckGeomGroupModif(); // issue 20145
214 catch(SALOME_Exception & S_ex) {
215 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
217 TPythonDump() << _this() << ".Clear()";
220 //================================================================================
222 * \brief Remove all nodes and elements for indicated shape
224 //================================================================================
226 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
227 throw (SALOME::SALOME_Exception)
229 Unexpect aCatch(SALOME_SalomeException);
231 _impl->ClearSubMesh( ShapeID );
233 catch(SALOME_Exception & S_ex) {
234 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
238 //=============================================================================
242 //=============================================================================
244 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
246 SMESH::DriverMED_ReadStatus res;
249 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
250 res = SMESH::DRS_OK; break;
251 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
252 res = SMESH::DRS_EMPTY; break;
253 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
254 res = SMESH::DRS_WARN_RENUMBER; break;
255 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
256 res = SMESH::DRS_WARN_SKIP_ELEM; break;
257 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
259 res = SMESH::DRS_FAIL; break;
264 //=============================================================================
268 * Imports mesh data from MED file
270 //=============================================================================
272 SMESH::DriverMED_ReadStatus
273 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
274 throw ( SALOME::SALOME_Exception )
276 Unexpect aCatch(SALOME_SalomeException);
279 status = _impl->MEDToMesh( theFileName, theMeshName );
281 catch( SALOME_Exception& S_ex ) {
282 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
285 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
288 CreateGroupServants();
290 int major, minor, release;
291 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
292 major = minor = release = -1;
293 myFileInfo = new SALOME_MED::MedFileInfo();
294 myFileInfo->fileName = theFileName;
295 myFileInfo->fileSize = 0;
298 if ( ::_stati64( theFileName, &d ) != -1 )
301 if ( ::stat64( theFileName, &d ) != -1 )
303 myFileInfo->fileSize = d.st_size;
304 myFileInfo->major = major;
305 myFileInfo->minor = minor;
306 myFileInfo->release = release;
308 return ConvertDriverMEDReadStatus(status);
311 //================================================================================
313 * \brief Return string representation of a MED file version comprising nbDigits
315 //================================================================================
317 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
319 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
321 return CORBA::string_dup( ver.c_str() );
324 //=============================================================================
328 * Imports mesh data from MED file
330 //=============================================================================
332 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
333 throw ( SALOME::SALOME_Exception )
335 // Read mesh with name = <theMeshName> into SMESH_Mesh
336 _impl->UNVToMesh( theFileName );
338 CreateGroupServants();
343 //=============================================================================
347 * Imports mesh data from STL file
349 //=============================================================================
350 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
351 throw ( SALOME::SALOME_Exception )
353 // Read mesh with name = <theMeshName> into SMESH_Mesh
354 _impl->STLToMesh( theFileName );
359 //=============================================================================
363 * Imports mesh data from MED file
365 //=============================================================================
367 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
369 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
370 // int status = _impl->MEDToMesh( theFileName, theMeshName );
371 // CreateGroupServants();
376 //=============================================================================
380 //=============================================================================
382 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
384 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
385 (SMESH_Hypothesis::Hypothesis_Status theStatus)
388 RETURNCASE( HYP_OK );
389 RETURNCASE( HYP_MISSING );
390 RETURNCASE( HYP_CONCURENT );
391 RETURNCASE( HYP_BAD_PARAMETER );
392 RETURNCASE( HYP_HIDDEN_ALGO );
393 RETURNCASE( HYP_HIDING_ALGO );
394 RETURNCASE( HYP_UNKNOWN_FATAL );
395 RETURNCASE( HYP_INCOMPATIBLE );
396 RETURNCASE( HYP_NOTCONFORM );
397 RETURNCASE( HYP_ALREADY_EXIST );
398 RETURNCASE( HYP_BAD_DIM );
399 RETURNCASE( HYP_BAD_SUBSHAPE );
400 RETURNCASE( HYP_BAD_GEOMETRY );
401 RETURNCASE( HYP_NEED_SHAPE );
404 return SMESH::HYP_UNKNOWN_FATAL;
407 //=============================================================================
411 * calls internal addHypothesis() and then adds a reference to <anHyp> under
412 * the SObject actually having a reference to <aSubShape>.
413 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
415 //=============================================================================
417 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
418 SMESH::SMESH_Hypothesis_ptr anHyp)
419 throw(SALOME::SALOME_Exception)
421 Unexpect aCatch(SALOME_SalomeException);
422 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
424 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
425 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
426 aSubShapeObject, anHyp );
428 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
430 // Update Python script
431 if(_impl->HasShapeToMesh()) {
432 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
433 << aSubShapeObject << ", " << anHyp << " )";
436 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
439 return ConvertHypothesisStatus(status);
442 //=============================================================================
446 //=============================================================================
448 SMESH_Hypothesis::Hypothesis_Status
449 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
450 SMESH::SMESH_Hypothesis_ptr anHyp)
452 if(MYDEBUG) MESSAGE("addHypothesis");
454 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
455 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
458 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
459 if (CORBA::is_nil(myHyp))
460 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
463 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
466 TopoDS_Shape myLocSubShape;
467 //use PseudoShape in case if mesh has no shape
469 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
471 myLocSubShape = _impl->GetShapeToMesh();
473 int hypId = myHyp->GetId();
474 status = _impl->AddHypothesis(myLocSubShape, hypId);
475 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
476 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
477 // assure there is a corresponding submesh
478 if ( !_impl->IsMainShape( myLocSubShape )) {
479 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
480 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
481 createSubMesh( aSubShapeObject );
485 catch(SALOME_Exception & S_ex)
487 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
492 //=============================================================================
496 //=============================================================================
498 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
499 SMESH::SMESH_Hypothesis_ptr anHyp)
500 throw(SALOME::SALOME_Exception)
502 Unexpect aCatch(SALOME_SalomeException);
503 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
505 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
506 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
507 aSubShapeObject, anHyp );
509 // Update Python script
510 // Update Python script
511 if(_impl->HasShapeToMesh()) {
512 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
513 << aSubShapeObject << ", " << anHyp << " )";
516 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
520 return ConvertHypothesisStatus(status);
523 //=============================================================================
527 //=============================================================================
529 SMESH_Hypothesis::Hypothesis_Status
530 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
531 SMESH::SMESH_Hypothesis_ptr anHyp)
533 if(MYDEBUG) MESSAGE("removeHypothesis()");
534 // **** proposer liste de subShape (selection multiple)
536 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
537 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
539 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
540 if (CORBA::is_nil(myHyp))
541 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
543 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
546 TopoDS_Shape myLocSubShape;
547 //use PseudoShape in case if mesh has no shape
549 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
551 myLocSubShape = _impl->GetShapeToMesh();
553 int hypId = myHyp->GetId();
554 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
555 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
556 // _mapHypo.erase( hypId );
558 catch(SALOME_Exception & S_ex)
560 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
565 //=============================================================================
569 //=============================================================================
571 SMESH::ListOfHypothesis *
572 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
573 throw(SALOME::SALOME_Exception)
575 Unexpect aCatch(SALOME_SalomeException);
576 if (MYDEBUG) MESSAGE("GetHypothesisList");
577 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
578 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
580 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
583 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
584 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
585 myLocSubShape = _impl->GetShapeToMesh();
586 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
587 int i = 0, n = aLocalList.size();
590 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
591 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
592 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
593 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
598 catch(SALOME_Exception & S_ex) {
599 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
602 return aList._retn();
605 //=============================================================================
609 //=============================================================================
610 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
611 const char* theName )
612 throw(SALOME::SALOME_Exception)
614 Unexpect aCatch(SALOME_SalomeException);
615 MESSAGE("SMESH_Mesh_i::GetSubMesh");
616 if (CORBA::is_nil(aSubShapeObject))
617 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
620 SMESH::SMESH_subMesh_var subMesh;
621 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
623 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
625 //Get or Create the SMESH_subMesh object implementation
627 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
628 subMesh = getSubMesh( subMeshId );
630 // create a new subMesh object servant if there is none for the shape
631 if ( subMesh->_is_nil() )
632 subMesh = createSubMesh( aSubShapeObject );
633 if ( _gen_i->CanPublishInStudy( subMesh )) {
634 SALOMEDS::SObject_var aSO =
635 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
636 subMesh, aSubShapeObject, theName );
637 if ( !aSO->_is_nil()) {
638 // Update Python script
639 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
640 << aSubShapeObject << ", '" << theName << "' )";
644 catch(SALOME_Exception & S_ex) {
645 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
647 return subMesh._retn();
650 //=============================================================================
654 //=============================================================================
656 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
657 throw (SALOME::SALOME_Exception)
659 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
660 if ( theSubMesh->_is_nil() )
663 GEOM::GEOM_Object_var aSubShapeObject;
664 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
665 if ( !aStudy->_is_nil() ) {
666 // Remove submesh's SObject
667 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
668 if ( !anSO->_is_nil() ) {
669 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
670 SALOMEDS::SObject_var anObj, aRef;
671 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
672 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
674 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
675 // aSubShapeObject = theSubMesh->GetSubShape();
677 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
679 // Update Python script
680 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
684 removeSubMesh( theSubMesh, aSubShapeObject.in() );
687 //=============================================================================
691 //=============================================================================
692 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
693 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
695 switch (theElemType) {
700 CASE2STRING( VOLUME );
706 //=============================================================================
710 //=============================================================================
712 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
713 const char* theName )
714 throw(SALOME::SALOME_Exception)
716 Unexpect aCatch(SALOME_SalomeException);
717 SMESH::SMESH_Group_var aNewGroup =
718 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
720 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
721 SALOMEDS::SObject_var aSO =
722 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
723 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
724 if ( !aSO->_is_nil()) {
725 // Update Python script
726 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
727 << ElementTypeString(theElemType) << ", '" << theName << "' )";
730 return aNewGroup._retn();
734 //=============================================================================
738 //=============================================================================
739 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
741 GEOM::GEOM_Object_ptr theGeomObj)
742 throw(SALOME::SALOME_Exception)
744 Unexpect aCatch(SALOME_SalomeException);
745 SMESH::SMESH_GroupOnGeom_var aNewGroup;
747 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
748 if ( !aShape.IsNull() )
750 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
751 ( createGroup( theElemType, theName, aShape ));
753 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
754 SALOMEDS::SObject_var aSO =
755 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
756 aNewGroup, theGeomObj, theName);
757 if ( !aSO->_is_nil()) {
758 // Update Python script
759 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
760 << ElementTypeString(theElemType) << ", '" << theName << "', "
761 << theGeomObj << " )";
766 return aNewGroup._retn();
769 //=============================================================================
773 //=============================================================================
775 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
776 throw (SALOME::SALOME_Exception)
778 if ( theGroup->_is_nil() )
781 SMESH_GroupBase_i* aGroup =
782 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
786 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
787 if ( !aStudy->_is_nil() ) {
788 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
790 if ( !aGroupSO->_is_nil() ) {
791 // Update Python script
792 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
794 // Remove group's SObject
795 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
799 // Remove the group from SMESH data structures
800 removeGroup( aGroup->GetLocalID() );
803 //=============================================================================
804 /*! RemoveGroupWithContents
805 * Remove group with its contents
807 //=============================================================================
808 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
809 throw (SALOME::SALOME_Exception)
811 if ( theGroup->_is_nil() )
814 SMESH_GroupBase_i* aGroup =
815 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
819 SMESH::long_array_var anIds = aGroup->GetListOfID();
820 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
822 // Update Python script
823 TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
826 if ( aGroup->GetType() == SMESH::NODE )
827 aMeshEditor->RemoveNodes( anIds );
829 aMeshEditor->RemoveElements( anIds );
832 RemoveGroup( theGroup );
834 // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
835 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
836 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
840 //================================================================================
842 * \brief Get the list of groups existing in the mesh
843 * \retval SMESH::ListOfGroups * - list of groups
845 //================================================================================
847 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
849 Unexpect aCatch(SALOME_SalomeException);
850 if (MYDEBUG) MESSAGE("GetGroups");
852 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
855 TPythonDump aPythonDump;
856 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
860 aList->length( _mapGroups.size() );
862 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
863 for ( ; it != _mapGroups.end(); it++ ) {
864 if ( CORBA::is_nil( it->second )) continue;
865 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
867 if (i > 1) aPythonDump << ", ";
868 aPythonDump << it->second;
872 catch(SALOME_Exception & S_ex) {
873 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
876 // Update Python script
877 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
878 aPythonDump << " ] = " << _this() << ".GetGroups()";
880 return aList._retn();
882 //=============================================================================
884 * Get number of groups existing in the mesh
886 //=============================================================================
888 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
890 Unexpect aCatch(SALOME_SalomeException);
891 return _mapGroups.size();
894 //=============================================================================
896 * New group is created. All mesh elements that are
897 * present in initial groups are added to the new one
899 //=============================================================================
900 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
901 SMESH::SMESH_GroupBase_ptr theGroup2,
902 const char* theName )
903 throw (SALOME::SALOME_Exception)
907 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
908 theGroup1->GetType() != theGroup2->GetType() )
909 return SMESH::SMESH_Group::_nil();
912 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
913 if ( aResGrp->_is_nil() )
914 return SMESH::SMESH_Group::_nil();
916 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
917 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
919 TColStd_MapOfInteger aResMap;
921 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
922 aResMap.Add( anIds1[ i1 ] );
924 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
925 aResMap.Add( anIds2[ i2 ] );
927 SMESH::long_array_var aResIds = new SMESH::long_array;
928 aResIds->length( aResMap.Extent() );
931 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
932 for( ; anIter.More(); anIter.Next() )
933 aResIds[ resI++ ] = anIter.Key();
935 aResGrp->Add( aResIds );
937 // Clear python lines, created by CreateGroup() and Add()
938 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
939 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
940 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
942 // Update Python script
943 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
944 << theGroup1 << ", " << theGroup2 << ", '"
947 return aResGrp._retn();
951 return SMESH::SMESH_Group::_nil();
955 //=============================================================================
957 \brief Union list of groups. New group is created. All mesh elements that are
958 present in initial groups are added to the new one.
959 \param theGroups list of groups
960 \param theName name of group to be created
961 \return pointer on the group
963 //=============================================================================
964 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
965 const char* theName )
966 throw (SALOME::SALOME_Exception)
969 return SMESH::SMESH_Group::_nil();
974 SMESH::ElementType aType = SMESH::ALL;
975 for ( int g = 0, n = theGroups.length(); g < n; g++ )
977 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
978 if ( CORBA::is_nil( aGrp ) )
982 SMESH::ElementType aCurrType = aGrp->GetType();
983 if ( aType == SMESH::ALL )
987 if ( aType != aCurrType )
988 return SMESH::SMESH_Group::_nil();
992 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
993 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
995 int aCurrId = aCurrIds[ i ];
996 anIds.push_back( aCurrId );
1001 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1002 if ( aResGrp->_is_nil() )
1003 return SMESH::SMESH_Group::_nil();
1005 // Create array of identifiers
1006 SMESH::long_array_var aResIds = new SMESH::long_array;
1007 aResIds->length( anIds.size() );
1009 //NCollection_Map< int >::Iterator anIter( anIds );
1010 for ( int i = 0; i<anIds.size(); i++ )
1012 aResIds[ i ] = anIds[i];
1014 aResGrp->Add( aResIds );
1016 // Clear python lines, created by CreateGroup() and Add()
1017 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1018 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1019 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1021 // Update Python script
1023 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1024 << &theGroups << ", '" << theName << "' )";
1026 return aResGrp._retn();
1030 return SMESH::SMESH_Group::_nil();
1034 //=============================================================================
1036 * New group is created. All mesh elements that are
1037 * present in both initial groups are added to the new one.
1039 //=============================================================================
1040 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1041 SMESH::SMESH_GroupBase_ptr theGroup2,
1042 const char* theName )
1043 throw (SALOME::SALOME_Exception)
1045 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1046 theGroup1->GetType() != theGroup2->GetType() )
1047 return SMESH::SMESH_Group::_nil();
1049 // Create Intersection
1050 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1051 if ( aResGrp->_is_nil() )
1054 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1055 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1057 TColStd_MapOfInteger aMap1;
1059 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1060 aMap1.Add( anIds1[ i1 ] );
1062 TColStd_SequenceOfInteger aSeq;
1064 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1065 if ( aMap1.Contains( anIds2[ i2 ] ) )
1066 aSeq.Append( anIds2[ i2 ] );
1068 SMESH::long_array_var aResIds = new SMESH::long_array;
1069 aResIds->length( aSeq.Length() );
1071 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1072 aResIds[ resI ] = aSeq( resI + 1 );
1074 aResGrp->Add( aResIds );
1076 // Clear python lines, created by CreateGroup() and Add()
1077 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1078 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1079 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1081 // Update Python script
1082 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1083 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1085 return aResGrp._retn();
1088 //=============================================================================
1090 \brief Intersect list of groups. New group is created. All mesh elements that
1091 are present in all initial groups simultaneously are added to the new one.
1092 \param theGroups list of groups
1093 \param theName name of group to be created
1094 \return pointer on the group
1096 //=============================================================================
1097 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1098 const SMESH::ListOfGroups& theGroups, const char* theName )
1099 throw (SALOME::SALOME_Exception)
1102 return SMESH::SMESH_Group::_nil();
1106 NCollection_DataMap< int, int > anIdToCount;
1107 SMESH::ElementType aType = SMESH::ALL;
1108 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1110 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1111 if ( CORBA::is_nil( aGrp ) )
1115 SMESH::ElementType aCurrType = aGrp->GetType();
1116 if ( aType == SMESH::ALL )
1120 if ( aType != aCurrType )
1121 return SMESH::SMESH_Group::_nil();
1124 // calculates number of occurance ids in groups
1125 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1126 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1128 int aCurrId = aCurrIds[ i ];
1129 if ( !anIdToCount.IsBound( aCurrId ) )
1130 anIdToCount.Bind( aCurrId, 1 );
1132 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1136 // create map of ids
1137 int nbGrp = theGroups.length();
1138 vector< int > anIds;
1139 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1140 for ( ; anIter.More(); anIter.Next() )
1142 int aCurrId = anIter.Key();
1143 int aCurrNb = anIter.Value();
1144 if ( aCurrNb == nbGrp )
1145 anIds.push_back( aCurrId );
1149 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1150 if ( aResGrp->_is_nil() )
1151 return SMESH::SMESH_Group::_nil();
1153 // Create array of identifiers
1154 SMESH::long_array_var aResIds = new SMESH::long_array;
1155 aResIds->length( anIds.size() );
1157 //NCollection_Map< int >::Iterator aListIter( anIds );
1158 for ( int i = 0; i<anIds.size(); i++ )
1160 aResIds[ i ] = anIds[i];
1162 aResGrp->Add( aResIds );
1164 // Clear python lines, created by CreateGroup() and Add()
1165 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1166 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1167 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1169 // Update Python script
1171 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1172 << &theGroups << ", '" << theName << "' )";
1174 return aResGrp._retn();
1178 return SMESH::SMESH_Group::_nil();
1182 //=============================================================================
1184 * New group is created. All mesh elements that are present in
1185 * main group but do not present in tool group are added to the new one
1187 //=============================================================================
1188 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1189 SMESH::SMESH_GroupBase_ptr theGroup2,
1190 const char* theName )
1191 throw (SALOME::SALOME_Exception)
1193 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1194 theGroup1->GetType() != theGroup2->GetType() )
1195 return SMESH::SMESH_Group::_nil();
1198 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1199 if ( aResGrp->_is_nil() )
1202 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1203 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1205 TColStd_MapOfInteger aMap2;
1207 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1208 aMap2.Add( anIds2[ i2 ] );
1210 TColStd_SequenceOfInteger aSeq;
1211 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1212 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1213 aSeq.Append( anIds1[ i1 ] );
1215 SMESH::long_array_var aResIds = new SMESH::long_array;
1216 aResIds->length( aSeq.Length() );
1218 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1219 aResIds[ resI ] = aSeq( resI + 1 );
1221 aResGrp->Add( aResIds );
1223 // Clear python lines, created by CreateGroup() and Add()
1224 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1225 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1226 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1228 // Update Python script
1229 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1230 << theGroup1 << ", " << theGroup2 << ", '"
1231 << theName << "' )";
1233 return aResGrp._retn();
1236 //=============================================================================
1238 \brief Cut lists of groups. New group is created. All mesh elements that are
1239 present in main groups but do not present in tool groups are added to the new one
1240 \param theMainGroups list of main groups
1241 \param theToolGroups list of tool groups
1242 \param theName name of group to be created
1243 \return pointer on the group
1245 //=============================================================================
1246 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1247 const SMESH::ListOfGroups& theMainGroups,
1248 const SMESH::ListOfGroups& theToolGroups,
1249 const char* theName )
1250 throw (SALOME::SALOME_Exception)
1253 return SMESH::SMESH_Group::_nil();
1257 set< int > aToolIds;
1258 SMESH::ElementType aType = SMESH::ALL;
1260 // iterate through tool groups
1261 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1263 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1264 if ( CORBA::is_nil( aGrp ) )
1268 SMESH::ElementType aCurrType = aGrp->GetType();
1269 if ( aType == SMESH::ALL )
1273 if ( aType != aCurrType )
1274 return SMESH::SMESH_Group::_nil();
1278 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1279 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1281 int aCurrId = aCurrIds[ i ];
1282 aToolIds.insert( aCurrId );
1286 vector< int > anIds; // result
1288 // Iterate through main group
1289 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1291 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1292 if ( CORBA::is_nil( aGrp ) )
1296 SMESH::ElementType aCurrType = aGrp->GetType();
1297 if ( aType == SMESH::ALL )
1301 if ( aType != aCurrType )
1302 return SMESH::SMESH_Group::_nil();
1306 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1307 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1309 int aCurrId = aCurrIds[ i ];
1310 if ( !aToolIds.count( aCurrId ) )
1311 anIds.push_back( aCurrId );
1316 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1317 if ( aResGrp->_is_nil() )
1318 return SMESH::SMESH_Group::_nil();
1320 // Create array of identifiers
1321 SMESH::long_array_var aResIds = new SMESH::long_array;
1322 aResIds->length( anIds.size() );
1324 for (int i=0; i<anIds.size(); i++ )
1326 aResIds[ i ] = anIds[i];
1328 aResGrp->Add( aResIds );
1330 // Clear python lines, created by CreateGroup() and Add()
1331 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1332 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1333 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1335 // Update Python script
1337 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1338 << &theMainGroups << ", " << &theToolGroups << ", '"
1339 << theName << "' )";
1341 return aResGrp._retn();
1345 return SMESH::SMESH_Group::_nil();
1349 //=============================================================================
1351 \brief Create groups of entities from existing groups of superior dimensions
1353 1) extract all nodes from each group,
1354 2) combine all elements of specified dimension laying on these nodes.
1355 \param theGroups list of source groups
1356 \param theElemType dimension of elements
1357 \param theName name of new group
1358 \return pointer on new group
1360 //=============================================================================
1361 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1362 const SMESH::ListOfGroups& theGroups,
1363 SMESH::ElementType theElemType,
1364 const char* theName )
1365 throw (SALOME::SALOME_Exception)
1367 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1369 if ( !theName || !aMeshDS )
1370 return SMESH::SMESH_Group::_nil();
1372 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1376 // Create map of nodes from all groups
1378 set< int > aNodeMap;
1380 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1382 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1383 if ( CORBA::is_nil( aGrp ) )
1386 SMESH::ElementType aType = aGrp->GetType();
1387 if ( aType == SMESH::ALL )
1389 else if ( aType == SMESH::NODE )
1391 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1392 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1394 int aCurrId = aCurrIds[ i ];
1395 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1397 aNodeMap.insert( aNode->GetID() );
1402 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1403 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1405 int aCurrId = aCurrIds[ i ];
1406 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1409 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1410 while( aNodeIter->more() )
1412 const SMDS_MeshNode* aNode =
1413 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1415 aNodeMap.insert( aNode->GetID() );
1421 // Get result identifiers
1423 vector< int > aResultIds;
1424 if ( theElemType == SMESH::NODE )
1426 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1427 set<int>::iterator iter = aNodeMap.begin();
1428 for ( ; iter != aNodeMap.end(); iter++ )
1429 aResultIds.push_back( *iter);
1433 // Create list of elements of given dimension constructed on the nodes
1434 vector< int > anElemList;
1435 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1436 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1437 set<int>::iterator iter = aNodeMap.begin();
1438 for ( ; iter != aNodeMap.end(); iter++ )
1440 const SMDS_MeshElement* aNode =
1441 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1445 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1446 while( anElemIter->more() )
1448 const SMDS_MeshElement* anElem =
1449 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1450 if ( anElem && anElem->GetType() == anElemType )
1451 anElemList.push_back( anElem->GetID() );
1455 // check whether all nodes of elements are present in nodes map
1456 //NCollection_Map< int >::Iterator anIter( anElemList );
1457 //for ( ; anIter.More(); anIter.Next() )
1458 for (int i=0; i< anElemList.size(); i++)
1460 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1465 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1466 while( aNodeIter->more() )
1468 const SMDS_MeshNode* aNode =
1469 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1470 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1477 aResultIds.push_back( anElem->GetID() );
1483 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1484 if ( aResGrp->_is_nil() )
1485 return SMESH::SMESH_Group::_nil();
1487 // Create array of identifiers
1488 SMESH::long_array_var aResIds = new SMESH::long_array;
1489 aResIds->length( aResultIds.size() );
1491 //NCollection_Map< int >::Iterator aResIter( aResultIds );
1492 //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1493 for (int i=0; i< aResultIds.size(); i++)
1494 aResIds[ i ] = aResultIds[i];
1495 aResGrp->Add( aResIds );
1497 // Remove strings corresponding to group creation
1498 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1499 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1500 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1502 // Update Python script
1504 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1505 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1507 return aResGrp._retn();
1511 return SMESH::SMESH_Group::_nil();
1515 //================================================================================
1517 * \brief Remember GEOM group data
1519 //================================================================================
1521 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1522 CORBA::Object_ptr theSmeshObj)
1524 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1527 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1528 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1529 if ( groupSO->_is_nil() )
1532 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1533 GEOM::GEOM_IGroupOperations_var groupOp =
1534 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1535 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1538 _geomGroupData.push_back( TGeomGroupData() );
1539 TGeomGroupData & groupData = _geomGroupData.back();
1541 CORBA::String_var entry = groupSO->GetID();
1542 groupData._groupEntry = entry.in();
1544 for ( int i = 0; i < ids->length(); ++i )
1545 groupData._indices.insert( ids[i] );
1547 groupData._smeshObject = theSmeshObj;
1550 //================================================================================
1552 * Remove GEOM group data relating to removed smesh object
1554 //================================================================================
1556 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1558 list<TGeomGroupData>::iterator
1559 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1560 for ( ; data != dataEnd; ++data ) {
1561 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1562 _geomGroupData.erase( data );
1568 //================================================================================
1570 * \brief Return new group contents if it has been changed and update group data
1572 //================================================================================
1574 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1576 TopoDS_Shape newShape;
1579 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1580 if ( study->_is_nil() ) return newShape; // means "not changed"
1581 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1582 if ( !groupSO->_is_nil() )
1584 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1585 if ( CORBA::is_nil( groupObj )) return newShape;
1586 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1588 // get indices of group items
1589 set<int> curIndices;
1590 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1591 GEOM::GEOM_IGroupOperations_var groupOp =
1592 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1593 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1594 for ( int i = 0; i < ids->length(); ++i )
1595 curIndices.insert( ids[i] );
1597 if ( groupData._indices == curIndices )
1598 return newShape; // group not changed
1601 groupData._indices = curIndices;
1603 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1604 if ( !geomClient ) return newShape;
1605 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1606 geomClient->RemoveShapeFromBuffer( groupIOR );
1607 newShape = _gen_i->GeomObjectToShape( geomGroup );
1610 if ( newShape.IsNull() ) {
1611 // geom group becomes empty - return empty compound
1612 TopoDS_Compound compound;
1613 BRep_Builder().MakeCompound(compound);
1614 newShape = compound;
1620 //=============================================================================
1622 * \brief Storage of shape and index used in CheckGeomGroupModif()
1624 //=============================================================================
1625 struct TIndexedShape {
1627 TopoDS_Shape _shape;
1628 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1631 //=============================================================================
1633 * \brief Update objects depending on changed geom groups
1635 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1636 * issue 0020210: Update of a smesh group after modification of the associated geom group
1638 //=============================================================================
1640 void SMESH_Mesh_i::CheckGeomGroupModif()
1642 if ( !_impl->HasShapeToMesh() ) return;
1644 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1645 if ( study->_is_nil() ) return;
1647 CORBA::Long nbEntities = NbNodes() + NbElements();
1649 // Check if group contents changed
1651 typedef map< string, TopoDS_Shape > TEntry2Geom;
1652 TEntry2Geom newGroupContents;
1654 list<TGeomGroupData>::iterator
1655 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1656 for ( ; data != dataEnd; ++data )
1658 pair< TEntry2Geom::iterator, bool > it_new =
1659 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1660 bool processedGroup = !it_new.second;
1661 TopoDS_Shape& newShape = it_new.first->second;
1662 if ( !processedGroup )
1663 newShape = newGroupShape( *data );
1664 if ( newShape.IsNull() )
1665 continue; // no changes
1667 if ( processedGroup ) { // update group indices
1668 list<TGeomGroupData>::iterator data2 = data;
1669 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1670 data->_indices = data2->_indices;
1673 // Update SMESH objects according to new GEOM group contents
1675 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1676 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1678 int oldID = submesh->GetId();
1679 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1681 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1683 // update hypotheses
1684 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1685 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1686 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1688 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1689 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1691 // care of submeshes
1692 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1693 int newID = newSubmesh->GetId();
1694 if ( newID != oldID ) {
1695 _mapSubMesh [ newID ] = newSubmesh;
1696 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1697 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1698 _mapSubMesh. erase(oldID);
1699 _mapSubMesh_i. erase(oldID);
1700 _mapSubMeshIor.erase(oldID);
1701 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1706 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1707 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1708 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1710 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1712 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1713 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1714 ds->SetShape( newShape );
1719 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1720 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1722 // Remove groups and submeshes basing on removed sub-shapes
1724 TopTools_MapOfShape newShapeMap;
1725 TopoDS_Iterator shapeIt( newShape );
1726 for ( ; shapeIt.More(); shapeIt.Next() )
1727 newShapeMap.Add( shapeIt.Value() );
1729 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1730 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1732 if ( newShapeMap.Contains( shapeIt.Value() ))
1734 TopTools_IndexedMapOfShape oldShapeMap;
1735 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1736 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1738 const TopoDS_Shape& oldShape = oldShapeMap(i);
1739 int oldInd = meshDS->ShapeToIndex( oldShape );
1741 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1742 if ( i_smIor != _mapSubMeshIor.end() ) {
1743 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1746 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1747 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1749 // check if a group bases on oldInd shape
1750 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1751 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1752 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1753 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1755 RemoveGroup( i_grp->second ); // several groups can base on same shape
1756 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1761 // Reassign hypotheses and update groups after setting the new shape to mesh
1763 // collect anassigned hypotheses
1764 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1765 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1766 TShapeHypList assignedHyps;
1767 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1769 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1770 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1771 if ( !hyps.empty() ) {
1772 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1773 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1774 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1777 // collect shapes supporting groups
1778 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1779 TShapeTypeList groupData;
1780 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1781 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1782 for ( ; grIt != groups.end(); ++grIt )
1784 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1786 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1788 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1789 _impl->ShapeToMesh( newShape );
1791 // reassign hypotheses
1792 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1793 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1795 TIndexedShape& geom = indS_hyps->first;
1796 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1797 int oldID = geom._index;
1798 int newID = meshDS->ShapeToIndex( geom._shape );
1801 if ( oldID == 1 ) { // main shape
1803 geom._shape = newShape;
1805 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1806 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1807 // care of submeshes
1808 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1809 if ( newID != oldID ) {
1810 _mapSubMesh [ newID ] = newSubmesh;
1811 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1812 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1813 _mapSubMesh. erase(oldID);
1814 _mapSubMesh_i. erase(oldID);
1815 _mapSubMeshIor.erase(oldID);
1816 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1820 TShapeTypeList::iterator geomType = groupData.begin();
1821 for ( ; geomType != groupData.end(); ++geomType )
1823 const TIndexedShape& geom = geomType->first;
1824 int oldID = geom._index;
1825 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1828 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1829 CORBA::String_var name = groupSO->GetName();
1831 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1833 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1834 group_i->changeLocalId( newID );
1837 break; // everything has been updated
1840 } // loop on group data
1844 CORBA::Long newNbEntities = NbNodes() + NbElements();
1845 list< SALOMEDS::SObject_var > soToUpdateIcons;
1846 if ( newNbEntities != nbEntities )
1848 // Add all SObjects with icons
1849 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1851 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1852 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1853 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1855 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1856 i_gr != _mapGroups.end(); ++i_gr ) // groups
1857 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1860 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1861 for ( ; so != soToUpdateIcons.end(); ++so )
1862 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1865 //=============================================================================
1867 * \brief Create standalone group instead if group on geometry
1869 //=============================================================================
1871 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1873 SMESH::SMESH_Group_var aGroup;
1874 if ( theGroup->_is_nil() )
1875 return aGroup._retn();
1877 Unexpect aCatch(SALOME_SalomeException);
1879 SMESH_GroupBase_i* aGroupToRem =
1880 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1882 return aGroup._retn();
1884 int anId = aGroupToRem->GetLocalID();
1885 if ( !_impl->ConvertToStandalone( anId ) )
1886 return aGroup._retn();
1887 removeGeomGroupData( theGroup );
1889 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1891 // remove old instance of group from own map
1892 _mapGroups.erase( anId );
1894 SALOMEDS::StudyBuilder_var builder;
1895 SALOMEDS::SObject_var aGroupSO;
1896 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1897 if ( !aStudy->_is_nil() ) {
1898 builder = aStudy->NewBuilder();
1899 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1900 if ( !aGroupSO->_is_nil() ) {
1902 // remove reference to geometry
1903 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1904 for ( ; chItr->More(); chItr->Next() )
1905 // Remove group's child SObject
1906 builder->RemoveObject( chItr->Value() );
1908 // Update Python script
1909 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1910 << aGroupSO << " )";
1914 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1915 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1916 aGroupImpl->Register();
1917 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1919 // remember new group in own map
1920 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1921 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1923 // register CORBA object for persistence
1924 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1926 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1928 return aGroup._retn();
1931 //=============================================================================
1935 //=============================================================================
1937 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1939 if(MYDEBUG) MESSAGE( "createSubMesh" );
1940 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1942 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1943 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1944 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1945 SMESH::SMESH_subMesh_var subMesh
1946 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1948 _mapSubMesh[subMeshId] = mySubMesh;
1949 _mapSubMesh_i[subMeshId] = subMeshServant;
1950 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1952 // register CORBA object for persistence
1953 int nextId = _gen_i->RegisterObject( subMesh );
1954 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1956 // to track changes of GEOM groups
1957 addGeomGroupData( theSubShapeObject, subMesh );
1959 return subMesh._retn();
1962 //=======================================================================
1963 //function : getSubMesh
1965 //=======================================================================
1967 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1969 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1970 if ( it == _mapSubMeshIor.end() )
1971 return SMESH::SMESH_subMesh::_nil();
1973 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
1977 //=============================================================================
1981 //=============================================================================
1983 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
1984 GEOM::GEOM_Object_ptr theSubShapeObject )
1986 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
1987 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
1990 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
1992 CORBA::Long shapeId = theSubMesh->GetId();
1993 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
1995 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
1998 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
1999 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2000 for ( ; hyp != hyps.end(); ++hyp )
2001 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2008 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2009 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2010 removeHypothesis( theSubShapeObject, aHypList[i] );
2013 catch( const SALOME::SALOME_Exception& ) {
2014 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2016 removeGeomGroupData( theSubShapeObject );
2018 int subMeshId = theSubMesh->GetId();
2020 _mapSubMesh.erase(subMeshId);
2021 _mapSubMesh_i.erase(subMeshId);
2022 _mapSubMeshIor.erase(subMeshId);
2023 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2026 //=============================================================================
2030 //=============================================================================
2032 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2033 const char* theName,
2034 const TopoDS_Shape& theShape )
2037 SMESH::SMESH_GroupBase_var aGroup;
2038 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2039 SMESH_GroupBase_i* aGroupImpl;
2040 if ( !theShape.IsNull() )
2041 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2043 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2045 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2046 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2047 aGroupImpl->Register();
2048 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2050 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2051 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2053 // register CORBA object for persistence
2054 int nextId = _gen_i->RegisterObject( aGroup );
2055 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2057 // to track changes of GEOM groups
2058 if ( !theShape.IsNull() ) {
2059 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2060 addGeomGroupData( geom, aGroup );
2063 return aGroup._retn();
2066 //=============================================================================
2068 * SMESH_Mesh_i::removeGroup
2070 * Should be called by ~SMESH_Group_i()
2072 //=============================================================================
2074 void SMESH_Mesh_i::removeGroup( const int theId )
2076 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2077 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2078 removeGeomGroupData( _mapGroups[theId] );
2079 _mapGroups.erase( theId );
2080 _impl->RemoveGroup( theId );
2085 //=============================================================================
2089 //=============================================================================
2091 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2092 throw(SALOME::SALOME_Exception)
2094 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2096 SMESH::log_array_var aLog;
2098 list < SMESHDS_Command * >logDS = _impl->GetLog();
2099 aLog = new SMESH::log_array;
2101 int lg = logDS.size();
2104 list < SMESHDS_Command * >::iterator its = logDS.begin();
2105 while(its != logDS.end()){
2106 SMESHDS_Command *com = *its;
2107 int comType = com->GetType();
2109 int lgcom = com->GetNumber();
2111 const list < int >&intList = com->GetIndexes();
2112 int inum = intList.size();
2114 list < int >::const_iterator ii = intList.begin();
2115 const list < double >&coordList = com->GetCoords();
2116 int rnum = coordList.size();
2118 list < double >::const_iterator ir = coordList.begin();
2119 aLog[indexLog].commandType = comType;
2120 aLog[indexLog].number = lgcom;
2121 aLog[indexLog].coords.length(rnum);
2122 aLog[indexLog].indexes.length(inum);
2123 for(int i = 0; i < rnum; i++){
2124 aLog[indexLog].coords[i] = *ir;
2125 //MESSAGE(" "<<i<<" "<<ir.Value());
2128 for(int i = 0; i < inum; i++){
2129 aLog[indexLog].indexes[i] = *ii;
2130 //MESSAGE(" "<<i<<" "<<ii.Value());
2139 catch(SALOME_Exception & S_ex){
2140 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2142 return aLog._retn();
2146 //=============================================================================
2150 //=============================================================================
2152 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2154 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2158 //=============================================================================
2162 //=============================================================================
2164 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2166 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2170 //=============================================================================
2174 //=============================================================================
2176 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2181 //=============================================================================
2185 //=============================================================================
2187 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2189 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2193 //=============================================================================
2197 //=============================================================================
2199 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2201 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2205 //=============================================================================
2207 * Return mesh editor
2209 //=============================================================================
2211 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2213 // Create MeshEditor
2214 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2215 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2217 // Update Python script
2218 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2220 return aMesh._retn();
2223 //=============================================================================
2225 * Return mesh edition previewer
2227 //=============================================================================
2229 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2231 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2232 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2233 return aMesh._retn();
2236 //=============================================================================
2240 //=============================================================================
2241 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2243 Unexpect aCatch(SALOME_SalomeException);
2244 _impl->SetAutoColor(theAutoColor);
2247 //=============================================================================
2251 //=============================================================================
2252 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2254 Unexpect aCatch(SALOME_SalomeException);
2255 return _impl->GetAutoColor();
2259 //=============================================================================
2261 * Export in different formats
2263 //=============================================================================
2265 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2267 return _impl->HasDuplicatedGroupNamesMED();
2270 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2272 TCollection_AsciiString aFullName ((char*)file);
2273 OSD_Path aPath (aFullName);
2274 OSD_File aFile (aPath);
2275 if (aFile.Exists()) {
2276 // existing filesystem node
2277 if (aFile.KindOfFile() == OSD_FILE) {
2278 if (aFile.IsWriteable()) {
2283 if (aFile.Failed()) {
2284 TCollection_AsciiString msg ("File ");
2285 msg += aFullName + " cannot be replaced.";
2286 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2289 TCollection_AsciiString msg ("File ");
2290 msg += aFullName + " cannot be overwritten.";
2291 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2294 TCollection_AsciiString msg ("Location ");
2295 msg += aFullName + " is not a file.";
2296 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2299 // nonexisting file; check if it can be created
2301 aFile.Build(OSD_WriteOnly, OSD_Protection());
2302 if (aFile.Failed()) {
2303 TCollection_AsciiString msg ("You cannot create the file ");
2304 msg += aFullName + ". Check the directory existance and access rights.";
2305 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2313 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2314 CORBA::Boolean auto_groups,
2315 SMESH::MED_VERSION theVersion,
2316 CORBA::Boolean overwrite)
2317 throw(SALOME::SALOME_Exception)
2319 Unexpect aCatch(SALOME_SalomeException);
2322 PrepareForWriting(file, overwrite);
2323 const char* aMeshName = "Mesh";
2324 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2325 if ( !aStudy->_is_nil() ) {
2326 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2327 if ( !aMeshSO->_is_nil() ) {
2328 aMeshName = aMeshSO->GetName();
2329 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2330 if ( !aStudy->GetProperties()->IsLocked() )
2332 SALOMEDS::GenericAttribute_var anAttr;
2333 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2334 SALOMEDS::AttributeExternalFileDef_var aFileName;
2335 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2336 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2337 ASSERT(!aFileName->_is_nil());
2338 aFileName->SetValue(file);
2339 SALOMEDS::AttributeFileType_var aFileType;
2340 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2341 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2342 ASSERT(!aFileType->_is_nil());
2343 aFileType->SetValue("FICHIERMED");
2347 // Update Python script
2348 // set name of mesh before export
2349 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2351 // check names of groups
2354 TPythonDump() << _this() << ".ExportToMEDX( '"
2355 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2357 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2360 void SMESH_Mesh_i::ExportToMED (const char* file,
2361 CORBA::Boolean auto_groups,
2362 SMESH::MED_VERSION theVersion)
2363 throw(SALOME::SALOME_Exception)
2365 ExportToMEDX(file,auto_groups,theVersion,true);
2368 void SMESH_Mesh_i::ExportMED (const char* file,
2369 CORBA::Boolean auto_groups)
2370 throw(SALOME::SALOME_Exception)
2372 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2375 void SMESH_Mesh_i::ExportDAT (const char *file)
2376 throw(SALOME::SALOME_Exception)
2378 Unexpect aCatch(SALOME_SalomeException);
2380 // Update Python script
2381 // check names of groups
2383 TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
2386 PrepareForWriting(file);
2387 _impl->ExportDAT(file);
2390 void SMESH_Mesh_i::ExportUNV (const char *file)
2391 throw(SALOME::SALOME_Exception)
2393 Unexpect aCatch(SALOME_SalomeException);
2395 // Update Python script
2396 // check names of groups
2398 TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
2401 PrepareForWriting(file);
2402 _impl->ExportUNV(file);
2405 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2406 throw(SALOME::SALOME_Exception)
2408 Unexpect aCatch(SALOME_SalomeException);
2410 // Update Python script
2411 // check names of groups
2413 TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
2416 PrepareForWriting(file);
2417 _impl->ExportSTL(file, isascii);
2420 //=============================================================================
2424 //=============================================================================
2426 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2428 Unexpect aCatch(SALOME_SalomeException);
2429 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2430 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2431 return aMesh._retn();
2434 //=============================================================================
2438 //=============================================================================
2439 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2441 Unexpect aCatch(SALOME_SalomeException);
2442 return _impl->NbNodes();
2445 //=============================================================================
2449 //=============================================================================
2450 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2452 Unexpect aCatch(SALOME_SalomeException);
2453 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2456 //=============================================================================
2460 //=============================================================================
2461 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2463 Unexpect aCatch(SALOME_SalomeException);
2464 return _impl->Nb0DElements();
2467 //=============================================================================
2471 //=============================================================================
2472 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2474 Unexpect aCatch(SALOME_SalomeException);
2475 return _impl->NbEdges();
2478 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2479 throw(SALOME::SALOME_Exception)
2481 Unexpect aCatch(SALOME_SalomeException);
2482 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2485 //=============================================================================
2489 //=============================================================================
2490 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2492 Unexpect aCatch(SALOME_SalomeException);
2493 return _impl->NbFaces();
2496 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2498 Unexpect aCatch(SALOME_SalomeException);
2499 return _impl->NbTriangles();
2502 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2504 Unexpect aCatch(SALOME_SalomeException);
2505 return _impl->NbQuadrangles();
2508 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2510 Unexpect aCatch(SALOME_SalomeException);
2511 return _impl->NbPolygons();
2514 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2515 throw(SALOME::SALOME_Exception)
2517 Unexpect aCatch(SALOME_SalomeException);
2518 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2521 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2522 throw(SALOME::SALOME_Exception)
2524 Unexpect aCatch(SALOME_SalomeException);
2525 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2528 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2529 throw(SALOME::SALOME_Exception)
2531 Unexpect aCatch(SALOME_SalomeException);
2532 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2535 //=============================================================================
2539 //=============================================================================
2540 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2542 Unexpect aCatch(SALOME_SalomeException);
2543 return _impl->NbVolumes();
2546 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2548 Unexpect aCatch(SALOME_SalomeException);
2549 return _impl->NbTetras();
2552 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2554 Unexpect aCatch(SALOME_SalomeException);
2555 return _impl->NbHexas();
2558 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2560 Unexpect aCatch(SALOME_SalomeException);
2561 return _impl->NbPyramids();
2564 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2566 Unexpect aCatch(SALOME_SalomeException);
2567 return _impl->NbPrisms();
2570 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2572 Unexpect aCatch(SALOME_SalomeException);
2573 return _impl->NbPolyhedrons();
2576 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2577 throw(SALOME::SALOME_Exception)
2579 Unexpect aCatch(SALOME_SalomeException);
2580 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2583 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2584 throw(SALOME::SALOME_Exception)
2586 Unexpect aCatch(SALOME_SalomeException);
2587 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2590 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2591 throw(SALOME::SALOME_Exception)
2593 Unexpect aCatch(SALOME_SalomeException);
2594 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2597 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2598 throw(SALOME::SALOME_Exception)
2600 Unexpect aCatch(SALOME_SalomeException);
2601 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2604 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2605 throw(SALOME::SALOME_Exception)
2607 Unexpect aCatch(SALOME_SalomeException);
2608 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2611 //=============================================================================
2615 //=============================================================================
2616 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2618 Unexpect aCatch(SALOME_SalomeException);
2619 return _mapSubMesh_i.size();
2622 //=============================================================================
2626 //=============================================================================
2627 char* SMESH_Mesh_i::Dump()
2631 return CORBA::string_dup( os.str().c_str() );
2634 //=============================================================================
2638 //=============================================================================
2639 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2641 // SMESH::long_array_var aResult = new SMESH::long_array();
2642 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2643 // int aMinId = aSMESHDS_Mesh->MinElementID();
2644 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2646 // aResult->length(aMaxId - aMinId + 1);
2648 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2649 // aResult[i++] = id;
2651 // return aResult._retn();
2653 return GetElementsId();
2656 //=============================================================================
2660 //=============================================================================
2662 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2663 throw (SALOME::SALOME_Exception)
2665 Unexpect aCatch(SALOME_SalomeException);
2666 MESSAGE("SMESH_Mesh_i::GetElementsId");
2667 SMESH::long_array_var aResult = new SMESH::long_array();
2668 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2670 if ( aSMESHDS_Mesh == NULL )
2671 return aResult._retn();
2673 long nbElements = NbElements();
2674 aResult->length( nbElements );
2675 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2676 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2677 aResult[i] = anIt->next()->GetID();
2679 return aResult._retn();
2683 //=============================================================================
2687 //=============================================================================
2689 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2690 throw (SALOME::SALOME_Exception)
2692 Unexpect aCatch(SALOME_SalomeException);
2693 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2694 SMESH::long_array_var aResult = new SMESH::long_array();
2695 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2697 if ( aSMESHDS_Mesh == NULL )
2698 return aResult._retn();
2700 long nbElements = NbElements();
2702 // No sense in returning ids of elements along with ids of nodes:
2703 // when theElemType == SMESH::ALL, return node ids only if
2704 // there are no elements
2705 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2706 return GetNodesId();
2708 aResult->length( nbElements );
2712 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2713 while ( i < nbElements && anIt->more() ) {
2714 const SMDS_MeshElement* anElem = anIt->next();
2715 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2716 aResult[i++] = anElem->GetID();
2719 aResult->length( i );
2721 return aResult._retn();
2724 //=============================================================================
2728 //=============================================================================
2730 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2731 throw (SALOME::SALOME_Exception)
2733 Unexpect aCatch(SALOME_SalomeException);
2734 MESSAGE("SMESH_subMesh_i::GetNodesId");
2735 SMESH::long_array_var aResult = new SMESH::long_array();
2736 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2738 if ( aSMESHDS_Mesh == NULL )
2739 return aResult._retn();
2741 long nbNodes = NbNodes();
2742 aResult->length( nbNodes );
2743 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2744 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2745 aResult[i] = anIt->next()->GetID();
2747 return aResult._retn();
2750 //=============================================================================
2754 //=============================================================================
2756 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2757 throw (SALOME::SALOME_Exception)
2759 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2762 //=============================================================================
2766 //=============================================================================
2768 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2769 throw (SALOME::SALOME_Exception)
2771 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2773 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2775 return ( SMESH::EntityType ) e->GetEntityType();
2778 //=============================================================================
2780 * Returns ID of elements for given submesh
2782 //=============================================================================
2783 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2784 throw (SALOME::SALOME_Exception)
2786 SMESH::long_array_var aResult = new SMESH::long_array();
2788 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2789 if(!SM) return aResult._retn();
2791 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2792 if(!SDSM) return aResult._retn();
2794 aResult->length(SDSM->NbElements());
2796 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2798 while ( eIt->more() ) {
2799 aResult[i++] = eIt->next()->GetID();
2802 return aResult._retn();
2806 //=============================================================================
2808 * Returns ID of nodes for given submesh
2809 * If param all==true - returns all nodes, else -
2810 * returns only nodes on shapes.
2812 //=============================================================================
2813 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2814 throw (SALOME::SALOME_Exception)
2816 SMESH::long_array_var aResult = new SMESH::long_array();
2818 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2819 if(!SM) return aResult._retn();
2821 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2822 if(!SDSM) return aResult._retn();
2825 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2826 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2827 while ( nIt->more() ) {
2828 const SMDS_MeshNode* elem = nIt->next();
2829 theElems.insert( elem->GetID() );
2832 else { // all nodes of submesh elements
2833 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2834 while ( eIt->more() ) {
2835 const SMDS_MeshElement* anElem = eIt->next();
2836 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2837 while ( nIt->more() ) {
2838 const SMDS_MeshElement* elem = nIt->next();
2839 theElems.insert( elem->GetID() );
2844 aResult->length(theElems.size());
2845 set<int>::iterator itElem;
2847 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2848 aResult[i++] = *itElem;
2850 return aResult._retn();
2854 //=============================================================================
2856 * Returns type of elements for given submesh
2858 //=============================================================================
2859 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2860 throw (SALOME::SALOME_Exception)
2862 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2863 if(!SM) return SMESH::ALL;
2865 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2866 if(!SDSM) return SMESH::ALL;
2868 if(SDSM->NbElements()==0)
2869 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2871 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2872 const SMDS_MeshElement* anElem = eIt->next();
2873 return ( SMESH::ElementType ) anElem->GetType();
2877 //=============================================================================
2881 //=============================================================================
2883 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2885 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2887 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2892 //=============================================================================
2894 * Get XYZ coordinates of node as list of double
2895 * If there is not node for given ID - returns empty list
2897 //=============================================================================
2899 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2901 SMESH::double_array_var aResult = new SMESH::double_array();
2902 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2903 if ( aSMESHDS_Mesh == NULL )
2904 return aResult._retn();
2907 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2909 return aResult._retn();
2913 aResult[0] = aNode->X();
2914 aResult[1] = aNode->Y();
2915 aResult[2] = aNode->Z();
2916 return aResult._retn();
2920 //=============================================================================
2922 * For given node returns list of IDs of inverse elements
2923 * If there is not node for given ID - returns empty list
2925 //=============================================================================
2927 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2929 SMESH::long_array_var aResult = new SMESH::long_array();
2930 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2931 if ( aSMESHDS_Mesh == NULL )
2932 return aResult._retn();
2935 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2937 return aResult._retn();
2939 // find inverse elements
2940 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2941 TColStd_SequenceOfInteger IDs;
2942 while(eIt->more()) {
2943 const SMDS_MeshElement* elem = eIt->next();
2944 IDs.Append(elem->GetID());
2946 if(IDs.Length()>0) {
2947 aResult->length(IDs.Length());
2949 for(; i<=IDs.Length(); i++) {
2950 aResult[i-1] = IDs.Value(i);
2953 return aResult._retn();
2956 //=============================================================================
2958 * \brief Return position of a node on shape
2960 //=============================================================================
2962 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
2964 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
2965 aNodePosition->shapeID = 0;
2966 aNodePosition->shapeType = GEOM::SHAPE;
2968 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
2969 if ( !mesh ) return aNodePosition;
2971 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
2973 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
2975 aNodePosition->shapeID = pos->GetShapeId();
2976 switch ( pos->GetTypeOfPosition() ) {
2978 aNodePosition->shapeType = GEOM::EDGE;
2979 aNodePosition->params.length(1);
2980 aNodePosition->params[0] =
2981 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
2984 aNodePosition->shapeType = GEOM::FACE;
2985 aNodePosition->params.length(2);
2986 aNodePosition->params[0] =
2987 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
2988 aNodePosition->params[1] =
2989 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
2991 case SMDS_TOP_VERTEX:
2992 aNodePosition->shapeType = GEOM::VERTEX;
2994 case SMDS_TOP_3DSPACE:
2995 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
2996 aNodePosition->shapeType = GEOM::SOLID;
2997 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
2998 aNodePosition->shapeType = GEOM::SHELL;
3004 return aNodePosition;
3007 //=============================================================================
3009 * If given element is node returns IDs of shape from position
3010 * If there is not node for given ID - returns -1
3012 //=============================================================================
3014 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3016 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3017 if ( aSMESHDS_Mesh == NULL )
3021 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3023 SMDS_PositionPtr pos = aNode->GetPosition();
3027 return pos->GetShapeId();
3034 //=============================================================================
3036 * For given element returns ID of result shape after
3037 * ::FindShape() from SMESH_MeshEditor
3038 * If there is not element for given ID - returns -1
3040 //=============================================================================
3042 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3044 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3045 if ( aSMESHDS_Mesh == NULL )
3048 // try to find element
3049 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3053 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3054 ::SMESH_MeshEditor aMeshEditor(_impl);
3055 int index = aMeshEditor.FindShape( elem );
3063 //=============================================================================
3065 * Returns number of nodes for given element
3066 * If there is not element for given ID - returns -1
3068 //=============================================================================
3070 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3072 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3073 if ( aSMESHDS_Mesh == NULL ) return -1;
3074 // try to find element
3075 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3076 if(!elem) return -1;
3077 return elem->NbNodes();
3081 //=============================================================================
3083 * Returns ID of node by given index for given element
3084 * If there is not element for given ID - returns -1
3085 * If there is not node for given index - returns -2
3087 //=============================================================================
3089 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3091 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3092 if ( aSMESHDS_Mesh == NULL ) return -1;
3093 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3094 if(!elem) return -1;
3095 if( index>=elem->NbNodes() || index<0 ) return -1;
3096 return elem->GetNode(index)->GetID();
3099 //=============================================================================
3101 * Returns IDs of nodes of given element
3103 //=============================================================================
3105 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3107 SMESH::long_array_var aResult = new SMESH::long_array();
3108 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3110 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3112 aResult->length( elem->NbNodes() );
3113 for ( int i = 0; i < elem->NbNodes(); ++i )
3114 aResult[ i ] = elem->GetNode( i )->GetID();
3117 return aResult._retn();
3120 //=============================================================================
3122 * Returns true if given node is medium node
3123 * in given quadratic element
3125 //=============================================================================
3127 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3129 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3130 if ( aSMESHDS_Mesh == NULL ) return false;
3132 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3133 if(!aNode) return false;
3134 // try to find element
3135 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3136 if(!elem) return false;
3138 return elem->IsMediumNode(aNode);
3142 //=============================================================================
3144 * Returns true if given node is medium node
3145 * in one of quadratic elements
3147 //=============================================================================
3149 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3150 SMESH::ElementType theElemType)
3152 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3153 if ( aSMESHDS_Mesh == NULL ) return false;
3156 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3157 if(!aNode) return false;
3159 SMESH_MesherHelper aHelper( *(_impl) );
3161 SMDSAbs_ElementType aType;
3162 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3163 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3164 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3165 else aType = SMDSAbs_All;
3167 return aHelper.IsMedium(aNode,aType);
3171 //=============================================================================
3173 * Returns number of edges for given element
3175 //=============================================================================
3177 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3179 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3180 if ( aSMESHDS_Mesh == NULL ) return -1;
3181 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3182 if(!elem) return -1;
3183 return elem->NbEdges();
3187 //=============================================================================
3189 * Returns number of faces for given element
3191 //=============================================================================
3193 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3195 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3196 if ( aSMESHDS_Mesh == NULL ) return -1;
3197 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3198 if(!elem) return -1;
3199 return elem->NbFaces();
3202 //=======================================================================
3203 //function : GetElemFaceNodes
3204 //purpose : Returns nodes of given face (counted from zero) for given element.
3205 //=======================================================================
3207 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3208 CORBA::Short faceIndex)
3210 SMESH::long_array_var aResult = new SMESH::long_array();
3211 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3213 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3215 SMDS_VolumeTool vtool( elem );
3216 if ( faceIndex < vtool.NbFaces() )
3218 aResult->length( vtool.NbFaceNodes( faceIndex ));
3219 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3220 for ( int i = 0; i < aResult->length(); ++i )
3221 aResult[ i ] = nn[ i ]->GetID();
3225 return aResult._retn();
3228 //=======================================================================
3229 //function : FindElementByNodes
3230 //purpose : Returns an element based on all given nodes.
3231 //=======================================================================
3233 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3235 CORBA::Long elemID(0);
3236 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3238 vector< const SMDS_MeshNode * > nn( nodes.length() );
3239 for ( int i = 0; i < nodes.length(); ++i )
3240 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3243 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3244 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3245 _impl->NbFaces( ORDER_QUADRATIC ) ||
3246 _impl->NbVolumes( ORDER_QUADRATIC )))
3247 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3249 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3254 //=============================================================================
3256 * Returns true if given element is polygon
3258 //=============================================================================
3260 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3262 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3263 if ( aSMESHDS_Mesh == NULL ) return false;
3264 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3265 if(!elem) return false;
3266 return elem->IsPoly();
3270 //=============================================================================
3272 * Returns true if given element is quadratic
3274 //=============================================================================
3276 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3278 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3279 if ( aSMESHDS_Mesh == NULL ) return false;
3280 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3281 if(!elem) return false;
3282 return elem->IsQuadratic();
3286 //=============================================================================
3288 * Returns bary center for given element
3290 //=============================================================================
3292 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3294 SMESH::double_array_var aResult = new SMESH::double_array();
3295 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3296 if ( aSMESHDS_Mesh == NULL )
3297 return aResult._retn();
3299 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3301 return aResult._retn();
3303 if(elem->GetType()==SMDSAbs_Volume) {
3304 SMDS_VolumeTool aTool;
3305 if(aTool.Set(elem)) {
3307 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3312 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3314 double x=0., y=0., z=0.;
3315 for(; anIt->more(); ) {
3317 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3331 return aResult._retn();
3335 //=============================================================================
3337 * Create and publish group servants if any groups were imported or created anyhow
3339 //=============================================================================
3341 void SMESH_Mesh_i::CreateGroupServants()
3343 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3345 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3346 while ( groupIt->more() )
3348 ::SMESH_Group* group = groupIt->next();
3349 int anId = group->GetGroupDS()->GetID();
3351 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3352 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3355 SMESH_GroupBase_i* aGroupImpl;
3357 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3358 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3360 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3361 shape = groupOnGeom->GetShape();
3364 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3367 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3368 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3369 aGroupImpl->Register();
3371 SMESH::SMESH_GroupBase_var groupVar =
3372 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3373 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3375 // register CORBA object for persistence
3376 int nextId = _gen_i->RegisterObject( groupVar );
3377 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3379 // publishing of the groups in the study
3380 if ( !aStudy->_is_nil() ) {
3381 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3382 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3387 //=============================================================================
3389 * \brief Return groups cantained in _mapGroups by their IDs
3391 //=============================================================================
3393 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3395 int nbGroups = groupIDs.size();
3396 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3397 aList->length( nbGroups );
3399 list<int>::const_iterator ids = groupIDs.begin();
3400 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3402 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3403 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3404 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3406 aList->length( nbGroups );
3407 return aList._retn();
3410 //=============================================================================
3412 * \brief Return information about imported file
3414 //=============================================================================
3416 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3418 SALOME_MED::MedFileInfo_var res( myFileInfo );
3419 if ( !res.operator->() ) {
3420 res = new SALOME_MED::MedFileInfo;
3422 res->fileSize = res->major = res->minor = res->release = -1;
3427 //=============================================================================
3429 * \brief Check and correct names of mesh groups
3431 //=============================================================================
3433 void SMESH_Mesh_i::checkGroupNames()
3435 int nbGrp = NbGroups();
3439 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3440 if ( aStudy->_is_nil() )
3441 return; // nothing to do
3443 SMESH::ListOfGroups* grpList = 0;
3444 // avoid dump of "GetGroups"
3446 // store python dump into a local variable inside local scope
3447 SMESH::TPythonDump pDump; // do not delete this line of code
3448 grpList = GetGroups();
3451 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3452 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3455 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3456 if ( aGrpSO->_is_nil() )
3458 // correct name of the mesh group if necessary
3459 const char* guiName = aGrpSO->GetName();
3460 if ( strcmp(guiName, aGrp->GetName()) )
3461 aGrp->SetName( guiName );
3465 //=============================================================================
3467 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3469 //=============================================================================
3470 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3472 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3473 CORBA::string_dup(theParameters));
3476 //=============================================================================
3478 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3480 //=============================================================================
3481 char* SMESH_Mesh_i::GetParameters()
3483 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3484 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3487 //=============================================================================
3489 * \brief Returns list of notebook variables used for last Mesh operation
3491 //=============================================================================
3492 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3494 SMESH::string_array_var aResult = new SMESH::string_array();
3495 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3497 char *aParameters = GetParameters();
3498 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3499 if(!aStudy->_is_nil()) {
3500 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3501 if(aSections->length() > 0) {
3502 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3503 aResult->length(aVars.length());
3504 for(int i = 0;i < aVars.length();i++)
3505 aResult[i] = CORBA::string_dup( aVars[i]);
3509 return aResult._retn();
3512 //=============================================================================
3514 * \brief Returns statistic of mesh elements
3516 //=============================================================================
3517 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3519 SMESH::long_array_var aRes = new SMESH::long_array();
3520 aRes->length(SMESH::Entity_Last);
3521 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3523 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3525 return aRes._retn();
3526 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3527 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3528 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3529 return aRes._retn();
3532 //=============================================================================
3534 * \brief Collect statistic of mesh elements given by iterator
3536 //=============================================================================
3537 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3538 SMESH::long_array& theInfo)
3540 if (!theItr) return;
3541 while (theItr->more())
3542 theInfo[ theItr->next()->GetEntityType() ]++;
3545 //=============================================================================
3547 * \brief mapping of mesh dimension into shape type
3549 //=============================================================================
3550 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3552 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3554 case 0: aType = TopAbs_VERTEX; break;
3555 case 1: aType = TopAbs_EDGE; break;
3556 case 2: aType = TopAbs_FACE; break;
3558 default:aType = TopAbs_SOLID; break;
3563 //=============================================================================
3565 * \brief Internal structure used to find concurent submeshes
3567 * It represents a pair < submesh, concurent dimension >, where
3568 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3569 * with another submesh. In other words, it is dimension of a hypothesis assigned
3572 //=============================================================================
3578 int _dim; //!< a dimension the algo can build (concurrent dimension)
3579 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3580 TopTools_MapOfShape _shapeMap;
3581 SMESH_subMesh* _subMesh;
3582 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3585 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3587 const TopoDS_Shape& theShape)
3589 _subMesh = (SMESH_subMesh*)theSubMesh;
3590 SetShape( theDim, theShape );
3594 void SetShape(const int theDim,
3595 const TopoDS_Shape& theShape)
3598 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3599 if (_dim >= _ownDim)
3600 _shapeMap.Add( theShape );
3602 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3603 for( ; anExp.More(); anExp.Next() )
3604 _shapeMap.Add( anExp.Current() );
3608 //! Check sharing of sub shapes
3609 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3610 const TopTools_MapOfShape& theToFind,
3611 const TopAbs_ShapeEnum theType)
3613 bool isShared = false;
3614 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3615 for (; !isShared && anItr.More(); anItr.Next() ) {
3616 const TopoDS_Shape aSubSh = anItr.Key();
3617 // check for case when concurrent dimensions are same
3618 isShared = theToFind.Contains( aSubSh );
3619 // check for subshape with concurrent dimension
3620 TopExp_Explorer anExp( aSubSh, theType );
3621 for ( ; !isShared && anExp.More(); anExp.Next() )
3622 isShared = theToFind.Contains( anExp.Current() );
3627 //! check algorithms
3628 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3629 const SMESHDS_Hypothesis* theA2)
3631 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3632 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3633 return false; // one of the hypothesis is not algorithm
3634 // check algorithm names (should be equal)
3635 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3639 //! Check if subshape hypotheses are concurrent
3640 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3642 if ( _subMesh == theOther->_subMesh )
3643 return false; // same subshape - should not be
3645 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3646 // any of the two submeshes is not on COMPOUND shape )
3647 // -> no concurrency
3648 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3649 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3650 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3653 // bool checkSubShape = ( _dim >= theOther->_dim )
3654 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3655 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3656 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3657 if ( !checkSubShape )
3660 // check algorithms to be same
3661 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3662 return true; // different algorithms
3664 // check hypothesises for concurrence (skip first as algorithm)
3666 // pointers should be same, becase it is referenes from mesh hypothesis partition
3667 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3668 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3669 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3670 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3672 // the submeshes are concurrent if their algorithms has different parameters
3673 return nbSame != theOther->_hypothesises.size() - 1;
3676 }; // end of SMESH_DimHyp
3678 typedef list<SMESH_DimHyp*> TDimHypList;
3680 static void addDimHypInstance(const int theDim,
3681 const TopoDS_Shape& theShape,
3682 const SMESH_Algo* theAlgo,
3683 const SMESH_subMesh* theSubMesh,
3684 const list <const SMESHDS_Hypothesis*>& theHypList,
3685 TDimHypList* theDimHypListArr )
3687 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3688 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3689 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3690 listOfdimHyp.push_back( dimHyp );
3693 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3694 dimHyp->_hypothesises.push_front(theAlgo);
3695 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3696 for( ; hypIt != theHypList.end(); hypIt++ )
3697 dimHyp->_hypothesises.push_back( *hypIt );
3700 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3701 const TDimHypList& theListOfDimHyp,
3702 TListOfInt& theListOfConcurr )
3704 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3705 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3706 const SMESH_DimHyp* curDimHyp = *rIt;
3707 if ( curDimHyp == theDimHyp )
3708 break; // meet own dimHyp pointer in same dimension
3709 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3710 if ( find( theListOfConcurr.begin(),
3711 theListOfConcurr.end(),
3712 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3713 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3717 static void unionLists(TListOfInt& theListOfId,
3718 TListOfListOfInt& theListOfListOfId,
3721 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3722 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3724 continue; //skip already treated lists
3725 // check if other list has any same submesh object
3726 TListOfInt& otherListOfId = *it;
3727 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3728 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3731 // union two lists (from source into target)
3732 TListOfInt::iterator it2 = otherListOfId.begin();
3733 for ( ; it2 != otherListOfId.end(); it2++ ) {
3734 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3735 theListOfId.push_back(*it2);
3737 // clear source list
3738 otherListOfId.clear();
3742 //! free memory allocated for dimension-hypothesis objects
3743 static void removeDimHyps( TDimHypList* theArrOfList )
3745 for (int i = 0; i < 4; i++ ) {
3746 TDimHypList& listOfdimHyp = theArrOfList[i];
3747 TDimHypList::const_iterator it = listOfdimHyp.begin();
3748 for ( ; it != listOfdimHyp.end(); it++ )
3753 //=============================================================================
3755 * \brief Return submesh objects list in meshing order
3757 //=============================================================================
3759 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3761 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3763 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3765 return aResult._retn();
3767 ::SMESH_Mesh& mesh = GetImpl();
3768 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3769 if ( !anOrder.size() ) {
3771 // collect submeshes detecting concurrent algorithms and hypothesises
3772 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3774 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3775 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3776 ::SMESH_subMesh* sm = (*i_sm).second;
3778 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3780 // list of assigned hypothesises
3781 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3782 // Find out dimensions where the submesh can be concurrent.
3783 // We define the dimensions by algo of each of hypotheses in hypList
3784 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3785 for( ; hypIt != hypList.end(); hypIt++ ) {
3786 SMESH_Algo* anAlgo = 0;
3787 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3788 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3789 // hyp it-self is algo
3790 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3792 // try to find algorithm with help of subshapes
3793 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3794 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3795 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3798 continue; // no assigned algorithm to current submesh
3800 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3801 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3803 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3804 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3805 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3807 } // end iterations on submesh
3809 // iterate on created dimension-hypotheses and check for concurrents
3810 for ( int i = 0; i < 4; i++ ) {
3811 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3812 // check for concurrents in own and other dimensions (step-by-step)
3813 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3814 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3815 const SMESH_DimHyp* dimHyp = *dhIt;
3816 TListOfInt listOfConcurr;
3817 // looking for concurrents and collect into own list
3818 for ( int j = i; j < 4; j++ )
3819 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3820 // check if any concurrents found
3821 if ( listOfConcurr.size() > 0 ) {
3822 // add own submesh to list of concurrent
3823 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3824 anOrder.push_back( listOfConcurr );
3829 removeDimHyps(dimHypListArr);
3831 // now, minimise the number of concurrent groups
3832 // Here we assume that lists of submhes can has same submesh
3833 // in case of multi-dimension algorithms, as result
3834 // list with common submesh have to be union into one list
3836 TListOfListOfInt::iterator listIt = anOrder.begin();
3837 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3838 unionLists( *listIt, anOrder, listIndx + 1 );
3840 // convert submesh ids into interface instances
3841 // and dump command into python
3842 convertMeshOrder( anOrder, aResult, true );
3844 return aResult._retn();
3847 //=============================================================================
3849 * \brief find common submeshes with given submesh
3850 * \param theSubMeshList list of already collected submesh to check
3851 * \param theSubMesh given submesh to intersect with other
3852 * \param theCommonSubMeshes collected common submeshes
3854 //=============================================================================
3856 static void findCommonSubMesh
3857 (list<const SMESH_subMesh*>& theSubMeshList,
3858 const SMESH_subMesh* theSubMesh,
3859 set<const SMESH_subMesh*>& theCommon )
3863 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
3864 for ( ; it != theSubMeshList.end(); it++ )
3865 theSubMesh->FindIntersection( *it, theCommon );
3866 theSubMeshList.push_back( theSubMesh );
3867 //theCommon.insert( theSubMesh );
3870 //=============================================================================
3872 * \brief Set submesh object order
3873 * \param theSubMeshArray submesh array order
3875 //=============================================================================
3877 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
3880 ::SMESH_Mesh& mesh = GetImpl();
3882 TPythonDump aPythonDump; // prevent dump of called methods
3883 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
3885 TListOfListOfInt subMeshOrder;
3886 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
3888 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
3889 TListOfInt subMeshIds;
3890 aPythonDump << "[ ";
3891 // Collect subMeshes which should be clear
3892 // do it list-by-list, because modification of submesh order
3893 // take effect between concurrent submeshes only
3894 set<const SMESH_subMesh*> subMeshToClear;
3895 list<const SMESH_subMesh*> subMeshList;
3896 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
3898 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
3900 aPythonDump << ", ";
3901 aPythonDump << subMesh;
3902 subMeshIds.push_back( subMesh->GetId() );
3903 // detect common parts of submeshes
3904 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
3905 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
3907 aPythonDump << " ]";
3908 subMeshOrder.push_back( subMeshIds );
3910 // clear collected submeshes
3911 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
3912 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
3913 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
3915 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
3916 // ClearSubMesh( *clrIt );
3919 aPythonDump << " ])";
3921 mesh.SetMeshOrder( subMeshOrder );
3927 //=============================================================================
3929 * \brief Convert submesh ids into submesh interfaces
3931 //=============================================================================
3933 void SMESH_Mesh_i::convertMeshOrder
3934 (const TListOfListOfInt& theIdsOrder,
3935 SMESH::submesh_array_array& theResOrder,
3936 const bool theIsDump)
3938 int nbSet = theIdsOrder.size();
3939 TPythonDump aPythonDump; // prevent dump of called methods
3941 aPythonDump << "[ ";
3942 theResOrder.length(nbSet);
3943 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
3945 for( ; it != theIdsOrder.end(); it++ ) {
3946 // translate submesh identificators into submesh objects
3947 // takeing into account real number of concurrent lists
3948 const TListOfInt& aSubOrder = (*it);
3949 if (!aSubOrder.size())
3952 aPythonDump << "[ ";
3953 // convert shape indeces into interfaces
3954 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
3955 aResSubSet->length(aSubOrder.size());
3956 TListOfInt::const_iterator subIt = aSubOrder.begin();
3957 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
3958 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
3960 SMESH::SMESH_subMesh_var subMesh =
3961 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
3964 aPythonDump << ", ";
3965 aPythonDump << subMesh;
3967 aResSubSet[ j++ ] = subMesh;
3970 aPythonDump << " ]";
3971 theResOrder[ listIndx++ ] = aResSubSet;
3973 // correct number of lists
3974 theResOrder.length( listIndx );
3977 // finilise python dump
3978 aPythonDump << " ]";
3979 aPythonDump << " = " << _this() << ".GetMeshOrder()";