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
22 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
23 // File : SMESH_Mesh_i.cxx
24 // Author : Paul RASCLE, EDF
27 #include "SMESH_Mesh_i.hxx"
29 #include "SMESH_Filter_i.hxx"
30 #include "SMESH_Gen_i.hxx"
31 #include "SMESH_Group_i.hxx"
32 #include "SMESH_MEDMesh_i.hxx"
33 #include "SMESH_MeshEditor_i.hxx"
34 #include "SMESH_PythonDump.hxx"
35 #include "SMESH_subMesh_i.hxx"
37 #include "DriverMED_R_SMESHDS_Mesh.h"
38 #include "DriverMED_W_SMESHDS_Mesh.h"
39 #include "SMDS_VolumeTool.hxx"
40 #include "SMDS_ElemIterator.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_GroupOnGeom.hxx"
44 #include "SMESH_Group.hxx"
45 #include "SMESH_MeshEditor.hxx"
46 #include "SMESH_MesherHelper.hxx"
47 #include "SMDS_EdgePosition.hxx"
48 #include "SMDS_FacePosition.hxx"
51 #include "SALOME_NamingService.hxx"
52 #include "Utils_CorbaException.hxx"
53 #include "Utils_ExceptHandlers.hxx"
54 #include "Utils_SINGLETON.hxx"
55 #include "utilities.h"
56 #include "GEOMImpl_Types.hxx"
59 #include <BRep_Builder.hxx>
60 #include <OSD_Directory.hxx>
61 #include <OSD_File.hxx>
62 #include <OSD_Path.hxx>
63 #include <OSD_Protection.hxx>
64 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
65 #include <TColStd_MapOfInteger.hxx>
66 #include <TColStd_SequenceOfInteger.hxx>
67 #include <TCollection_AsciiString.hxx>
69 #include <TopExp_Explorer.hxx>
70 #include <TopoDS_Compound.hxx>
71 #include <TopTools_MapOfShape.hxx>
72 #include <TopTools_MapIteratorOfMapOfShape.hxx>
82 static int MYDEBUG = 0;
84 static int MYDEBUG = 0;
88 using SMESH::TPythonDump;
90 int SMESH_Mesh_i::myIdGenerator = 0;
92 //To disable automatic genericobj management, the following line should be commented.
93 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
94 #define WITHGENERICOBJ
96 //=============================================================================
100 //=============================================================================
102 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
104 CORBA::Long studyId )
105 : SALOME::GenericObj_i( thePOA )
107 MESSAGE("SMESH_Mesh_i");
110 _id = myIdGenerator++;
114 //=============================================================================
118 //=============================================================================
120 SMESH_Mesh_i::~SMESH_Mesh_i()
122 INFOS("~SMESH_Mesh_i");
124 #ifdef WITHGENERICOBJ
126 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
127 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
128 if ( CORBA::is_nil( itGr->second ))
130 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
132 // this method is called from destructor of group (PAL6331)
133 //_impl->RemoveGroup( aGroup->GetLocalID() );
134 aGroup->myMeshServant = 0;
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
143 if ( CORBA::is_nil( itSM->second ))
145 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
150 _mapSubMeshIor.clear();
152 // destroy hypotheses
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( CORBA::is_nil( itH->second ))
157 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
168 //=============================================================================
172 * Associates <this> mesh with <theShape> and puts a reference
173 * to <theShape> into the current study;
174 * the previous shape is substituted by the new one.
176 //=============================================================================
178 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
179 throw (SALOME::SALOME_Exception)
181 Unexpect aCatch(SALOME_SalomeException);
183 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
185 catch(SALOME_Exception & S_ex) {
186 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
188 // to track changes of GEOM groups
189 addGeomGroupData( theShapeObject, _this() );
192 //================================================================================
194 * \brief return true if mesh has a shape to build a shape on
196 //================================================================================
198 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
199 throw (SALOME::SALOME_Exception)
201 Unexpect aCatch(SALOME_SalomeException);
204 res = _impl->HasShapeToMesh();
206 catch(SALOME_Exception & S_ex) {
207 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
212 //=======================================================================
213 //function : GetShapeToMesh
215 //=======================================================================
217 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
218 throw (SALOME::SALOME_Exception)
220 Unexpect aCatch(SALOME_SalomeException);
221 GEOM::GEOM_Object_var aShapeObj;
223 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
225 aShapeObj = _gen_i->ShapeToGeomObject( S );
227 catch(SALOME_Exception & S_ex) {
228 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
230 return aShapeObj._retn();
233 //================================================================================
235 * \brief Remove all nodes and elements
237 //================================================================================
239 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
241 Unexpect aCatch(SALOME_SalomeException);
244 CheckGeomGroupModif(); // issue 20145
246 catch(SALOME_Exception & S_ex) {
247 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
249 TPythonDump() << _this() << ".Clear()";
252 //================================================================================
254 * \brief Remove all nodes and elements for indicated shape
256 //================================================================================
258 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
259 throw (SALOME::SALOME_Exception)
261 Unexpect aCatch(SALOME_SalomeException);
263 _impl->ClearSubMesh( ShapeID );
265 catch(SALOME_Exception & S_ex) {
266 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
270 //=============================================================================
274 //=============================================================================
276 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
278 SMESH::DriverMED_ReadStatus res;
281 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
282 res = SMESH::DRS_OK; break;
283 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
284 res = SMESH::DRS_EMPTY; break;
285 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
286 res = SMESH::DRS_WARN_RENUMBER; break;
287 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
288 res = SMESH::DRS_WARN_SKIP_ELEM; break;
289 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
291 res = SMESH::DRS_FAIL; break;
296 //=============================================================================
300 * Imports mesh data from MED file
302 //=============================================================================
304 SMESH::DriverMED_ReadStatus
305 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
306 throw ( SALOME::SALOME_Exception )
308 Unexpect aCatch(SALOME_SalomeException);
311 status = _impl->MEDToMesh( theFileName, theMeshName );
313 catch( SALOME_Exception& S_ex ) {
314 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
317 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
320 CreateGroupServants();
322 int major, minor, release;
323 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
324 major = minor = release = -1;
325 myFileInfo = new SALOME_MED::MedFileInfo();
326 myFileInfo->fileName = theFileName;
327 myFileInfo->fileSize = 0;
330 if ( ::_stati64( theFileName, &d ) != -1 )
333 if ( ::stat64( theFileName, &d ) != -1 )
335 myFileInfo->fileSize = d.st_size;
336 myFileInfo->major = major;
337 myFileInfo->minor = minor;
338 myFileInfo->release = release;
340 return ConvertDriverMEDReadStatus(status);
343 //================================================================================
345 * \brief Return string representation of a MED file version comprising nbDigits
347 //================================================================================
349 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
351 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
353 return CORBA::string_dup( ver.c_str() );
356 //=============================================================================
360 * Imports mesh data from MED file
362 //=============================================================================
364 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
365 throw ( SALOME::SALOME_Exception )
367 // Read mesh with name = <theMeshName> into SMESH_Mesh
368 _impl->UNVToMesh( theFileName );
370 CreateGroupServants();
375 //=============================================================================
379 * Imports mesh data from STL file
381 //=============================================================================
382 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
383 throw ( SALOME::SALOME_Exception )
385 // Read mesh with name = <theMeshName> into SMESH_Mesh
386 _impl->STLToMesh( theFileName );
391 //=============================================================================
395 * Imports mesh data from MED file
397 //=============================================================================
399 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
401 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
402 // int status = _impl->MEDToMesh( theFileName, theMeshName );
403 // CreateGroupServants();
408 //=============================================================================
412 //=============================================================================
414 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
416 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
417 (SMESH_Hypothesis::Hypothesis_Status theStatus)
420 RETURNCASE( HYP_OK );
421 RETURNCASE( HYP_MISSING );
422 RETURNCASE( HYP_CONCURENT );
423 RETURNCASE( HYP_BAD_PARAMETER );
424 RETURNCASE( HYP_HIDDEN_ALGO );
425 RETURNCASE( HYP_HIDING_ALGO );
426 RETURNCASE( HYP_UNKNOWN_FATAL );
427 RETURNCASE( HYP_INCOMPATIBLE );
428 RETURNCASE( HYP_NOTCONFORM );
429 RETURNCASE( HYP_ALREADY_EXIST );
430 RETURNCASE( HYP_BAD_DIM );
431 RETURNCASE( HYP_BAD_SUBSHAPE );
432 RETURNCASE( HYP_BAD_GEOMETRY );
433 RETURNCASE( HYP_NEED_SHAPE );
436 return SMESH::HYP_UNKNOWN_FATAL;
439 //=============================================================================
443 * calls internal addHypothesis() and then adds a reference to <anHyp> under
444 * the SObject actually having a reference to <aSubShape>.
445 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
447 //=============================================================================
449 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
450 SMESH::SMESH_Hypothesis_ptr anHyp)
451 throw(SALOME::SALOME_Exception)
453 Unexpect aCatch(SALOME_SalomeException);
454 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
456 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
457 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
458 aSubShapeObject, anHyp );
460 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
462 // Update Python script
463 if(_impl->HasShapeToMesh()) {
464 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
465 << aSubShapeObject << ", " << anHyp << " )";
468 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
471 return ConvertHypothesisStatus(status);
474 //=============================================================================
478 //=============================================================================
480 SMESH_Hypothesis::Hypothesis_Status
481 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
482 SMESH::SMESH_Hypothesis_ptr anHyp)
484 if(MYDEBUG) MESSAGE("addHypothesis");
486 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
487 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
490 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
491 if (CORBA::is_nil(myHyp))
492 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
495 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
498 TopoDS_Shape myLocSubShape;
499 //use PseudoShape in case if mesh has no shape
501 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
503 myLocSubShape = _impl->GetShapeToMesh();
505 int hypId = myHyp->GetId();
506 status = _impl->AddHypothesis(myLocSubShape, hypId);
507 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
508 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
509 #ifdef WITHGENERICOBJ
510 _mapHypo[hypId]->Register();
512 // assure there is a corresponding submesh
513 if ( !_impl->IsMainShape( myLocSubShape )) {
514 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
515 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
516 createSubMesh( aSubShapeObject );
520 catch(SALOME_Exception & S_ex)
522 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
527 //=============================================================================
531 //=============================================================================
533 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
534 SMESH::SMESH_Hypothesis_ptr anHyp)
535 throw(SALOME::SALOME_Exception)
537 Unexpect aCatch(SALOME_SalomeException);
538 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
540 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
541 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
542 aSubShapeObject, anHyp );
544 // Update Python script
545 // Update Python script
546 if(_impl->HasShapeToMesh()) {
547 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
548 << aSubShapeObject << ", " << anHyp << " )";
551 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
555 return ConvertHypothesisStatus(status);
558 //=============================================================================
562 //=============================================================================
564 SMESH_Hypothesis::Hypothesis_Status
565 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
566 SMESH::SMESH_Hypothesis_ptr anHyp)
568 if(MYDEBUG) MESSAGE("removeHypothesis()");
569 // **** proposer liste de subShape (selection multiple)
571 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
572 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
574 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
575 if (CORBA::is_nil(myHyp))
576 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
578 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
581 TopoDS_Shape myLocSubShape;
582 //use PseudoShape in case if mesh has no shape
584 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
586 myLocSubShape = _impl->GetShapeToMesh();
588 int hypId = myHyp->GetId();
589 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
590 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
591 // _mapHypo.erase( hypId );
593 catch(SALOME_Exception & S_ex)
595 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
600 //=============================================================================
604 //=============================================================================
606 SMESH::ListOfHypothesis *
607 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
608 throw(SALOME::SALOME_Exception)
610 Unexpect aCatch(SALOME_SalomeException);
611 if (MYDEBUG) MESSAGE("GetHypothesisList");
612 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
613 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
615 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
618 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
619 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
620 myLocSubShape = _impl->GetShapeToMesh();
621 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
622 int i = 0, n = aLocalList.size();
625 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
626 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
627 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
628 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
633 catch(SALOME_Exception & S_ex) {
634 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
637 return aList._retn();
640 //=============================================================================
644 //=============================================================================
645 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
646 const char* theName )
647 throw(SALOME::SALOME_Exception)
649 Unexpect aCatch(SALOME_SalomeException);
650 MESSAGE("SMESH_Mesh_i::GetSubMesh");
651 if (CORBA::is_nil(aSubShapeObject))
652 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
655 SMESH::SMESH_subMesh_var subMesh;
656 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
658 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
660 //Get or Create the SMESH_subMesh object implementation
662 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
663 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
664 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
666 subMesh = getSubMesh( subMeshId );
668 // create a new subMesh object servant if there is none for the shape
669 if ( subMesh->_is_nil() )
670 subMesh = createSubMesh( aSubShapeObject );
671 if ( _gen_i->CanPublishInStudy( subMesh )) {
672 SALOMEDS::SObject_var aSO =
673 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
674 subMesh, aSubShapeObject, theName );
675 if ( !aSO->_is_nil()) {
676 // Update Python script
677 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
678 << aSubShapeObject << ", '" << theName << "' )";
682 catch(SALOME_Exception & S_ex) {
683 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
685 return subMesh._retn();
688 //=============================================================================
692 //=============================================================================
694 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
695 throw (SALOME::SALOME_Exception)
697 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
698 if ( theSubMesh->_is_nil() )
701 GEOM::GEOM_Object_var aSubShapeObject;
702 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
703 if ( !aStudy->_is_nil() ) {
704 // Remove submesh's SObject
705 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
706 if ( !anSO->_is_nil() ) {
707 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
708 SALOMEDS::SObject_var anObj, aRef;
709 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
710 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
712 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
713 // aSubShapeObject = theSubMesh->GetSubShape();
715 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
717 // Update Python script
718 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
722 removeSubMesh( theSubMesh, aSubShapeObject.in() );
725 //=============================================================================
729 //=============================================================================
730 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
731 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
733 switch (theElemType) {
738 CASE2STRING( VOLUME );
739 CASE2STRING( ELEM0D );
745 //=============================================================================
749 //=============================================================================
751 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
752 const char* theName )
753 throw(SALOME::SALOME_Exception)
755 Unexpect aCatch(SALOME_SalomeException);
756 SMESH::SMESH_Group_var aNewGroup =
757 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
759 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
760 SALOMEDS::SObject_var aSO =
761 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
762 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
763 if ( !aSO->_is_nil()) {
764 // Update Python script
765 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
766 << ElementTypeString(theElemType) << ", '" << theName << "' )";
769 return aNewGroup._retn();
773 //=============================================================================
777 //=============================================================================
778 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
780 GEOM::GEOM_Object_ptr theGeomObj)
781 throw(SALOME::SALOME_Exception)
783 Unexpect aCatch(SALOME_SalomeException);
784 SMESH::SMESH_GroupOnGeom_var aNewGroup;
786 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
787 if ( !aShape.IsNull() )
789 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
790 ( createGroup( theElemType, theName, aShape ));
792 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
793 SALOMEDS::SObject_var aSO =
794 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
795 aNewGroup, theGeomObj, theName);
796 if ( !aSO->_is_nil()) {
797 // Update Python script
798 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
799 << ElementTypeString(theElemType) << ", '" << theName << "', "
800 << theGeomObj << " )";
805 return aNewGroup._retn();
808 //=============================================================================
812 //=============================================================================
814 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
815 throw (SALOME::SALOME_Exception)
817 if ( theGroup->_is_nil() )
820 SMESH_GroupBase_i* aGroup =
821 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
825 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
826 if ( !aStudy->_is_nil() ) {
827 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
829 if ( !aGroupSO->_is_nil() ) {
830 // Update Python script
831 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
833 // Remove group's SObject
834 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
838 // Remove the group from SMESH data structures
839 removeGroup( aGroup->GetLocalID() );
842 //=============================================================================
843 /*! RemoveGroupWithContents
844 * Remove group with its contents
846 //=============================================================================
847 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
848 throw (SALOME::SALOME_Exception)
850 if ( theGroup->_is_nil() )
853 SMESH_GroupBase_i* aGroup =
854 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
858 SMESH::long_array_var anIds = aGroup->GetListOfID();
859 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
861 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
864 if ( aGroup->GetType() == SMESH::NODE )
865 aMeshEditor->RemoveNodes( anIds );
867 aMeshEditor->RemoveElements( anIds );
870 RemoveGroup( theGroup );
872 // Update Python script
873 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
876 //================================================================================
878 * \brief Get the list of groups existing in the mesh
879 * \retval SMESH::ListOfGroups * - list of groups
881 //================================================================================
883 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
885 Unexpect aCatch(SALOME_SalomeException);
886 if (MYDEBUG) MESSAGE("GetGroups");
888 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
891 TPythonDump aPythonDump;
892 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
896 aList->length( _mapGroups.size() );
898 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
899 for ( ; it != _mapGroups.end(); it++ ) {
900 if ( CORBA::is_nil( it->second )) continue;
901 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
903 if (i > 1) aPythonDump << ", ";
904 aPythonDump << it->second;
908 catch(SALOME_Exception & S_ex) {
909 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
912 // Update Python script
913 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
914 aPythonDump << " ] = " << _this() << ".GetGroups()";
916 return aList._retn();
919 //=============================================================================
921 * Get number of groups existing in the mesh
923 //=============================================================================
925 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
927 Unexpect aCatch(SALOME_SalomeException);
928 return _mapGroups.size();
931 //=============================================================================
933 * New group is created. All mesh elements that are
934 * present in initial groups are added to the new one
936 //=============================================================================
937 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
938 SMESH::SMESH_GroupBase_ptr theGroup2,
939 const char* theName )
940 throw (SALOME::SALOME_Exception)
944 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
945 theGroup1->GetType() != theGroup2->GetType() )
946 return SMESH::SMESH_Group::_nil();
949 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
950 if ( aResGrp->_is_nil() )
951 return SMESH::SMESH_Group::_nil();
953 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
954 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
956 TColStd_MapOfInteger aResMap;
958 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
959 aResMap.Add( anIds1[ i1 ] );
961 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
962 aResMap.Add( anIds2[ i2 ] );
964 SMESH::long_array_var aResIds = new SMESH::long_array;
965 aResIds->length( aResMap.Extent() );
968 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
969 for( ; anIter.More(); anIter.Next() )
970 aResIds[ resI++ ] = anIter.Key();
972 aResGrp->Add( aResIds );
974 // Clear python lines, created by CreateGroup() and Add()
975 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
976 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
977 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
979 // Update Python script
980 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
981 << theGroup1 << ", " << theGroup2 << ", '"
984 return aResGrp._retn();
988 return SMESH::SMESH_Group::_nil();
992 //=============================================================================
994 \brief Union list of groups. New group is created. All mesh elements that are
995 present in initial groups are added to the new one.
996 \param theGroups list of groups
997 \param theName name of group to be created
998 \return pointer on the group
1000 //=============================================================================
1001 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1002 const char* theName )
1003 throw (SALOME::SALOME_Exception)
1006 return SMESH::SMESH_Group::_nil();
1010 vector< int > anIds;
1011 SMESH::ElementType aType = SMESH::ALL;
1012 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1014 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1015 if ( CORBA::is_nil( aGrp ) )
1019 SMESH::ElementType aCurrType = aGrp->GetType();
1020 if ( aType == SMESH::ALL )
1024 if ( aType != aCurrType )
1025 return SMESH::SMESH_Group::_nil();
1029 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1030 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1032 int aCurrId = aCurrIds[ i ];
1033 anIds.push_back( aCurrId );
1038 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1039 if ( aResGrp->_is_nil() )
1040 return SMESH::SMESH_Group::_nil();
1042 // Create array of identifiers
1043 SMESH::long_array_var aResIds = new SMESH::long_array;
1044 aResIds->length( anIds.size() );
1046 //NCollection_Map< int >::Iterator anIter( anIds );
1047 for ( int i = 0; i<anIds.size(); i++ )
1049 aResIds[ i ] = anIds[i];
1051 aResGrp->Add( aResIds );
1053 // Clear python lines, created by CreateGroup() and Add()
1054 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1055 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1056 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1058 // Update Python script
1060 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1061 << &theGroups << ", '" << theName << "' )";
1063 return aResGrp._retn();
1067 return SMESH::SMESH_Group::_nil();
1071 //=============================================================================
1073 * New group is created. All mesh elements that are
1074 * present in both initial groups are added to the new one.
1076 //=============================================================================
1077 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1078 SMESH::SMESH_GroupBase_ptr theGroup2,
1079 const char* theName )
1080 throw (SALOME::SALOME_Exception)
1082 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1083 theGroup1->GetType() != theGroup2->GetType() )
1084 return SMESH::SMESH_Group::_nil();
1086 // Create Intersection
1087 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1088 if ( aResGrp->_is_nil() )
1091 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1092 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1094 TColStd_MapOfInteger aMap1;
1096 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1097 aMap1.Add( anIds1[ i1 ] );
1099 TColStd_SequenceOfInteger aSeq;
1101 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1102 if ( aMap1.Contains( anIds2[ i2 ] ) )
1103 aSeq.Append( anIds2[ i2 ] );
1105 SMESH::long_array_var aResIds = new SMESH::long_array;
1106 aResIds->length( aSeq.Length() );
1108 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1109 aResIds[ resI ] = aSeq( resI + 1 );
1111 aResGrp->Add( aResIds );
1113 // Clear python lines, created by CreateGroup() and Add()
1114 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1115 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1116 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1118 // Update Python script
1119 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1120 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1122 return aResGrp._retn();
1125 //=============================================================================
1127 \brief Intersect list of groups. New group is created. All mesh elements that
1128 are present in all initial groups simultaneously are added to the new one.
1129 \param theGroups list of groups
1130 \param theName name of group to be created
1131 \return pointer on the group
1133 //=============================================================================
1134 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1135 const SMESH::ListOfGroups& theGroups, const char* theName )
1136 throw (SALOME::SALOME_Exception)
1139 return SMESH::SMESH_Group::_nil();
1143 NCollection_DataMap< int, int > anIdToCount;
1144 SMESH::ElementType aType = SMESH::ALL;
1145 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1147 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1148 if ( CORBA::is_nil( aGrp ) )
1152 SMESH::ElementType aCurrType = aGrp->GetType();
1153 if ( aType == SMESH::ALL )
1157 if ( aType != aCurrType )
1158 return SMESH::SMESH_Group::_nil();
1161 // calculates number of occurance ids in groups
1162 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1163 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1165 int aCurrId = aCurrIds[ i ];
1166 if ( !anIdToCount.IsBound( aCurrId ) )
1167 anIdToCount.Bind( aCurrId, 1 );
1169 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1173 // create map of ids
1174 int nbGrp = theGroups.length();
1175 vector< int > anIds;
1176 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1177 for ( ; anIter.More(); anIter.Next() )
1179 int aCurrId = anIter.Key();
1180 int aCurrNb = anIter.Value();
1181 if ( aCurrNb == nbGrp )
1182 anIds.push_back( aCurrId );
1186 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1187 if ( aResGrp->_is_nil() )
1188 return SMESH::SMESH_Group::_nil();
1190 // Create array of identifiers
1191 SMESH::long_array_var aResIds = new SMESH::long_array;
1192 aResIds->length( anIds.size() );
1194 //NCollection_Map< int >::Iterator aListIter( anIds );
1195 for ( int i = 0; i<anIds.size(); i++ )
1197 aResIds[ i ] = anIds[i];
1199 aResGrp->Add( aResIds );
1201 // Clear python lines, created by CreateGroup() and Add()
1202 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1203 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1204 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1206 // Update Python script
1208 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1209 << &theGroups << ", '" << theName << "' )";
1211 return aResGrp._retn();
1215 return SMESH::SMESH_Group::_nil();
1219 //=============================================================================
1221 * New group is created. All mesh elements that are present in
1222 * main group but do not present in tool group are added to the new one
1224 //=============================================================================
1225 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1226 SMESH::SMESH_GroupBase_ptr theGroup2,
1227 const char* theName )
1228 throw (SALOME::SALOME_Exception)
1230 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1231 theGroup1->GetType() != theGroup2->GetType() )
1232 return SMESH::SMESH_Group::_nil();
1235 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1236 if ( aResGrp->_is_nil() )
1239 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1240 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1242 TColStd_MapOfInteger aMap2;
1244 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1245 aMap2.Add( anIds2[ i2 ] );
1247 TColStd_SequenceOfInteger aSeq;
1248 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1249 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1250 aSeq.Append( anIds1[ i1 ] );
1252 SMESH::long_array_var aResIds = new SMESH::long_array;
1253 aResIds->length( aSeq.Length() );
1255 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1256 aResIds[ resI ] = aSeq( resI + 1 );
1258 aResGrp->Add( aResIds );
1260 // Clear python lines, created by CreateGroup() and Add()
1261 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1262 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1263 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1265 // Update Python script
1266 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1267 << theGroup1 << ", " << theGroup2 << ", '"
1268 << theName << "' )";
1270 return aResGrp._retn();
1273 //=============================================================================
1275 \brief Cut lists of groups. New group is created. All mesh elements that are
1276 present in main groups but do not present in tool groups are added to the new one
1277 \param theMainGroups list of main groups
1278 \param theToolGroups list of tool groups
1279 \param theName name of group to be created
1280 \return pointer on the group
1282 //=============================================================================
1283 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1284 const SMESH::ListOfGroups& theMainGroups,
1285 const SMESH::ListOfGroups& theToolGroups,
1286 const char* theName )
1287 throw (SALOME::SALOME_Exception)
1290 return SMESH::SMESH_Group::_nil();
1294 set< int > aToolIds;
1295 SMESH::ElementType aType = SMESH::ALL;
1297 // iterate through tool groups
1298 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1300 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1301 if ( CORBA::is_nil( aGrp ) )
1305 SMESH::ElementType aCurrType = aGrp->GetType();
1306 if ( aType == SMESH::ALL )
1310 if ( aType != aCurrType )
1311 return SMESH::SMESH_Group::_nil();
1315 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1316 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1318 int aCurrId = aCurrIds[ i ];
1319 aToolIds.insert( aCurrId );
1323 vector< int > anIds; // result
1325 // Iterate through main group
1326 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1328 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1329 if ( CORBA::is_nil( aGrp ) )
1333 SMESH::ElementType aCurrType = aGrp->GetType();
1334 if ( aType == SMESH::ALL )
1338 if ( aType != aCurrType )
1339 return SMESH::SMESH_Group::_nil();
1343 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1344 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1346 int aCurrId = aCurrIds[ i ];
1347 if ( !aToolIds.count( aCurrId ) )
1348 anIds.push_back( aCurrId );
1353 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1354 if ( aResGrp->_is_nil() )
1355 return SMESH::SMESH_Group::_nil();
1357 // Create array of identifiers
1358 SMESH::long_array_var aResIds = new SMESH::long_array;
1359 aResIds->length( anIds.size() );
1361 for (int i=0; i<anIds.size(); i++ )
1363 aResIds[ i ] = anIds[i];
1365 aResGrp->Add( aResIds );
1367 // Clear python lines, created by CreateGroup() and Add()
1368 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1369 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1370 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1372 // Update Python script
1374 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1375 << &theMainGroups << ", " << &theToolGroups << ", '"
1376 << theName << "' )";
1378 return aResGrp._retn();
1382 return SMESH::SMESH_Group::_nil();
1386 //=============================================================================
1388 \brief Create groups of entities from existing groups of superior dimensions
1390 1) extract all nodes from each group,
1391 2) combine all elements of specified dimension laying on these nodes.
1392 \param theGroups list of source groups
1393 \param theElemType dimension of elements
1394 \param theName name of new group
1395 \return pointer on new group
1397 //=============================================================================
1398 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1399 const SMESH::ListOfGroups& theGroups,
1400 SMESH::ElementType theElemType,
1401 const char* theName )
1402 throw (SALOME::SALOME_Exception)
1404 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1406 if ( !theName || !aMeshDS )
1407 return SMESH::SMESH_Group::_nil();
1409 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1413 // Create map of nodes from all groups
1415 set< int > aNodeMap;
1417 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1419 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1420 if ( CORBA::is_nil( aGrp ) )
1423 SMESH::ElementType aType = aGrp->GetType();
1424 if ( aType == SMESH::ALL )
1426 else if ( aType == SMESH::NODE )
1428 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1429 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1431 int aCurrId = aCurrIds[ i ];
1432 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1434 aNodeMap.insert( aNode->GetID() );
1439 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1440 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1442 int aCurrId = aCurrIds[ i ];
1443 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1446 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1447 while( aNodeIter->more() )
1449 const SMDS_MeshNode* aNode =
1450 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1452 aNodeMap.insert( aNode->GetID() );
1458 // Get result identifiers
1460 vector< int > aResultIds;
1461 if ( theElemType == SMESH::NODE )
1463 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1464 set<int>::iterator iter = aNodeMap.begin();
1465 for ( ; iter != aNodeMap.end(); iter++ )
1466 aResultIds.push_back( *iter);
1470 // Create list of elements of given dimension constructed on the nodes
1471 vector< int > anElemList;
1472 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1473 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1474 set<int>::iterator iter = aNodeMap.begin();
1475 for ( ; iter != aNodeMap.end(); iter++ )
1477 const SMDS_MeshElement* aNode =
1478 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1482 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1483 while( anElemIter->more() )
1485 const SMDS_MeshElement* anElem =
1486 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1487 if ( anElem && anElem->GetType() == anElemType )
1488 anElemList.push_back( anElem->GetID() );
1492 // check whether all nodes of elements are present in nodes map
1493 //NCollection_Map< int >::Iterator anIter( anElemList );
1494 //for ( ; anIter.More(); anIter.Next() )
1495 for (int i=0; i< anElemList.size(); i++)
1497 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1502 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1503 while( aNodeIter->more() )
1505 const SMDS_MeshNode* aNode =
1506 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1507 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1514 aResultIds.push_back( anElem->GetID() );
1520 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1521 if ( aResGrp->_is_nil() )
1522 return SMESH::SMESH_Group::_nil();
1524 // Create array of identifiers
1525 SMESH::long_array_var aResIds = new SMESH::long_array;
1526 aResIds->length( aResultIds.size() );
1528 //NCollection_Map< int >::Iterator aResIter( aResultIds );
1529 //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1530 for (int i=0; i< aResultIds.size(); i++)
1531 aResIds[ i ] = aResultIds[i];
1532 aResGrp->Add( aResIds );
1534 // Remove strings corresponding to group creation
1535 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1536 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1537 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1539 // Update Python script
1541 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1542 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1544 return aResGrp._retn();
1548 return SMESH::SMESH_Group::_nil();
1552 //================================================================================
1554 * \brief Remember GEOM group data
1556 //================================================================================
1558 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1559 CORBA::Object_ptr theSmeshObj)
1561 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1564 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1565 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1566 if ( groupSO->_is_nil() )
1569 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1570 GEOM::GEOM_IGroupOperations_var groupOp =
1571 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1572 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1575 _geomGroupData.push_back( TGeomGroupData() );
1576 TGeomGroupData & groupData = _geomGroupData.back();
1578 CORBA::String_var entry = groupSO->GetID();
1579 groupData._groupEntry = entry.in();
1581 for ( int i = 0; i < ids->length(); ++i )
1582 groupData._indices.insert( ids[i] );
1584 groupData._smeshObject = theSmeshObj;
1587 //================================================================================
1589 * Remove GEOM group data relating to removed smesh object
1591 //================================================================================
1593 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1595 list<TGeomGroupData>::iterator
1596 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1597 for ( ; data != dataEnd; ++data ) {
1598 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1599 _geomGroupData.erase( data );
1605 //================================================================================
1607 * \brief Return new group contents if it has been changed and update group data
1609 //================================================================================
1611 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1613 TopoDS_Shape newShape;
1616 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1617 if ( study->_is_nil() ) return newShape; // means "not changed"
1618 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1619 if ( !groupSO->_is_nil() )
1621 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1622 if ( CORBA::is_nil( groupObj )) return newShape;
1623 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1625 // get indices of group items
1626 set<int> curIndices;
1627 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1628 GEOM::GEOM_IGroupOperations_var groupOp =
1629 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1630 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1631 for ( int i = 0; i < ids->length(); ++i )
1632 curIndices.insert( ids[i] );
1634 if ( groupData._indices == curIndices )
1635 return newShape; // group not changed
1638 groupData._indices = curIndices;
1640 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1641 if ( !geomClient ) return newShape;
1642 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1643 geomClient->RemoveShapeFromBuffer( groupIOR );
1644 newShape = _gen_i->GeomObjectToShape( geomGroup );
1647 if ( newShape.IsNull() ) {
1648 // geom group becomes empty - return empty compound
1649 TopoDS_Compound compound;
1650 BRep_Builder().MakeCompound(compound);
1651 newShape = compound;
1657 //=============================================================================
1659 * \brief Storage of shape and index used in CheckGeomGroupModif()
1661 //=============================================================================
1662 struct TIndexedShape {
1664 TopoDS_Shape _shape;
1665 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1668 //=============================================================================
1670 * \brief Update objects depending on changed geom groups
1672 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1673 * issue 0020210: Update of a smesh group after modification of the associated geom group
1675 //=============================================================================
1677 void SMESH_Mesh_i::CheckGeomGroupModif()
1679 if ( !_impl->HasShapeToMesh() ) return;
1681 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1682 if ( study->_is_nil() ) return;
1684 CORBA::Long nbEntities = NbNodes() + NbElements();
1686 // Check if group contents changed
1688 typedef map< string, TopoDS_Shape > TEntry2Geom;
1689 TEntry2Geom newGroupContents;
1691 list<TGeomGroupData>::iterator
1692 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1693 for ( ; data != dataEnd; ++data )
1695 pair< TEntry2Geom::iterator, bool > it_new =
1696 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1697 bool processedGroup = !it_new.second;
1698 TopoDS_Shape& newShape = it_new.first->second;
1699 if ( !processedGroup )
1700 newShape = newGroupShape( *data );
1701 if ( newShape.IsNull() )
1702 continue; // no changes
1704 if ( processedGroup ) { // update group indices
1705 list<TGeomGroupData>::iterator data2 = data;
1706 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1707 data->_indices = data2->_indices;
1710 // Update SMESH objects according to new GEOM group contents
1712 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1713 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1715 int oldID = submesh->GetId();
1716 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1718 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1720 // update hypotheses
1721 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1722 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1723 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1725 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1726 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1728 // care of submeshes
1729 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1730 int newID = newSubmesh->GetId();
1731 if ( newID != oldID ) {
1732 _mapSubMesh [ newID ] = newSubmesh;
1733 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1734 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1735 _mapSubMesh. erase(oldID);
1736 _mapSubMesh_i. erase(oldID);
1737 _mapSubMeshIor.erase(oldID);
1738 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1743 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1744 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1745 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1747 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1749 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1750 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1751 ds->SetShape( newShape );
1756 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1757 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1759 // Remove groups and submeshes basing on removed sub-shapes
1761 TopTools_MapOfShape newShapeMap;
1762 TopoDS_Iterator shapeIt( newShape );
1763 for ( ; shapeIt.More(); shapeIt.Next() )
1764 newShapeMap.Add( shapeIt.Value() );
1766 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1767 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1769 if ( newShapeMap.Contains( shapeIt.Value() ))
1771 TopTools_IndexedMapOfShape oldShapeMap;
1772 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1773 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1775 const TopoDS_Shape& oldShape = oldShapeMap(i);
1776 int oldInd = meshDS->ShapeToIndex( oldShape );
1778 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1779 if ( i_smIor != _mapSubMeshIor.end() ) {
1780 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1783 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1784 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1786 // check if a group bases on oldInd shape
1787 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1788 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1789 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1790 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1792 RemoveGroup( i_grp->second ); // several groups can base on same shape
1793 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1798 // Reassign hypotheses and update groups after setting the new shape to mesh
1800 // collect anassigned hypotheses
1801 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1802 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1803 TShapeHypList assignedHyps;
1804 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1806 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1807 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1808 if ( !hyps.empty() ) {
1809 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1810 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1811 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1814 // collect shapes supporting groups
1815 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1816 TShapeTypeList groupData;
1817 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1818 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1819 for ( ; grIt != groups.end(); ++grIt )
1821 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1823 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1825 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1826 _impl->ShapeToMesh( newShape );
1828 // reassign hypotheses
1829 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1830 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1832 TIndexedShape& geom = indS_hyps->first;
1833 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1834 int oldID = geom._index;
1835 int newID = meshDS->ShapeToIndex( geom._shape );
1838 if ( oldID == 1 ) { // main shape
1840 geom._shape = newShape;
1842 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1843 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1844 // care of submeshes
1845 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1846 if ( newID != oldID ) {
1847 _mapSubMesh [ newID ] = newSubmesh;
1848 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1849 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1850 _mapSubMesh. erase(oldID);
1851 _mapSubMesh_i. erase(oldID);
1852 _mapSubMeshIor.erase(oldID);
1853 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1857 TShapeTypeList::iterator geomType = groupData.begin();
1858 for ( ; geomType != groupData.end(); ++geomType )
1860 const TIndexedShape& geom = geomType->first;
1861 int oldID = geom._index;
1862 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1865 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1866 CORBA::String_var name = groupSO->GetName();
1868 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1870 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1871 group_i->changeLocalId( newID );
1874 break; // everything has been updated
1877 } // loop on group data
1881 CORBA::Long newNbEntities = NbNodes() + NbElements();
1882 list< SALOMEDS::SObject_var > soToUpdateIcons;
1883 if ( newNbEntities != nbEntities )
1885 // Add all SObjects with icons
1886 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1888 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1889 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1890 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1892 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1893 i_gr != _mapGroups.end(); ++i_gr ) // groups
1894 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1897 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1898 for ( ; so != soToUpdateIcons.end(); ++so )
1899 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1902 //=============================================================================
1904 * \brief Create standalone group instead if group on geometry
1906 //=============================================================================
1908 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1910 SMESH::SMESH_Group_var aGroup;
1911 if ( theGroup->_is_nil() )
1912 return aGroup._retn();
1914 Unexpect aCatch(SALOME_SalomeException);
1916 SMESH_GroupBase_i* aGroupToRem =
1917 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1919 return aGroup._retn();
1921 int anId = aGroupToRem->GetLocalID();
1922 if ( !_impl->ConvertToStandalone( anId ) )
1923 return aGroup._retn();
1924 removeGeomGroupData( theGroup );
1926 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1928 // remove old instance of group from own map
1929 _mapGroups.erase( anId );
1931 SALOMEDS::StudyBuilder_var builder;
1932 SALOMEDS::SObject_var aGroupSO;
1933 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1934 if ( !aStudy->_is_nil() ) {
1935 builder = aStudy->NewBuilder();
1936 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1937 if ( !aGroupSO->_is_nil() ) {
1939 // remove reference to geometry
1940 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1941 for ( ; chItr->More(); chItr->Next() )
1942 // Remove group's child SObject
1943 builder->RemoveObject( chItr->Value() );
1945 // Update Python script
1946 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1947 << aGroupSO << " )";
1951 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1952 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1953 aGroupImpl->Register();
1954 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1956 // remember new group in own map
1957 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1958 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1960 // register CORBA object for persistence
1961 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1963 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1965 return aGroup._retn();
1968 //=============================================================================
1972 //=============================================================================
1974 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1976 if(MYDEBUG) MESSAGE( "createSubMesh" );
1977 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1979 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1980 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1981 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1982 SMESH::SMESH_subMesh_var subMesh
1983 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1985 _mapSubMesh[subMeshId] = mySubMesh;
1986 _mapSubMesh_i[subMeshId] = subMeshServant;
1987 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1989 // register CORBA object for persistence
1990 int nextId = _gen_i->RegisterObject( subMesh );
1991 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1993 // to track changes of GEOM groups
1994 addGeomGroupData( theSubShapeObject, subMesh );
1996 return subMesh._retn();
1999 //=======================================================================
2000 //function : getSubMesh
2002 //=======================================================================
2004 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2006 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2007 if ( it == _mapSubMeshIor.end() )
2008 return SMESH::SMESH_subMesh::_nil();
2010 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2014 //=============================================================================
2018 //=============================================================================
2020 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2021 GEOM::GEOM_Object_ptr theSubShapeObject )
2023 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2024 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2027 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2029 CORBA::Long shapeId = theSubMesh->GetId();
2030 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2032 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2035 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2036 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2037 for ( ; hyp != hyps.end(); ++hyp )
2038 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2045 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2046 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2047 removeHypothesis( theSubShapeObject, aHypList[i] );
2050 catch( const SALOME::SALOME_Exception& ) {
2051 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2053 removeGeomGroupData( theSubShapeObject );
2055 int subMeshId = theSubMesh->GetId();
2057 _mapSubMesh.erase(subMeshId);
2058 _mapSubMesh_i.erase(subMeshId);
2059 _mapSubMeshIor.erase(subMeshId);
2060 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2063 //=============================================================================
2067 //=============================================================================
2069 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2070 const char* theName,
2071 const TopoDS_Shape& theShape )
2074 SMESH::SMESH_GroupBase_var aGroup;
2075 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2076 SMESH_GroupBase_i* aGroupImpl;
2077 if ( !theShape.IsNull() )
2078 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2080 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2082 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2083 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2084 aGroupImpl->Register();
2085 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2087 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2088 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2090 // register CORBA object for persistence
2091 int nextId = _gen_i->RegisterObject( aGroup );
2092 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2094 // to track changes of GEOM groups
2095 if ( !theShape.IsNull() ) {
2096 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2097 addGeomGroupData( geom, aGroup );
2100 return aGroup._retn();
2103 //=============================================================================
2105 * SMESH_Mesh_i::removeGroup
2107 * Should be called by ~SMESH_Group_i()
2109 //=============================================================================
2111 void SMESH_Mesh_i::removeGroup( const int theId )
2113 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2114 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2115 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2116 _mapGroups.erase( theId );
2117 removeGeomGroupData( group );
2118 if (! _impl->RemoveGroup( theId ))
2120 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2121 RemoveGroup( group );
2126 //=============================================================================
2130 //=============================================================================
2132 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2133 throw(SALOME::SALOME_Exception)
2135 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2137 SMESH::log_array_var aLog;
2139 list < SMESHDS_Command * >logDS = _impl->GetLog();
2140 aLog = new SMESH::log_array;
2142 int lg = logDS.size();
2145 list < SMESHDS_Command * >::iterator its = logDS.begin();
2146 while(its != logDS.end()){
2147 SMESHDS_Command *com = *its;
2148 int comType = com->GetType();
2150 int lgcom = com->GetNumber();
2152 const list < int >&intList = com->GetIndexes();
2153 int inum = intList.size();
2155 list < int >::const_iterator ii = intList.begin();
2156 const list < double >&coordList = com->GetCoords();
2157 int rnum = coordList.size();
2159 list < double >::const_iterator ir = coordList.begin();
2160 aLog[indexLog].commandType = comType;
2161 aLog[indexLog].number = lgcom;
2162 aLog[indexLog].coords.length(rnum);
2163 aLog[indexLog].indexes.length(inum);
2164 for(int i = 0; i < rnum; i++){
2165 aLog[indexLog].coords[i] = *ir;
2166 //MESSAGE(" "<<i<<" "<<ir.Value());
2169 for(int i = 0; i < inum; i++){
2170 aLog[indexLog].indexes[i] = *ii;
2171 //MESSAGE(" "<<i<<" "<<ii.Value());
2180 catch(SALOME_Exception & S_ex){
2181 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2183 return aLog._retn();
2187 //=============================================================================
2191 //=============================================================================
2193 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2195 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2199 //=============================================================================
2203 //=============================================================================
2205 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2207 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2211 //=============================================================================
2215 //=============================================================================
2217 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2222 //=============================================================================
2225 //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
2226 // SMESH_Mesh::RemoveGroup() (issue 0020918)
2227 struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
2229 SMESH_Mesh_i* _mesh;
2230 TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2231 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2235 //=============================================================================
2239 //=============================================================================
2241 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2243 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2246 _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
2249 //=============================================================================
2253 //=============================================================================
2255 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2257 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2261 //=============================================================================
2263 * Return mesh editor
2265 //=============================================================================
2267 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2269 // Create MeshEditor
2270 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2271 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2273 // Update Python script
2274 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2276 return aMesh._retn();
2279 //=============================================================================
2281 * Return mesh edition previewer
2283 //=============================================================================
2285 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2287 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2288 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2289 return aMesh._retn();
2292 //================================================================================
2294 * \brief Return true if the mesh has been edited since a last total re-compute
2295 * and those modifications may prevent successful partial re-compute
2297 //================================================================================
2299 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2301 Unexpect aCatch(SALOME_SalomeException);
2302 return _impl->HasModificationsToDiscard();
2305 //=============================================================================
2309 //=============================================================================
2310 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2312 Unexpect aCatch(SALOME_SalomeException);
2313 _impl->SetAutoColor(theAutoColor);
2316 //=============================================================================
2320 //=============================================================================
2321 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2323 Unexpect aCatch(SALOME_SalomeException);
2324 return _impl->GetAutoColor();
2328 //=============================================================================
2330 * Export in different formats
2332 //=============================================================================
2334 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2336 return _impl->HasDuplicatedGroupNamesMED();
2339 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2341 TCollection_AsciiString aFullName ((char*)file);
2342 OSD_Path aPath (aFullName);
2343 OSD_File aFile (aPath);
2344 if (aFile.Exists()) {
2345 // existing filesystem node
2346 if (aFile.KindOfFile() == OSD_FILE) {
2347 if (aFile.IsWriteable()) {
2352 if (aFile.Failed()) {
2353 TCollection_AsciiString msg ("File ");
2354 msg += aFullName + " cannot be replaced.";
2355 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2358 TCollection_AsciiString msg ("File ");
2359 msg += aFullName + " cannot be overwritten.";
2360 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2363 TCollection_AsciiString msg ("Location ");
2364 msg += aFullName + " is not a file.";
2365 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2368 // nonexisting file; check if it can be created
2370 aFile.Build(OSD_WriteOnly, OSD_Protection());
2371 if (aFile.Failed()) {
2372 TCollection_AsciiString msg ("You cannot create the file ");
2373 msg += aFullName + ". Check the directory existance and access rights.";
2374 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2382 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2383 CORBA::Boolean auto_groups,
2384 SMESH::MED_VERSION theVersion,
2385 CORBA::Boolean overwrite)
2386 throw(SALOME::SALOME_Exception)
2388 Unexpect aCatch(SALOME_SalomeException);
2391 PrepareForWriting(file, overwrite);
2392 const char* aMeshName = "Mesh";
2393 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2394 if ( !aStudy->_is_nil() ) {
2395 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2396 if ( !aMeshSO->_is_nil() ) {
2397 aMeshName = aMeshSO->GetName();
2398 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2399 if ( !aStudy->GetProperties()->IsLocked() )
2401 SALOMEDS::GenericAttribute_var anAttr;
2402 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2403 SALOMEDS::AttributeExternalFileDef_var aFileName;
2404 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2405 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2406 ASSERT(!aFileName->_is_nil());
2407 aFileName->SetValue(file);
2408 SALOMEDS::AttributeFileType_var aFileType;
2409 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2410 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2411 ASSERT(!aFileType->_is_nil());
2412 aFileType->SetValue("FICHIERMED");
2416 // Update Python script
2417 // set name of mesh before export
2418 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2420 // check names of groups
2423 TPythonDump() << _this() << ".ExportToMEDX( r'"
2424 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2426 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2429 void SMESH_Mesh_i::ExportToMED (const char* file,
2430 CORBA::Boolean auto_groups,
2431 SMESH::MED_VERSION theVersion)
2432 throw(SALOME::SALOME_Exception)
2434 ExportToMEDX(file,auto_groups,theVersion,true);
2437 void SMESH_Mesh_i::ExportMED (const char* file,
2438 CORBA::Boolean auto_groups)
2439 throw(SALOME::SALOME_Exception)
2441 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2444 void SMESH_Mesh_i::ExportDAT (const char *file)
2445 throw(SALOME::SALOME_Exception)
2447 Unexpect aCatch(SALOME_SalomeException);
2449 // Update Python script
2450 // check names of groups
2452 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2455 PrepareForWriting(file);
2456 _impl->ExportDAT(file);
2459 void SMESH_Mesh_i::ExportUNV (const char *file)
2460 throw(SALOME::SALOME_Exception)
2462 Unexpect aCatch(SALOME_SalomeException);
2464 // Update Python script
2465 // check names of groups
2467 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2470 PrepareForWriting(file);
2471 _impl->ExportUNV(file);
2474 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2475 throw(SALOME::SALOME_Exception)
2477 Unexpect aCatch(SALOME_SalomeException);
2479 // Update Python script
2480 // check names of groups
2482 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2485 PrepareForWriting(file);
2486 _impl->ExportSTL(file, isascii);
2489 //=============================================================================
2493 //=============================================================================
2495 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2497 Unexpect aCatch(SALOME_SalomeException);
2498 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2499 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2500 return aMesh._retn();
2503 //=============================================================================
2507 //=============================================================================
2508 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2510 Unexpect aCatch(SALOME_SalomeException);
2511 return _impl->NbNodes();
2514 //=============================================================================
2518 //=============================================================================
2519 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2521 Unexpect aCatch(SALOME_SalomeException);
2522 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2525 //=============================================================================
2529 //=============================================================================
2530 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2532 Unexpect aCatch(SALOME_SalomeException);
2533 return _impl->Nb0DElements();
2536 //=============================================================================
2540 //=============================================================================
2541 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2543 Unexpect aCatch(SALOME_SalomeException);
2544 return _impl->NbEdges();
2547 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2548 throw(SALOME::SALOME_Exception)
2550 Unexpect aCatch(SALOME_SalomeException);
2551 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2554 //=============================================================================
2558 //=============================================================================
2559 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2561 Unexpect aCatch(SALOME_SalomeException);
2562 return _impl->NbFaces();
2565 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2567 Unexpect aCatch(SALOME_SalomeException);
2568 return _impl->NbTriangles();
2571 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2573 Unexpect aCatch(SALOME_SalomeException);
2574 return _impl->NbQuadrangles();
2577 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2579 Unexpect aCatch(SALOME_SalomeException);
2580 return _impl->NbPolygons();
2583 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2584 throw(SALOME::SALOME_Exception)
2586 Unexpect aCatch(SALOME_SalomeException);
2587 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2590 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2591 throw(SALOME::SALOME_Exception)
2593 Unexpect aCatch(SALOME_SalomeException);
2594 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2597 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2598 throw(SALOME::SALOME_Exception)
2600 Unexpect aCatch(SALOME_SalomeException);
2601 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2604 //=============================================================================
2608 //=============================================================================
2609 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2611 Unexpect aCatch(SALOME_SalomeException);
2612 return _impl->NbVolumes();
2615 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2617 Unexpect aCatch(SALOME_SalomeException);
2618 return _impl->NbTetras();
2621 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2623 Unexpect aCatch(SALOME_SalomeException);
2624 return _impl->NbHexas();
2627 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2629 Unexpect aCatch(SALOME_SalomeException);
2630 return _impl->NbPyramids();
2633 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2635 Unexpect aCatch(SALOME_SalomeException);
2636 return _impl->NbPrisms();
2639 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2641 Unexpect aCatch(SALOME_SalomeException);
2642 return _impl->NbPolyhedrons();
2645 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2646 throw(SALOME::SALOME_Exception)
2648 Unexpect aCatch(SALOME_SalomeException);
2649 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2652 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2653 throw(SALOME::SALOME_Exception)
2655 Unexpect aCatch(SALOME_SalomeException);
2656 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2659 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2660 throw(SALOME::SALOME_Exception)
2662 Unexpect aCatch(SALOME_SalomeException);
2663 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2666 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2667 throw(SALOME::SALOME_Exception)
2669 Unexpect aCatch(SALOME_SalomeException);
2670 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2673 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2674 throw(SALOME::SALOME_Exception)
2676 Unexpect aCatch(SALOME_SalomeException);
2677 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2680 //=============================================================================
2684 //=============================================================================
2685 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2687 Unexpect aCatch(SALOME_SalomeException);
2688 return _mapSubMesh_i.size();
2691 //=============================================================================
2695 //=============================================================================
2696 char* SMESH_Mesh_i::Dump()
2700 return CORBA::string_dup( os.str().c_str() );
2703 //=============================================================================
2707 //=============================================================================
2708 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2710 // SMESH::long_array_var aResult = new SMESH::long_array();
2711 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2712 // int aMinId = aSMESHDS_Mesh->MinElementID();
2713 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2715 // aResult->length(aMaxId - aMinId + 1);
2717 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2718 // aResult[i++] = id;
2720 // return aResult._retn();
2722 return GetElementsId();
2725 //=============================================================================
2729 //=============================================================================
2731 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2732 throw (SALOME::SALOME_Exception)
2734 Unexpect aCatch(SALOME_SalomeException);
2735 MESSAGE("SMESH_Mesh_i::GetElementsId");
2736 SMESH::long_array_var aResult = new SMESH::long_array();
2737 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2739 if ( aSMESHDS_Mesh == NULL )
2740 return aResult._retn();
2742 long nbElements = NbElements();
2743 aResult->length( nbElements );
2744 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2745 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2746 aResult[i] = anIt->next()->GetID();
2748 return aResult._retn();
2752 //=============================================================================
2756 //=============================================================================
2758 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2759 throw (SALOME::SALOME_Exception)
2761 Unexpect aCatch(SALOME_SalomeException);
2762 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2763 SMESH::long_array_var aResult = new SMESH::long_array();
2764 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2766 if ( aSMESHDS_Mesh == NULL )
2767 return aResult._retn();
2769 long nbElements = NbElements();
2771 // No sense in returning ids of elements along with ids of nodes:
2772 // when theElemType == SMESH::ALL, return node ids only if
2773 // there are no elements
2774 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2775 return GetNodesId();
2777 aResult->length( nbElements );
2781 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2782 while ( i < nbElements && anIt->more() ) {
2783 const SMDS_MeshElement* anElem = anIt->next();
2784 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2785 aResult[i++] = anElem->GetID();
2788 aResult->length( i );
2790 return aResult._retn();
2793 //=============================================================================
2797 //=============================================================================
2799 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2800 throw (SALOME::SALOME_Exception)
2802 Unexpect aCatch(SALOME_SalomeException);
2803 MESSAGE("SMESH_subMesh_i::GetNodesId");
2804 SMESH::long_array_var aResult = new SMESH::long_array();
2805 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2807 if ( aSMESHDS_Mesh == NULL )
2808 return aResult._retn();
2810 long nbNodes = NbNodes();
2811 aResult->length( nbNodes );
2812 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
2813 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2814 aResult[i] = anIt->next()->GetID();
2816 return aResult._retn();
2819 //=============================================================================
2823 //=============================================================================
2825 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2826 throw (SALOME::SALOME_Exception)
2828 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2831 //=============================================================================
2835 //=============================================================================
2837 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2838 throw (SALOME::SALOME_Exception)
2840 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2842 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2844 return ( SMESH::EntityType ) e->GetEntityType();
2847 //=============================================================================
2849 * Returns ID of elements for given submesh
2851 //=============================================================================
2852 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2853 throw (SALOME::SALOME_Exception)
2855 SMESH::long_array_var aResult = new SMESH::long_array();
2857 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2858 if(!SM) return aResult._retn();
2860 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2861 if(!SDSM) return aResult._retn();
2863 aResult->length(SDSM->NbElements());
2865 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2867 while ( eIt->more() ) {
2868 aResult[i++] = eIt->next()->GetID();
2871 return aResult._retn();
2875 //=============================================================================
2877 * Returns ID of nodes for given submesh
2878 * If param all==true - returns all nodes, else -
2879 * returns only nodes on shapes.
2881 //=============================================================================
2882 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2883 throw (SALOME::SALOME_Exception)
2885 SMESH::long_array_var aResult = new SMESH::long_array();
2887 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2888 if(!SM) return aResult._retn();
2890 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2891 if(!SDSM) return aResult._retn();
2894 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2895 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2896 while ( nIt->more() ) {
2897 const SMDS_MeshNode* elem = nIt->next();
2898 theElems.insert( elem->GetID() );
2901 else { // all nodes of submesh elements
2902 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2903 while ( eIt->more() ) {
2904 const SMDS_MeshElement* anElem = eIt->next();
2905 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2906 while ( nIt->more() ) {
2907 const SMDS_MeshElement* elem = nIt->next();
2908 theElems.insert( elem->GetID() );
2913 aResult->length(theElems.size());
2914 set<int>::iterator itElem;
2916 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2917 aResult[i++] = *itElem;
2919 return aResult._retn();
2923 //=============================================================================
2925 * Returns type of elements for given submesh
2927 //=============================================================================
2928 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2929 throw (SALOME::SALOME_Exception)
2931 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2932 if(!SM) return SMESH::ALL;
2934 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2935 if(!SDSM) return SMESH::ALL;
2937 if(SDSM->NbElements()==0)
2938 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2940 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2941 const SMDS_MeshElement* anElem = eIt->next();
2942 return ( SMESH::ElementType ) anElem->GetType();
2946 //=============================================================================
2950 //=============================================================================
2952 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2954 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2956 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2961 //=============================================================================
2963 * Get XYZ coordinates of node as list of double
2964 * If there is not node for given ID - returns empty list
2966 //=============================================================================
2968 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2970 SMESH::double_array_var aResult = new SMESH::double_array();
2971 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2972 if ( aSMESHDS_Mesh == NULL )
2973 return aResult._retn();
2976 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2978 return aResult._retn();
2982 aResult[0] = aNode->X();
2983 aResult[1] = aNode->Y();
2984 aResult[2] = aNode->Z();
2985 return aResult._retn();
2989 //=============================================================================
2991 * For given node returns list of IDs of inverse elements
2992 * If there is not node for given ID - returns empty list
2994 //=============================================================================
2996 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2998 SMESH::long_array_var aResult = new SMESH::long_array();
2999 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3000 if ( aSMESHDS_Mesh == NULL )
3001 return aResult._retn();
3004 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3006 return aResult._retn();
3008 // find inverse elements
3009 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3010 TColStd_SequenceOfInteger IDs;
3011 while(eIt->more()) {
3012 const SMDS_MeshElement* elem = eIt->next();
3013 IDs.Append(elem->GetID());
3015 if(IDs.Length()>0) {
3016 aResult->length(IDs.Length());
3018 for(; i<=IDs.Length(); i++) {
3019 aResult[i-1] = IDs.Value(i);
3022 return aResult._retn();
3025 //=============================================================================
3027 * \brief Return position of a node on shape
3029 //=============================================================================
3031 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3033 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3034 aNodePosition->shapeID = 0;
3035 aNodePosition->shapeType = GEOM::SHAPE;
3037 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3038 if ( !mesh ) return aNodePosition;
3040 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3042 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3044 aNodePosition->shapeID = aNode->getshapeId();
3045 switch ( pos->GetTypeOfPosition() ) {
3047 aNodePosition->shapeType = GEOM::EDGE;
3048 aNodePosition->params.length(1);
3049 aNodePosition->params[0] =
3050 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3053 aNodePosition->shapeType = GEOM::FACE;
3054 aNodePosition->params.length(2);
3055 aNodePosition->params[0] =
3056 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3057 aNodePosition->params[1] =
3058 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3060 case SMDS_TOP_VERTEX:
3061 aNodePosition->shapeType = GEOM::VERTEX;
3063 case SMDS_TOP_3DSPACE:
3064 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3065 aNodePosition->shapeType = GEOM::SOLID;
3066 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3067 aNodePosition->shapeType = GEOM::SHELL;
3073 return aNodePosition;
3076 //=============================================================================
3078 * If given element is node returns IDs of shape from position
3079 * If there is not node for given ID - returns -1
3081 //=============================================================================
3083 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3085 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3086 if ( aSMESHDS_Mesh == NULL )
3090 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3092 return aNode->getshapeId();
3099 //=============================================================================
3101 * For given element returns ID of result shape after
3102 * ::FindShape() from SMESH_MeshEditor
3103 * If there is not element for given ID - returns -1
3105 //=============================================================================
3107 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3109 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3110 if ( aSMESHDS_Mesh == NULL )
3113 // try to find element
3114 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3118 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3119 ::SMESH_MeshEditor aMeshEditor(_impl);
3120 int index = aMeshEditor.FindShape( elem );
3128 //=============================================================================
3130 * Returns number of nodes for given element
3131 * If there is not element for given ID - returns -1
3133 //=============================================================================
3135 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3137 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3138 if ( aSMESHDS_Mesh == NULL ) return -1;
3139 // try to find element
3140 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3141 if(!elem) return -1;
3142 return elem->NbNodes();
3146 //=============================================================================
3148 * Returns ID of node by given index for given element
3149 * If there is not element for given ID - returns -1
3150 * If there is not node for given index - returns -2
3152 //=============================================================================
3154 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3156 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3157 if ( aSMESHDS_Mesh == NULL ) return -1;
3158 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3159 if(!elem) return -1;
3160 if( index>=elem->NbNodes() || index<0 ) return -1;
3161 return elem->GetNode(index)->GetID();
3164 //=============================================================================
3166 * Returns IDs of nodes of given element
3168 //=============================================================================
3170 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3172 SMESH::long_array_var aResult = new SMESH::long_array();
3173 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3175 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3177 aResult->length( elem->NbNodes() );
3178 for ( int i = 0; i < elem->NbNodes(); ++i )
3179 aResult[ i ] = elem->GetNode( i )->GetID();
3182 return aResult._retn();
3185 //=============================================================================
3187 * Returns true if given node is medium node
3188 * in given quadratic element
3190 //=============================================================================
3192 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3194 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3195 if ( aSMESHDS_Mesh == NULL ) return false;
3197 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3198 if(!aNode) return false;
3199 // try to find element
3200 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3201 if(!elem) return false;
3203 return elem->IsMediumNode(aNode);
3207 //=============================================================================
3209 * Returns true if given node is medium node
3210 * in one of quadratic elements
3212 //=============================================================================
3214 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3215 SMESH::ElementType theElemType)
3217 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3218 if ( aSMESHDS_Mesh == NULL ) return false;
3221 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3222 if(!aNode) return false;
3224 SMESH_MesherHelper aHelper( *(_impl) );
3226 SMDSAbs_ElementType aType;
3227 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3228 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3229 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3230 else aType = SMDSAbs_All;
3232 return aHelper.IsMedium(aNode,aType);
3236 //=============================================================================
3238 * Returns number of edges for given element
3240 //=============================================================================
3242 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3244 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3245 if ( aSMESHDS_Mesh == NULL ) return -1;
3246 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3247 if(!elem) return -1;
3248 return elem->NbEdges();
3252 //=============================================================================
3254 * Returns number of faces for given element
3256 //=============================================================================
3258 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3260 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3261 if ( aSMESHDS_Mesh == NULL ) return -1;
3262 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3263 if(!elem) return -1;
3264 return elem->NbFaces();
3267 //=======================================================================
3268 //function : GetElemFaceNodes
3269 //purpose : Returns nodes of given face (counted from zero) for given element.
3270 //=======================================================================
3272 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3273 CORBA::Short faceIndex)
3275 SMESH::long_array_var aResult = new SMESH::long_array();
3276 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3278 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3280 SMDS_VolumeTool vtool( elem );
3281 if ( faceIndex < vtool.NbFaces() )
3283 aResult->length( vtool.NbFaceNodes( faceIndex ));
3284 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3285 for ( int i = 0; i < aResult->length(); ++i )
3286 aResult[ i ] = nn[ i ]->GetID();
3290 return aResult._retn();
3293 //=======================================================================
3294 //function : FindElementByNodes
3295 //purpose : Returns an element based on all given nodes.
3296 //=======================================================================
3298 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3300 CORBA::Long elemID(0);
3301 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3303 vector< const SMDS_MeshNode * > nn( nodes.length() );
3304 for ( int i = 0; i < nodes.length(); ++i )
3305 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3308 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3309 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3310 _impl->NbFaces( ORDER_QUADRATIC ) ||
3311 _impl->NbVolumes( ORDER_QUADRATIC )))
3312 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3314 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3319 //=============================================================================
3321 * Returns true if given element is polygon
3323 //=============================================================================
3325 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3327 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3328 if ( aSMESHDS_Mesh == NULL ) return false;
3329 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3330 if(!elem) return false;
3331 return elem->IsPoly();
3335 //=============================================================================
3337 * Returns true if given element is quadratic
3339 //=============================================================================
3341 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3343 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3344 if ( aSMESHDS_Mesh == NULL ) return false;
3345 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3346 if(!elem) return false;
3347 return elem->IsQuadratic();
3351 //=============================================================================
3353 * Returns bary center for given element
3355 //=============================================================================
3357 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3359 SMESH::double_array_var aResult = new SMESH::double_array();
3360 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3361 if ( aSMESHDS_Mesh == NULL )
3362 return aResult._retn();
3364 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3366 return aResult._retn();
3368 if(elem->GetType()==SMDSAbs_Volume) {
3369 SMDS_VolumeTool aTool;
3370 if(aTool.Set(elem)) {
3372 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3377 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3379 double x=0., y=0., z=0.;
3380 for(; anIt->more(); ) {
3382 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3396 return aResult._retn();
3400 //=============================================================================
3402 * Create and publish group servants if any groups were imported or created anyhow
3404 //=============================================================================
3406 void SMESH_Mesh_i::CreateGroupServants()
3408 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3411 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3412 while ( groupIt->more() )
3414 ::SMESH_Group* group = groupIt->next();
3415 int anId = group->GetGroupDS()->GetID();
3417 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3418 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3420 addedIDs.insert( anId );
3422 SMESH_GroupBase_i* aGroupImpl;
3424 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3425 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3427 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3428 shape = groupOnGeom->GetShape();
3431 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3434 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3435 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3436 aGroupImpl->Register();
3438 SMESH::SMESH_GroupBase_var groupVar =
3439 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3440 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3442 // register CORBA object for persistence
3443 int nextId = _gen_i->RegisterObject( groupVar );
3444 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3446 // publishing the groups in the study
3447 if ( !aStudy->_is_nil() ) {
3448 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3449 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3452 if ( !addedIDs.empty() )
3455 set<int>::iterator id = addedIDs.begin();
3456 for ( ; id != addedIDs.end(); ++id )
3458 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3459 int i = std::distance( _mapGroups.begin(), it );
3460 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3465 //=============================================================================
3467 * \brief Return groups cantained in _mapGroups by their IDs
3469 //=============================================================================
3471 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3473 int nbGroups = groupIDs.size();
3474 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3475 aList->length( nbGroups );
3477 list<int>::const_iterator ids = groupIDs.begin();
3478 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3480 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3481 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3482 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3484 aList->length( nbGroups );
3485 return aList._retn();
3488 //=============================================================================
3490 * \brief Return information about imported file
3492 //=============================================================================
3494 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3496 SALOME_MED::MedFileInfo_var res( myFileInfo );
3497 if ( !res.operator->() ) {
3498 res = new SALOME_MED::MedFileInfo;
3500 res->fileSize = res->major = res->minor = res->release = -1;
3505 //=============================================================================
3507 * \brief Check and correct names of mesh groups
3509 //=============================================================================
3511 void SMESH_Mesh_i::checkGroupNames()
3513 int nbGrp = NbGroups();
3517 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3518 if ( aStudy->_is_nil() )
3519 return; // nothing to do
3521 SMESH::ListOfGroups* grpList = 0;
3522 // avoid dump of "GetGroups"
3524 // store python dump into a local variable inside local scope
3525 SMESH::TPythonDump pDump; // do not delete this line of code
3526 grpList = GetGroups();
3529 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3530 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3533 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3534 if ( aGrpSO->_is_nil() )
3536 // correct name of the mesh group if necessary
3537 const char* guiName = aGrpSO->GetName();
3538 if ( strcmp(guiName, aGrp->GetName()) )
3539 aGrp->SetName( guiName );
3543 //=============================================================================
3545 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3547 //=============================================================================
3548 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3550 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3551 CORBA::string_dup(theParameters));
3554 //=============================================================================
3556 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3558 //=============================================================================
3559 char* SMESH_Mesh_i::GetParameters()
3561 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3562 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3565 //=============================================================================
3567 * \brief Returns list of notebook variables used for last Mesh operation
3569 //=============================================================================
3570 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3572 SMESH::string_array_var aResult = new SMESH::string_array();
3573 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3575 char *aParameters = GetParameters();
3576 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3577 if(!aStudy->_is_nil()) {
3578 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3579 if(aSections->length() > 0) {
3580 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3581 aResult->length(aVars.length());
3582 for(int i = 0;i < aVars.length();i++)
3583 aResult[i] = CORBA::string_dup( aVars[i]);
3587 return aResult._retn();
3590 //=======================================================================
3591 //function : GetTypes
3592 //purpose : Returns types of elements it contains
3593 //=======================================================================
3595 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3597 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3601 if (_impl->NbEdges())
3602 types[nbTypes++] = SMESH::EDGE;
3603 if (_impl->NbFaces())
3604 types[nbTypes++] = SMESH::FACE;
3605 if (_impl->NbVolumes())
3606 types[nbTypes++] = SMESH::VOLUME;
3607 if (_impl->Nb0DElements())
3608 types[nbTypes++] = SMESH::ELEM0D;
3609 types->length( nbTypes );
3611 return types._retn();
3614 //=======================================================================
3615 //function : GetMesh
3616 //purpose : Returns self
3617 //=======================================================================
3619 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3621 return SMESH::SMESH_Mesh::_duplicate( _this() );
3624 //=============================================================================
3626 * \brief Returns statistic of mesh elements
3628 //=============================================================================
3629 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3631 SMESH::long_array_var aRes = new SMESH::long_array();
3632 aRes->length(SMESH::Entity_Last);
3633 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3635 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3637 return aRes._retn();
3638 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3639 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3640 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3641 return aRes._retn();
3644 //=============================================================================
3646 * \brief Collect statistic of mesh elements given by iterator
3648 //=============================================================================
3649 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3650 SMESH::long_array& theInfo)
3652 if (!theItr) return;
3653 while (theItr->more())
3654 theInfo[ theItr->next()->GetEntityType() ]++;
3657 //=============================================================================
3659 * \brief mapping of mesh dimension into shape type
3661 //=============================================================================
3662 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3664 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3666 case 0: aType = TopAbs_VERTEX; break;
3667 case 1: aType = TopAbs_EDGE; break;
3668 case 2: aType = TopAbs_FACE; break;
3670 default:aType = TopAbs_SOLID; break;
3675 //=============================================================================
3677 * \brief Internal structure used to find concurent submeshes
3679 * It represents a pair < submesh, concurent dimension >, where
3680 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3681 * with another submesh. In other words, it is dimension of a hypothesis assigned
3684 //=============================================================================
3690 int _dim; //!< a dimension the algo can build (concurrent dimension)
3691 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3692 TopTools_MapOfShape _shapeMap;
3693 SMESH_subMesh* _subMesh;
3694 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3697 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3699 const TopoDS_Shape& theShape)
3701 _subMesh = (SMESH_subMesh*)theSubMesh;
3702 SetShape( theDim, theShape );
3706 void SetShape(const int theDim,
3707 const TopoDS_Shape& theShape)
3710 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3711 if (_dim >= _ownDim)
3712 _shapeMap.Add( theShape );
3714 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3715 for( ; anExp.More(); anExp.Next() )
3716 _shapeMap.Add( anExp.Current() );
3720 //! Check sharing of sub shapes
3721 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3722 const TopTools_MapOfShape& theToFind,
3723 const TopAbs_ShapeEnum theType)
3725 bool isShared = false;
3726 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3727 for (; !isShared && anItr.More(); anItr.Next() ) {
3728 const TopoDS_Shape aSubSh = anItr.Key();
3729 // check for case when concurrent dimensions are same
3730 isShared = theToFind.Contains( aSubSh );
3731 // check for subshape with concurrent dimension
3732 TopExp_Explorer anExp( aSubSh, theType );
3733 for ( ; !isShared && anExp.More(); anExp.Next() )
3734 isShared = theToFind.Contains( anExp.Current() );
3739 //! check algorithms
3740 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3741 const SMESHDS_Hypothesis* theA2)
3743 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3744 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3745 return false; // one of the hypothesis is not algorithm
3746 // check algorithm names (should be equal)
3747 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3751 //! Check if subshape hypotheses are concurrent
3752 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3754 if ( _subMesh == theOther->_subMesh )
3755 return false; // same subshape - should not be
3757 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3758 // any of the two submeshes is not on COMPOUND shape )
3759 // -> no concurrency
3760 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3761 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3762 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3765 // bool checkSubShape = ( _dim >= theOther->_dim )
3766 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3767 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3768 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3769 if ( !checkSubShape )
3772 // check algorithms to be same
3773 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3774 return true; // different algorithms
3776 // check hypothesises for concurrence (skip first as algorithm)
3778 // pointers should be same, becase it is referenes from mesh hypothesis partition
3779 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3780 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3781 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3782 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3784 // the submeshes are concurrent if their algorithms has different parameters
3785 return nbSame != theOther->_hypothesises.size() - 1;
3788 }; // end of SMESH_DimHyp
3790 typedef list<SMESH_DimHyp*> TDimHypList;
3792 static void addDimHypInstance(const int theDim,
3793 const TopoDS_Shape& theShape,
3794 const SMESH_Algo* theAlgo,
3795 const SMESH_subMesh* theSubMesh,
3796 const list <const SMESHDS_Hypothesis*>& theHypList,
3797 TDimHypList* theDimHypListArr )
3799 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3800 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3801 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3802 listOfdimHyp.push_back( dimHyp );
3805 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3806 dimHyp->_hypothesises.push_front(theAlgo);
3807 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3808 for( ; hypIt != theHypList.end(); hypIt++ )
3809 dimHyp->_hypothesises.push_back( *hypIt );
3812 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3813 const TDimHypList& theListOfDimHyp,
3814 TListOfInt& theListOfConcurr )
3816 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3817 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3818 const SMESH_DimHyp* curDimHyp = *rIt;
3819 if ( curDimHyp == theDimHyp )
3820 break; // meet own dimHyp pointer in same dimension
3821 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3822 if ( find( theListOfConcurr.begin(),
3823 theListOfConcurr.end(),
3824 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3825 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3829 static void unionLists(TListOfInt& theListOfId,
3830 TListOfListOfInt& theListOfListOfId,
3833 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3834 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3836 continue; //skip already treated lists
3837 // check if other list has any same submesh object
3838 TListOfInt& otherListOfId = *it;
3839 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3840 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3843 // union two lists (from source into target)
3844 TListOfInt::iterator it2 = otherListOfId.begin();
3845 for ( ; it2 != otherListOfId.end(); it2++ ) {
3846 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3847 theListOfId.push_back(*it2);
3849 // clear source list
3850 otherListOfId.clear();
3854 //! free memory allocated for dimension-hypothesis objects
3855 static void removeDimHyps( TDimHypList* theArrOfList )
3857 for (int i = 0; i < 4; i++ ) {
3858 TDimHypList& listOfdimHyp = theArrOfList[i];
3859 TDimHypList::const_iterator it = listOfdimHyp.begin();
3860 for ( ; it != listOfdimHyp.end(); it++ )
3865 //=============================================================================
3867 * \brief Return submesh objects list in meshing order
3869 //=============================================================================
3871 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3873 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3875 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3877 return aResult._retn();
3879 ::SMESH_Mesh& mesh = GetImpl();
3880 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3881 if ( !anOrder.size() ) {
3883 // collect submeshes detecting concurrent algorithms and hypothesises
3884 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3886 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3887 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3888 ::SMESH_subMesh* sm = (*i_sm).second;
3890 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3892 // list of assigned hypothesises
3893 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3894 // Find out dimensions where the submesh can be concurrent.
3895 // We define the dimensions by algo of each of hypotheses in hypList
3896 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3897 for( ; hypIt != hypList.end(); hypIt++ ) {
3898 SMESH_Algo* anAlgo = 0;
3899 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3900 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3901 // hyp it-self is algo
3902 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3904 // try to find algorithm with help of subshapes
3905 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3906 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3907 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3910 continue; // no assigned algorithm to current submesh
3912 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3913 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3915 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3916 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3917 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3919 } // end iterations on submesh
3921 // iterate on created dimension-hypotheses and check for concurrents
3922 for ( int i = 0; i < 4; i++ ) {
3923 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3924 // check for concurrents in own and other dimensions (step-by-step)
3925 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3926 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3927 const SMESH_DimHyp* dimHyp = *dhIt;
3928 TListOfInt listOfConcurr;
3929 // looking for concurrents and collect into own list
3930 for ( int j = i; j < 4; j++ )
3931 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3932 // check if any concurrents found
3933 if ( listOfConcurr.size() > 0 ) {
3934 // add own submesh to list of concurrent
3935 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3936 anOrder.push_back( listOfConcurr );
3941 removeDimHyps(dimHypListArr);
3943 // now, minimise the number of concurrent groups
3944 // Here we assume that lists of submhes can has same submesh
3945 // in case of multi-dimension algorithms, as result
3946 // list with common submesh have to be union into one list
3948 TListOfListOfInt::iterator listIt = anOrder.begin();
3949 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3950 unionLists( *listIt, anOrder, listIndx + 1 );
3952 // convert submesh ids into interface instances
3953 // and dump command into python
3954 convertMeshOrder( anOrder, aResult, true );
3956 return aResult._retn();
3959 //=============================================================================
3961 * \brief find common submeshes with given submesh
3962 * \param theSubMeshList list of already collected submesh to check
3963 * \param theSubMesh given submesh to intersect with other
3964 * \param theCommonSubMeshes collected common submeshes
3966 //=============================================================================
3968 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
3969 const SMESH_subMesh* theSubMesh,
3970 set<const SMESH_subMesh*>& theCommon )
3974 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
3975 for ( ; it != theSubMeshList.end(); it++ )
3976 theSubMesh->FindIntersection( *it, theCommon );
3977 theSubMeshList.push_back( theSubMesh );
3978 //theCommon.insert( theSubMesh );
3981 //=============================================================================
3983 * \brief Set submesh object order
3984 * \param theSubMeshArray submesh array order
3986 //=============================================================================
3988 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
3991 ::SMESH_Mesh& mesh = GetImpl();
3993 TPythonDump aPythonDump; // prevent dump of called methods
3994 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
3996 TListOfListOfInt subMeshOrder;
3997 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
3999 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4000 TListOfInt subMeshIds;
4001 aPythonDump << "[ ";
4002 // Collect subMeshes which should be clear
4003 // do it list-by-list, because modification of submesh order
4004 // take effect between concurrent submeshes only
4005 set<const SMESH_subMesh*> subMeshToClear;
4006 list<const SMESH_subMesh*> subMeshList;
4007 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4009 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4011 aPythonDump << ", ";
4012 aPythonDump << subMesh;
4013 subMeshIds.push_back( subMesh->GetId() );
4014 // detect common parts of submeshes
4015 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4016 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4018 aPythonDump << " ]";
4019 subMeshOrder.push_back( subMeshIds );
4021 // clear collected submeshes
4022 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4023 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4024 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4026 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4027 // ClearSubMesh( *clrIt );
4030 aPythonDump << " ])";
4032 mesh.SetMeshOrder( subMeshOrder );
4038 //=============================================================================
4040 * \brief Convert submesh ids into submesh interfaces
4042 //=============================================================================
4044 void SMESH_Mesh_i::convertMeshOrder
4045 (const TListOfListOfInt& theIdsOrder,
4046 SMESH::submesh_array_array& theResOrder,
4047 const bool theIsDump)
4049 int nbSet = theIdsOrder.size();
4050 TPythonDump aPythonDump; // prevent dump of called methods
4052 aPythonDump << "[ ";
4053 theResOrder.length(nbSet);
4054 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4056 for( ; it != theIdsOrder.end(); it++ ) {
4057 // translate submesh identificators into submesh objects
4058 // takeing into account real number of concurrent lists
4059 const TListOfInt& aSubOrder = (*it);
4060 if (!aSubOrder.size())
4063 aPythonDump << "[ ";
4064 // convert shape indeces into interfaces
4065 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4066 aResSubSet->length(aSubOrder.size());
4067 TListOfInt::const_iterator subIt = aSubOrder.begin();
4068 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4069 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4071 SMESH::SMESH_subMesh_var subMesh =
4072 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4075 aPythonDump << ", ";
4076 aPythonDump << subMesh;
4078 aResSubSet[ j++ ] = subMesh;
4081 aPythonDump << " ]";
4082 theResOrder[ listIndx++ ] = aResSubSet;
4084 // correct number of lists
4085 theResOrder.length( listIndx );
4088 // finilise python dump
4089 aPythonDump << " ]";
4090 aPythonDump << " = " << _this() << ".GetMeshOrder()";