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 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2307 const int MAX_ATTEMPTS = 100;
2309 double tolerance = 0.5;
2310 SALOMEDS::Color col;
2314 // generate random color
2315 double red = (double)rand() / RAND_MAX;
2316 double green = (double)rand() / RAND_MAX;
2317 double blue = (double)rand() / RAND_MAX;
2318 // check existence in the list of the existing colors
2319 bool matched = false;
2320 std::list<SALOMEDS::Color>::const_iterator it;
2321 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2322 SALOMEDS::Color color = *it;
2323 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2324 matched = tol < tolerance;
2326 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2327 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2335 //=============================================================================
2339 //=============================================================================
2340 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2342 Unexpect aCatch(SALOME_SalomeException);
2343 _impl->SetAutoColor(theAutoColor);
2345 std::list<SALOMEDS::Color> aReservedColors;
2346 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2347 for ( ; it != _mapGroups.end(); it++ ) {
2348 if ( CORBA::is_nil( it->second )) continue;
2349 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2350 it->second->SetColor( aColor );
2351 aReservedColors.push_back( aColor );
2355 //=============================================================================
2359 //=============================================================================
2360 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2362 Unexpect aCatch(SALOME_SalomeException);
2363 return _impl->GetAutoColor();
2367 //=============================================================================
2369 * Export in different formats
2371 //=============================================================================
2373 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2375 return _impl->HasDuplicatedGroupNamesMED();
2378 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2380 TCollection_AsciiString aFullName ((char*)file);
2381 OSD_Path aPath (aFullName);
2382 OSD_File aFile (aPath);
2383 if (aFile.Exists()) {
2384 // existing filesystem node
2385 if (aFile.KindOfFile() == OSD_FILE) {
2386 if (aFile.IsWriteable()) {
2391 if (aFile.Failed()) {
2392 TCollection_AsciiString msg ("File ");
2393 msg += aFullName + " cannot be replaced.";
2394 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2397 TCollection_AsciiString msg ("File ");
2398 msg += aFullName + " cannot be overwritten.";
2399 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2402 TCollection_AsciiString msg ("Location ");
2403 msg += aFullName + " is not a file.";
2404 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2407 // nonexisting file; check if it can be created
2409 aFile.Build(OSD_WriteOnly, OSD_Protection());
2410 if (aFile.Failed()) {
2411 TCollection_AsciiString msg ("You cannot create the file ");
2412 msg += aFullName + ". Check the directory existance and access rights.";
2413 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2421 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2422 CORBA::Boolean auto_groups,
2423 SMESH::MED_VERSION theVersion,
2424 CORBA::Boolean overwrite)
2425 throw(SALOME::SALOME_Exception)
2427 Unexpect aCatch(SALOME_SalomeException);
2430 PrepareForWriting(file, overwrite);
2431 const char* aMeshName = "Mesh";
2432 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2433 if ( !aStudy->_is_nil() ) {
2434 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2435 if ( !aMeshSO->_is_nil() ) {
2436 aMeshName = aMeshSO->GetName();
2437 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2438 if ( !aStudy->GetProperties()->IsLocked() )
2440 SALOMEDS::GenericAttribute_var anAttr;
2441 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2442 SALOMEDS::AttributeExternalFileDef_var aFileName;
2443 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2444 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2445 ASSERT(!aFileName->_is_nil());
2446 aFileName->SetValue(file);
2447 SALOMEDS::AttributeFileType_var aFileType;
2448 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2449 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2450 ASSERT(!aFileType->_is_nil());
2451 aFileType->SetValue("FICHIERMED");
2455 // Update Python script
2456 // set name of mesh before export
2457 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2459 // check names of groups
2462 TPythonDump() << _this() << ".ExportToMEDX( r'"
2463 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2465 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2468 void SMESH_Mesh_i::ExportToMED (const char* file,
2469 CORBA::Boolean auto_groups,
2470 SMESH::MED_VERSION theVersion)
2471 throw(SALOME::SALOME_Exception)
2473 ExportToMEDX(file,auto_groups,theVersion,true);
2476 void SMESH_Mesh_i::ExportMED (const char* file,
2477 CORBA::Boolean auto_groups)
2478 throw(SALOME::SALOME_Exception)
2480 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2483 void SMESH_Mesh_i::ExportDAT (const char *file)
2484 throw(SALOME::SALOME_Exception)
2486 Unexpect aCatch(SALOME_SalomeException);
2488 // Update Python script
2489 // check names of groups
2491 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2494 PrepareForWriting(file);
2495 _impl->ExportDAT(file);
2498 void SMESH_Mesh_i::ExportUNV (const char *file)
2499 throw(SALOME::SALOME_Exception)
2501 Unexpect aCatch(SALOME_SalomeException);
2503 // Update Python script
2504 // check names of groups
2506 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2509 PrepareForWriting(file);
2510 _impl->ExportUNV(file);
2513 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2514 throw(SALOME::SALOME_Exception)
2516 Unexpect aCatch(SALOME_SalomeException);
2518 // Update Python script
2519 // check names of groups
2521 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2524 PrepareForWriting(file);
2525 _impl->ExportSTL(file, isascii);
2528 //=============================================================================
2532 //=============================================================================
2534 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2536 Unexpect aCatch(SALOME_SalomeException);
2537 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2538 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2539 return aMesh._retn();
2542 //=============================================================================
2546 //=============================================================================
2547 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2549 Unexpect aCatch(SALOME_SalomeException);
2550 return _impl->NbNodes();
2553 //=============================================================================
2557 //=============================================================================
2558 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2560 Unexpect aCatch(SALOME_SalomeException);
2561 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2564 //=============================================================================
2568 //=============================================================================
2569 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2571 Unexpect aCatch(SALOME_SalomeException);
2572 return _impl->Nb0DElements();
2575 //=============================================================================
2579 //=============================================================================
2580 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2582 Unexpect aCatch(SALOME_SalomeException);
2583 return _impl->NbEdges();
2586 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2587 throw(SALOME::SALOME_Exception)
2589 Unexpect aCatch(SALOME_SalomeException);
2590 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2593 //=============================================================================
2597 //=============================================================================
2598 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2600 Unexpect aCatch(SALOME_SalomeException);
2601 return _impl->NbFaces();
2604 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2606 Unexpect aCatch(SALOME_SalomeException);
2607 return _impl->NbTriangles();
2610 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2612 Unexpect aCatch(SALOME_SalomeException);
2613 return _impl->NbQuadrangles();
2616 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2618 Unexpect aCatch(SALOME_SalomeException);
2619 return _impl->NbPolygons();
2622 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2623 throw(SALOME::SALOME_Exception)
2625 Unexpect aCatch(SALOME_SalomeException);
2626 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2629 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2630 throw(SALOME::SALOME_Exception)
2632 Unexpect aCatch(SALOME_SalomeException);
2633 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2636 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2637 throw(SALOME::SALOME_Exception)
2639 Unexpect aCatch(SALOME_SalomeException);
2640 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2643 //=============================================================================
2647 //=============================================================================
2648 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2650 Unexpect aCatch(SALOME_SalomeException);
2651 return _impl->NbVolumes();
2654 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2656 Unexpect aCatch(SALOME_SalomeException);
2657 return _impl->NbTetras();
2660 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2662 Unexpect aCatch(SALOME_SalomeException);
2663 return _impl->NbHexas();
2666 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2668 Unexpect aCatch(SALOME_SalomeException);
2669 return _impl->NbPyramids();
2672 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2674 Unexpect aCatch(SALOME_SalomeException);
2675 return _impl->NbPrisms();
2678 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2680 Unexpect aCatch(SALOME_SalomeException);
2681 return _impl->NbPolyhedrons();
2684 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2685 throw(SALOME::SALOME_Exception)
2687 Unexpect aCatch(SALOME_SalomeException);
2688 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2691 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2692 throw(SALOME::SALOME_Exception)
2694 Unexpect aCatch(SALOME_SalomeException);
2695 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2698 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2699 throw(SALOME::SALOME_Exception)
2701 Unexpect aCatch(SALOME_SalomeException);
2702 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2705 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2706 throw(SALOME::SALOME_Exception)
2708 Unexpect aCatch(SALOME_SalomeException);
2709 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2712 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2713 throw(SALOME::SALOME_Exception)
2715 Unexpect aCatch(SALOME_SalomeException);
2716 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2719 //=============================================================================
2723 //=============================================================================
2724 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2726 Unexpect aCatch(SALOME_SalomeException);
2727 return _mapSubMesh_i.size();
2730 //=============================================================================
2734 //=============================================================================
2735 char* SMESH_Mesh_i::Dump()
2739 return CORBA::string_dup( os.str().c_str() );
2742 //=============================================================================
2746 //=============================================================================
2747 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2749 // SMESH::long_array_var aResult = new SMESH::long_array();
2750 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2751 // int aMinId = aSMESHDS_Mesh->MinElementID();
2752 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2754 // aResult->length(aMaxId - aMinId + 1);
2756 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2757 // aResult[i++] = id;
2759 // return aResult._retn();
2761 return GetElementsId();
2764 //=============================================================================
2768 //=============================================================================
2770 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2771 throw (SALOME::SALOME_Exception)
2773 Unexpect aCatch(SALOME_SalomeException);
2774 MESSAGE("SMESH_Mesh_i::GetElementsId");
2775 SMESH::long_array_var aResult = new SMESH::long_array();
2776 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2778 if ( aSMESHDS_Mesh == NULL )
2779 return aResult._retn();
2781 long nbElements = NbElements();
2782 aResult->length( nbElements );
2783 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2784 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2785 aResult[i] = anIt->next()->GetID();
2787 return aResult._retn();
2791 //=============================================================================
2795 //=============================================================================
2797 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2798 throw (SALOME::SALOME_Exception)
2800 Unexpect aCatch(SALOME_SalomeException);
2801 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2802 SMESH::long_array_var aResult = new SMESH::long_array();
2803 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2805 if ( aSMESHDS_Mesh == NULL )
2806 return aResult._retn();
2808 long nbElements = NbElements();
2810 // No sense in returning ids of elements along with ids of nodes:
2811 // when theElemType == SMESH::ALL, return node ids only if
2812 // there are no elements
2813 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2814 return GetNodesId();
2816 aResult->length( nbElements );
2820 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2821 while ( i < nbElements && anIt->more() ) {
2822 const SMDS_MeshElement* anElem = anIt->next();
2823 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2824 aResult[i++] = anElem->GetID();
2827 aResult->length( i );
2829 return aResult._retn();
2832 //=============================================================================
2836 //=============================================================================
2838 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2839 throw (SALOME::SALOME_Exception)
2841 Unexpect aCatch(SALOME_SalomeException);
2842 MESSAGE("SMESH_subMesh_i::GetNodesId");
2843 SMESH::long_array_var aResult = new SMESH::long_array();
2844 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2846 if ( aSMESHDS_Mesh == NULL )
2847 return aResult._retn();
2849 long nbNodes = NbNodes();
2850 aResult->length( nbNodes );
2851 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
2852 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2853 aResult[i] = anIt->next()->GetID();
2855 return aResult._retn();
2858 //=============================================================================
2862 //=============================================================================
2864 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2865 throw (SALOME::SALOME_Exception)
2867 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2870 //=============================================================================
2874 //=============================================================================
2876 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2877 throw (SALOME::SALOME_Exception)
2879 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2881 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2883 return ( SMESH::EntityType ) e->GetEntityType();
2886 //=============================================================================
2888 * Returns ID of elements for given submesh
2890 //=============================================================================
2891 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2892 throw (SALOME::SALOME_Exception)
2894 SMESH::long_array_var aResult = new SMESH::long_array();
2896 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2897 if(!SM) return aResult._retn();
2899 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2900 if(!SDSM) return aResult._retn();
2902 aResult->length(SDSM->NbElements());
2904 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2906 while ( eIt->more() ) {
2907 aResult[i++] = eIt->next()->GetID();
2910 return aResult._retn();
2914 //=============================================================================
2916 * Returns ID of nodes for given submesh
2917 * If param all==true - returns all nodes, else -
2918 * returns only nodes on shapes.
2920 //=============================================================================
2921 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2922 throw (SALOME::SALOME_Exception)
2924 SMESH::long_array_var aResult = new SMESH::long_array();
2926 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2927 if(!SM) return aResult._retn();
2929 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2930 if(!SDSM) return aResult._retn();
2933 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2934 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2935 while ( nIt->more() ) {
2936 const SMDS_MeshNode* elem = nIt->next();
2937 theElems.insert( elem->GetID() );
2940 else { // all nodes of submesh elements
2941 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2942 while ( eIt->more() ) {
2943 const SMDS_MeshElement* anElem = eIt->next();
2944 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2945 while ( nIt->more() ) {
2946 const SMDS_MeshElement* elem = nIt->next();
2947 theElems.insert( elem->GetID() );
2952 aResult->length(theElems.size());
2953 set<int>::iterator itElem;
2955 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2956 aResult[i++] = *itElem;
2958 return aResult._retn();
2962 //=============================================================================
2964 * Returns type of elements for given submesh
2966 //=============================================================================
2967 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2968 throw (SALOME::SALOME_Exception)
2970 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2971 if(!SM) return SMESH::ALL;
2973 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2974 if(!SDSM) return SMESH::ALL;
2976 if(SDSM->NbElements()==0)
2977 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2979 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2980 const SMDS_MeshElement* anElem = eIt->next();
2981 return ( SMESH::ElementType ) anElem->GetType();
2985 //=============================================================================
2989 //=============================================================================
2991 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2993 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2995 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3000 //=============================================================================
3002 * Get XYZ coordinates of node as list of double
3003 * If there is not node for given ID - returns empty list
3005 //=============================================================================
3007 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3009 SMESH::double_array_var aResult = new SMESH::double_array();
3010 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3011 if ( aSMESHDS_Mesh == NULL )
3012 return aResult._retn();
3015 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3017 return aResult._retn();
3021 aResult[0] = aNode->X();
3022 aResult[1] = aNode->Y();
3023 aResult[2] = aNode->Z();
3024 return aResult._retn();
3028 //=============================================================================
3030 * For given node returns list of IDs of inverse elements
3031 * If there is not node for given ID - returns empty list
3033 //=============================================================================
3035 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3037 SMESH::long_array_var aResult = new SMESH::long_array();
3038 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3039 if ( aSMESHDS_Mesh == NULL )
3040 return aResult._retn();
3043 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3045 return aResult._retn();
3047 // find inverse elements
3048 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3049 TColStd_SequenceOfInteger IDs;
3050 while(eIt->more()) {
3051 const SMDS_MeshElement* elem = eIt->next();
3052 IDs.Append(elem->GetID());
3054 if(IDs.Length()>0) {
3055 aResult->length(IDs.Length());
3057 for(; i<=IDs.Length(); i++) {
3058 aResult[i-1] = IDs.Value(i);
3061 return aResult._retn();
3064 //=============================================================================
3066 * \brief Return position of a node on shape
3068 //=============================================================================
3070 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3072 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3073 aNodePosition->shapeID = 0;
3074 aNodePosition->shapeType = GEOM::SHAPE;
3076 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3077 if ( !mesh ) return aNodePosition;
3079 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3081 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3083 aNodePosition->shapeID = aNode->getshapeId();
3084 switch ( pos->GetTypeOfPosition() ) {
3086 aNodePosition->shapeType = GEOM::EDGE;
3087 aNodePosition->params.length(1);
3088 aNodePosition->params[0] =
3089 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3092 aNodePosition->shapeType = GEOM::FACE;
3093 aNodePosition->params.length(2);
3094 aNodePosition->params[0] =
3095 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3096 aNodePosition->params[1] =
3097 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3099 case SMDS_TOP_VERTEX:
3100 aNodePosition->shapeType = GEOM::VERTEX;
3102 case SMDS_TOP_3DSPACE:
3103 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3104 aNodePosition->shapeType = GEOM::SOLID;
3105 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3106 aNodePosition->shapeType = GEOM::SHELL;
3112 return aNodePosition;
3115 //=============================================================================
3117 * If given element is node returns IDs of shape from position
3118 * If there is not node for given ID - returns -1
3120 //=============================================================================
3122 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3124 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3125 if ( aSMESHDS_Mesh == NULL )
3129 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3131 return aNode->getshapeId();
3138 //=============================================================================
3140 * For given element returns ID of result shape after
3141 * ::FindShape() from SMESH_MeshEditor
3142 * If there is not element for given ID - returns -1
3144 //=============================================================================
3146 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3148 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3149 if ( aSMESHDS_Mesh == NULL )
3152 // try to find element
3153 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3157 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3158 ::SMESH_MeshEditor aMeshEditor(_impl);
3159 int index = aMeshEditor.FindShape( elem );
3167 //=============================================================================
3169 * Returns number of nodes for given element
3170 * If there is not element for given ID - returns -1
3172 //=============================================================================
3174 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3176 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3177 if ( aSMESHDS_Mesh == NULL ) return -1;
3178 // try to find element
3179 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3180 if(!elem) return -1;
3181 return elem->NbNodes();
3185 //=============================================================================
3187 * Returns ID of node by given index for given element
3188 * If there is not element for given ID - returns -1
3189 * If there is not node for given index - returns -2
3191 //=============================================================================
3193 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3195 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3196 if ( aSMESHDS_Mesh == NULL ) return -1;
3197 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3198 if(!elem) return -1;
3199 if( index>=elem->NbNodes() || index<0 ) return -1;
3200 return elem->GetNode(index)->GetID();
3203 //=============================================================================
3205 * Returns IDs of nodes of given element
3207 //=============================================================================
3209 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3211 SMESH::long_array_var aResult = new SMESH::long_array();
3212 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3214 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3216 aResult->length( elem->NbNodes() );
3217 for ( int i = 0; i < elem->NbNodes(); ++i )
3218 aResult[ i ] = elem->GetNode( i )->GetID();
3221 return aResult._retn();
3224 //=============================================================================
3226 * Returns true if given node is medium node
3227 * in given quadratic element
3229 //=============================================================================
3231 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3233 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3234 if ( aSMESHDS_Mesh == NULL ) return false;
3236 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3237 if(!aNode) return false;
3238 // try to find element
3239 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3240 if(!elem) return false;
3242 return elem->IsMediumNode(aNode);
3246 //=============================================================================
3248 * Returns true if given node is medium node
3249 * in one of quadratic elements
3251 //=============================================================================
3253 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3254 SMESH::ElementType theElemType)
3256 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3257 if ( aSMESHDS_Mesh == NULL ) return false;
3260 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3261 if(!aNode) return false;
3263 SMESH_MesherHelper aHelper( *(_impl) );
3265 SMDSAbs_ElementType aType;
3266 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3267 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3268 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3269 else aType = SMDSAbs_All;
3271 return aHelper.IsMedium(aNode,aType);
3275 //=============================================================================
3277 * Returns number of edges for given element
3279 //=============================================================================
3281 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3283 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3284 if ( aSMESHDS_Mesh == NULL ) return -1;
3285 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3286 if(!elem) return -1;
3287 return elem->NbEdges();
3291 //=============================================================================
3293 * Returns number of faces for given element
3295 //=============================================================================
3297 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3299 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3300 if ( aSMESHDS_Mesh == NULL ) return -1;
3301 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3302 if(!elem) return -1;
3303 return elem->NbFaces();
3306 //=======================================================================
3307 //function : GetElemFaceNodes
3308 //purpose : Returns nodes of given face (counted from zero) for given element.
3309 //=======================================================================
3311 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3312 CORBA::Short faceIndex)
3314 SMESH::long_array_var aResult = new SMESH::long_array();
3315 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3317 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3319 SMDS_VolumeTool vtool( elem );
3320 if ( faceIndex < vtool.NbFaces() )
3322 aResult->length( vtool.NbFaceNodes( faceIndex ));
3323 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3324 for ( int i = 0; i < aResult->length(); ++i )
3325 aResult[ i ] = nn[ i ]->GetID();
3329 return aResult._retn();
3332 //=======================================================================
3333 //function : FindElementByNodes
3334 //purpose : Returns an element based on all given nodes.
3335 //=======================================================================
3337 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3339 CORBA::Long elemID(0);
3340 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3342 vector< const SMDS_MeshNode * > nn( nodes.length() );
3343 for ( int i = 0; i < nodes.length(); ++i )
3344 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3347 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3348 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3349 _impl->NbFaces( ORDER_QUADRATIC ) ||
3350 _impl->NbVolumes( ORDER_QUADRATIC )))
3351 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3353 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3358 //=============================================================================
3360 * Returns true if given element is polygon
3362 //=============================================================================
3364 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3366 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3367 if ( aSMESHDS_Mesh == NULL ) return false;
3368 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3369 if(!elem) return false;
3370 return elem->IsPoly();
3374 //=============================================================================
3376 * Returns true if given element is quadratic
3378 //=============================================================================
3380 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3382 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3383 if ( aSMESHDS_Mesh == NULL ) return false;
3384 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3385 if(!elem) return false;
3386 return elem->IsQuadratic();
3390 //=============================================================================
3392 * Returns bary center for given element
3394 //=============================================================================
3396 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3398 SMESH::double_array_var aResult = new SMESH::double_array();
3399 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3400 if ( aSMESHDS_Mesh == NULL )
3401 return aResult._retn();
3403 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3405 return aResult._retn();
3407 if(elem->GetType()==SMDSAbs_Volume) {
3408 SMDS_VolumeTool aTool;
3409 if(aTool.Set(elem)) {
3411 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3416 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3418 double x=0., y=0., z=0.;
3419 for(; anIt->more(); ) {
3421 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3435 return aResult._retn();
3439 //=============================================================================
3441 * Create and publish group servants if any groups were imported or created anyhow
3443 //=============================================================================
3445 void SMESH_Mesh_i::CreateGroupServants()
3447 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3450 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3451 while ( groupIt->more() )
3453 ::SMESH_Group* group = groupIt->next();
3454 int anId = group->GetGroupDS()->GetID();
3456 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3457 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3459 addedIDs.insert( anId );
3461 SMESH_GroupBase_i* aGroupImpl;
3463 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3464 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3466 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3467 shape = groupOnGeom->GetShape();
3470 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3473 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3474 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3475 aGroupImpl->Register();
3477 SMESH::SMESH_GroupBase_var groupVar =
3478 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3479 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3481 // register CORBA object for persistence
3482 int nextId = _gen_i->RegisterObject( groupVar );
3483 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3485 // publishing the groups in the study
3486 if ( !aStudy->_is_nil() ) {
3487 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3488 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3491 if ( !addedIDs.empty() )
3494 set<int>::iterator id = addedIDs.begin();
3495 for ( ; id != addedIDs.end(); ++id )
3497 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3498 int i = std::distance( _mapGroups.begin(), it );
3499 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3504 //=============================================================================
3506 * \brief Return groups cantained in _mapGroups by their IDs
3508 //=============================================================================
3510 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3512 int nbGroups = groupIDs.size();
3513 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3514 aList->length( nbGroups );
3516 list<int>::const_iterator ids = groupIDs.begin();
3517 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3519 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3520 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3521 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3523 aList->length( nbGroups );
3524 return aList._retn();
3527 //=============================================================================
3529 * \brief Return information about imported file
3531 //=============================================================================
3533 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3535 SALOME_MED::MedFileInfo_var res( myFileInfo );
3536 if ( !res.operator->() ) {
3537 res = new SALOME_MED::MedFileInfo;
3539 res->fileSize = res->major = res->minor = res->release = -1;
3544 //=============================================================================
3546 * \brief Check and correct names of mesh groups
3548 //=============================================================================
3550 void SMESH_Mesh_i::checkGroupNames()
3552 int nbGrp = NbGroups();
3556 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3557 if ( aStudy->_is_nil() )
3558 return; // nothing to do
3560 SMESH::ListOfGroups* grpList = 0;
3561 // avoid dump of "GetGroups"
3563 // store python dump into a local variable inside local scope
3564 SMESH::TPythonDump pDump; // do not delete this line of code
3565 grpList = GetGroups();
3568 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3569 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3572 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3573 if ( aGrpSO->_is_nil() )
3575 // correct name of the mesh group if necessary
3576 const char* guiName = aGrpSO->GetName();
3577 if ( strcmp(guiName, aGrp->GetName()) )
3578 aGrp->SetName( guiName );
3582 //=============================================================================
3584 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3586 //=============================================================================
3587 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3589 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3590 CORBA::string_dup(theParameters));
3593 //=============================================================================
3595 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3597 //=============================================================================
3598 char* SMESH_Mesh_i::GetParameters()
3600 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3601 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3604 //=============================================================================
3606 * \brief Returns list of notebook variables used for last Mesh operation
3608 //=============================================================================
3609 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3611 SMESH::string_array_var aResult = new SMESH::string_array();
3612 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3614 char *aParameters = GetParameters();
3615 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3616 if(!aStudy->_is_nil()) {
3617 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3618 if(aSections->length() > 0) {
3619 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3620 aResult->length(aVars.length());
3621 for(int i = 0;i < aVars.length();i++)
3622 aResult[i] = CORBA::string_dup( aVars[i]);
3626 return aResult._retn();
3629 //=======================================================================
3630 //function : GetTypes
3631 //purpose : Returns types of elements it contains
3632 //=======================================================================
3634 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3636 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3640 if (_impl->NbEdges())
3641 types[nbTypes++] = SMESH::EDGE;
3642 if (_impl->NbFaces())
3643 types[nbTypes++] = SMESH::FACE;
3644 if (_impl->NbVolumes())
3645 types[nbTypes++] = SMESH::VOLUME;
3646 if (_impl->Nb0DElements())
3647 types[nbTypes++] = SMESH::ELEM0D;
3648 types->length( nbTypes );
3650 return types._retn();
3653 //=======================================================================
3654 //function : GetMesh
3655 //purpose : Returns self
3656 //=======================================================================
3658 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3660 return SMESH::SMESH_Mesh::_duplicate( _this() );
3663 //=============================================================================
3665 * \brief Returns statistic of mesh elements
3667 //=============================================================================
3668 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3670 SMESH::long_array_var aRes = new SMESH::long_array();
3671 aRes->length(SMESH::Entity_Last);
3672 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3674 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3676 return aRes._retn();
3677 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3678 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3679 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3680 return aRes._retn();
3683 //=============================================================================
3685 * \brief Collect statistic of mesh elements given by iterator
3687 //=============================================================================
3688 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3689 SMESH::long_array& theInfo)
3691 if (!theItr) return;
3692 while (theItr->more())
3693 theInfo[ theItr->next()->GetEntityType() ]++;
3696 //=============================================================================
3698 * \brief mapping of mesh dimension into shape type
3700 //=============================================================================
3701 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3703 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3705 case 0: aType = TopAbs_VERTEX; break;
3706 case 1: aType = TopAbs_EDGE; break;
3707 case 2: aType = TopAbs_FACE; break;
3709 default:aType = TopAbs_SOLID; break;
3714 //=============================================================================
3716 * \brief Internal structure used to find concurent submeshes
3718 * It represents a pair < submesh, concurent dimension >, where
3719 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3720 * with another submesh. In other words, it is dimension of a hypothesis assigned
3723 //=============================================================================
3729 int _dim; //!< a dimension the algo can build (concurrent dimension)
3730 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3731 TopTools_MapOfShape _shapeMap;
3732 SMESH_subMesh* _subMesh;
3733 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3736 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3738 const TopoDS_Shape& theShape)
3740 _subMesh = (SMESH_subMesh*)theSubMesh;
3741 SetShape( theDim, theShape );
3745 void SetShape(const int theDim,
3746 const TopoDS_Shape& theShape)
3749 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3750 if (_dim >= _ownDim)
3751 _shapeMap.Add( theShape );
3753 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3754 for( ; anExp.More(); anExp.Next() )
3755 _shapeMap.Add( anExp.Current() );
3759 //! Check sharing of sub shapes
3760 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3761 const TopTools_MapOfShape& theToFind,
3762 const TopAbs_ShapeEnum theType)
3764 bool isShared = false;
3765 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3766 for (; !isShared && anItr.More(); anItr.Next() ) {
3767 const TopoDS_Shape aSubSh = anItr.Key();
3768 // check for case when concurrent dimensions are same
3769 isShared = theToFind.Contains( aSubSh );
3770 // check for subshape with concurrent dimension
3771 TopExp_Explorer anExp( aSubSh, theType );
3772 for ( ; !isShared && anExp.More(); anExp.Next() )
3773 isShared = theToFind.Contains( anExp.Current() );
3778 //! check algorithms
3779 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3780 const SMESHDS_Hypothesis* theA2)
3782 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3783 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3784 return false; // one of the hypothesis is not algorithm
3785 // check algorithm names (should be equal)
3786 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3790 //! Check if subshape hypotheses are concurrent
3791 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3793 if ( _subMesh == theOther->_subMesh )
3794 return false; // same subshape - should not be
3796 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3797 // any of the two submeshes is not on COMPOUND shape )
3798 // -> no concurrency
3799 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3800 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3801 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3804 // bool checkSubShape = ( _dim >= theOther->_dim )
3805 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3806 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3807 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3808 if ( !checkSubShape )
3811 // check algorithms to be same
3812 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3813 return true; // different algorithms
3815 // check hypothesises for concurrence (skip first as algorithm)
3817 // pointers should be same, becase it is referenes from mesh hypothesis partition
3818 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3819 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3820 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3821 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3823 // the submeshes are concurrent if their algorithms has different parameters
3824 return nbSame != theOther->_hypothesises.size() - 1;
3827 }; // end of SMESH_DimHyp
3829 typedef list<SMESH_DimHyp*> TDimHypList;
3831 static void addDimHypInstance(const int theDim,
3832 const TopoDS_Shape& theShape,
3833 const SMESH_Algo* theAlgo,
3834 const SMESH_subMesh* theSubMesh,
3835 const list <const SMESHDS_Hypothesis*>& theHypList,
3836 TDimHypList* theDimHypListArr )
3838 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3839 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3840 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3841 listOfdimHyp.push_back( dimHyp );
3844 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3845 dimHyp->_hypothesises.push_front(theAlgo);
3846 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3847 for( ; hypIt != theHypList.end(); hypIt++ )
3848 dimHyp->_hypothesises.push_back( *hypIt );
3851 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3852 const TDimHypList& theListOfDimHyp,
3853 TListOfInt& theListOfConcurr )
3855 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3856 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3857 const SMESH_DimHyp* curDimHyp = *rIt;
3858 if ( curDimHyp == theDimHyp )
3859 break; // meet own dimHyp pointer in same dimension
3860 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3861 if ( find( theListOfConcurr.begin(),
3862 theListOfConcurr.end(),
3863 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3864 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3868 static void unionLists(TListOfInt& theListOfId,
3869 TListOfListOfInt& theListOfListOfId,
3872 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3873 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3875 continue; //skip already treated lists
3876 // check if other list has any same submesh object
3877 TListOfInt& otherListOfId = *it;
3878 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3879 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3882 // union two lists (from source into target)
3883 TListOfInt::iterator it2 = otherListOfId.begin();
3884 for ( ; it2 != otherListOfId.end(); it2++ ) {
3885 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3886 theListOfId.push_back(*it2);
3888 // clear source list
3889 otherListOfId.clear();
3893 //! free memory allocated for dimension-hypothesis objects
3894 static void removeDimHyps( TDimHypList* theArrOfList )
3896 for (int i = 0; i < 4; i++ ) {
3897 TDimHypList& listOfdimHyp = theArrOfList[i];
3898 TDimHypList::const_iterator it = listOfdimHyp.begin();
3899 for ( ; it != listOfdimHyp.end(); it++ )
3904 //=============================================================================
3906 * \brief Return submesh objects list in meshing order
3908 //=============================================================================
3910 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3912 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3914 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3916 return aResult._retn();
3918 ::SMESH_Mesh& mesh = GetImpl();
3919 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3920 if ( !anOrder.size() ) {
3922 // collect submeshes detecting concurrent algorithms and hypothesises
3923 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3925 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3926 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3927 ::SMESH_subMesh* sm = (*i_sm).second;
3929 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3931 // list of assigned hypothesises
3932 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3933 // Find out dimensions where the submesh can be concurrent.
3934 // We define the dimensions by algo of each of hypotheses in hypList
3935 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3936 for( ; hypIt != hypList.end(); hypIt++ ) {
3937 SMESH_Algo* anAlgo = 0;
3938 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3939 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3940 // hyp it-self is algo
3941 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3943 // try to find algorithm with help of subshapes
3944 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3945 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3946 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3949 continue; // no assigned algorithm to current submesh
3951 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3952 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3954 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3955 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3956 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3958 } // end iterations on submesh
3960 // iterate on created dimension-hypotheses and check for concurrents
3961 for ( int i = 0; i < 4; i++ ) {
3962 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3963 // check for concurrents in own and other dimensions (step-by-step)
3964 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3965 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3966 const SMESH_DimHyp* dimHyp = *dhIt;
3967 TListOfInt listOfConcurr;
3968 // looking for concurrents and collect into own list
3969 for ( int j = i; j < 4; j++ )
3970 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3971 // check if any concurrents found
3972 if ( listOfConcurr.size() > 0 ) {
3973 // add own submesh to list of concurrent
3974 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3975 anOrder.push_back( listOfConcurr );
3980 removeDimHyps(dimHypListArr);
3982 // now, minimise the number of concurrent groups
3983 // Here we assume that lists of submhes can has same submesh
3984 // in case of multi-dimension algorithms, as result
3985 // list with common submesh have to be union into one list
3987 TListOfListOfInt::iterator listIt = anOrder.begin();
3988 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3989 unionLists( *listIt, anOrder, listIndx + 1 );
3991 // convert submesh ids into interface instances
3992 // and dump command into python
3993 convertMeshOrder( anOrder, aResult, true );
3995 return aResult._retn();
3998 //=============================================================================
4000 * \brief find common submeshes with given submesh
4001 * \param theSubMeshList list of already collected submesh to check
4002 * \param theSubMesh given submesh to intersect with other
4003 * \param theCommonSubMeshes collected common submeshes
4005 //=============================================================================
4007 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4008 const SMESH_subMesh* theSubMesh,
4009 set<const SMESH_subMesh*>& theCommon )
4013 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4014 for ( ; it != theSubMeshList.end(); it++ )
4015 theSubMesh->FindIntersection( *it, theCommon );
4016 theSubMeshList.push_back( theSubMesh );
4017 //theCommon.insert( theSubMesh );
4020 //=============================================================================
4022 * \brief Set submesh object order
4023 * \param theSubMeshArray submesh array order
4025 //=============================================================================
4027 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4030 ::SMESH_Mesh& mesh = GetImpl();
4032 TPythonDump aPythonDump; // prevent dump of called methods
4033 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4035 TListOfListOfInt subMeshOrder;
4036 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4038 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4039 TListOfInt subMeshIds;
4040 aPythonDump << "[ ";
4041 // Collect subMeshes which should be clear
4042 // do it list-by-list, because modification of submesh order
4043 // take effect between concurrent submeshes only
4044 set<const SMESH_subMesh*> subMeshToClear;
4045 list<const SMESH_subMesh*> subMeshList;
4046 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4048 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4050 aPythonDump << ", ";
4051 aPythonDump << subMesh;
4052 subMeshIds.push_back( subMesh->GetId() );
4053 // detect common parts of submeshes
4054 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4055 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4057 aPythonDump << " ]";
4058 subMeshOrder.push_back( subMeshIds );
4060 // clear collected submeshes
4061 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4062 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4063 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4065 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4066 // ClearSubMesh( *clrIt );
4069 aPythonDump << " ])";
4071 mesh.SetMeshOrder( subMeshOrder );
4077 //=============================================================================
4079 * \brief Convert submesh ids into submesh interfaces
4081 //=============================================================================
4083 void SMESH_Mesh_i::convertMeshOrder
4084 (const TListOfListOfInt& theIdsOrder,
4085 SMESH::submesh_array_array& theResOrder,
4086 const bool theIsDump)
4088 int nbSet = theIdsOrder.size();
4089 TPythonDump aPythonDump; // prevent dump of called methods
4091 aPythonDump << "[ ";
4092 theResOrder.length(nbSet);
4093 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4095 for( ; it != theIdsOrder.end(); it++ ) {
4096 // translate submesh identificators into submesh objects
4097 // takeing into account real number of concurrent lists
4098 const TListOfInt& aSubOrder = (*it);
4099 if (!aSubOrder.size())
4102 aPythonDump << "[ ";
4103 // convert shape indeces into interfaces
4104 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4105 aResSubSet->length(aSubOrder.size());
4106 TListOfInt::const_iterator subIt = aSubOrder.begin();
4107 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4108 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4110 SMESH::SMESH_subMesh_var subMesh =
4111 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4114 aPythonDump << ", ";
4115 aPythonDump << subMesh;
4117 aResSubSet[ j++ ] = subMesh;
4120 aPythonDump << " ]";
4121 theResOrder[ listIndx++ ] = aResSubSet;
4123 // correct number of lists
4124 theResOrder.length( listIndx );
4127 // finilise python dump
4128 aPythonDump << " ]";
4129 aPythonDump << " = " << _this() << ".GetMeshOrder()";