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 NCollection_Map< 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.Add( 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.Extent() );
1046 NCollection_Map< int >::Iterator anIter( anIds );
1047 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1049 aResIds[ i ] = anIter.Value();
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 NCollection_Map< 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.Add( 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.Extent() );
1194 NCollection_Map< int >::Iterator aListIter( anIds );
1195 for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1197 aResIds[ i ] = aListIter.Value();
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 NCollection_Map< 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.Add( aCurrId );
1323 NCollection_Map< 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.Contains( aCurrId ) )
1348 anIds.Add( 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.Extent() );
1361 NCollection_Map< int >::Iterator anIter( anIds );
1362 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1364 aResIds[ i ] = anIter.Value();
1366 aResGrp->Add( aResIds );
1368 // Clear python lines, created by CreateGroup() and Add()
1369 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1370 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1371 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1373 // Update Python script
1375 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1376 << &theMainGroups << ", " << &theToolGroups << ", '"
1377 << theName << "' )";
1379 return aResGrp._retn();
1383 return SMESH::SMESH_Group::_nil();
1387 //=============================================================================
1389 \brief Create groups of entities from existing groups of superior dimensions
1391 1) extract all nodes from each group,
1392 2) combine all elements of specified dimension laying on these nodes.
1393 \param theGroups list of source groups
1394 \param theElemType dimension of elements
1395 \param theName name of new group
1396 \return pointer on new group
1398 //=============================================================================
1399 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1400 const SMESH::ListOfGroups& theGroups,
1401 SMESH::ElementType theElemType,
1402 const char* theName )
1403 throw (SALOME::SALOME_Exception)
1405 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1407 if ( !theName || !aMeshDS )
1408 return SMESH::SMESH_Group::_nil();
1410 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1414 // Create map of nodes from all groups
1416 NCollection_Map< int > aNodeMap;
1418 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1420 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1421 if ( CORBA::is_nil( aGrp ) )
1424 SMESH::ElementType aType = aGrp->GetType();
1425 if ( aType == SMESH::ALL )
1427 else if ( aType == SMESH::NODE )
1429 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1430 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1432 int aCurrId = aCurrIds[ i ];
1433 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1435 aNodeMap.Add( aNode->GetID() );
1440 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1441 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1443 int aCurrId = aCurrIds[ i ];
1444 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1447 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1448 while( aNodeIter->more() )
1450 const SMDS_MeshNode* aNode =
1451 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1453 aNodeMap.Add( aNode->GetID() );
1459 // Get result identifiers
1461 NCollection_Map< int > aResultIds;
1462 if ( theElemType == SMESH::NODE )
1464 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1465 for ( ; aNodeIter.More(); aNodeIter.Next() )
1466 aResultIds.Add( aNodeIter.Value() );
1470 // Create list of elements of given dimension constructed on the nodes
1471 NCollection_Map< int > anElemList;
1472 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1473 for ( ; aNodeIter.More(); aNodeIter.Next() )
1475 const SMDS_MeshElement* aNode =
1476 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1480 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1481 while( anElemIter->more() )
1483 const SMDS_MeshElement* anElem =
1484 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1485 if ( anElem && anElem->GetType() == anElemType )
1486 anElemList.Add( anElem->GetID() );
1490 // check whether all nodes of elements are present in nodes map
1491 NCollection_Map< int >::Iterator anIter( anElemList );
1492 for ( ; anIter.More(); anIter.Next() )
1494 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1499 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1500 while( aNodeIter->more() )
1502 const SMDS_MeshNode* aNode =
1503 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1504 if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1511 aResultIds.Add( anElem->GetID() );
1517 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1518 if ( aResGrp->_is_nil() )
1519 return SMESH::SMESH_Group::_nil();
1521 // Create array of identifiers
1522 SMESH::long_array_var aResIds = new SMESH::long_array;
1523 aResIds->length( aResultIds.Extent() );
1525 NCollection_Map< int >::Iterator aResIter( aResultIds );
1526 for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1527 aResIds[ i ] = aResIter.Value();
1528 aResGrp->Add( aResIds );
1530 // Remove strings corresponding to group creation
1531 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1532 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1533 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1535 // Update Python script
1537 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1538 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1540 return aResGrp._retn();
1544 return SMESH::SMESH_Group::_nil();
1548 //================================================================================
1550 * \brief Remember GEOM group data
1552 //================================================================================
1554 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1555 CORBA::Object_ptr theSmeshObj)
1557 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1560 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1561 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1562 if ( groupSO->_is_nil() )
1565 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1566 GEOM::GEOM_IGroupOperations_var groupOp =
1567 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1568 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1571 _geomGroupData.push_back( TGeomGroupData() );
1572 TGeomGroupData & groupData = _geomGroupData.back();
1574 CORBA::String_var entry = groupSO->GetID();
1575 groupData._groupEntry = entry.in();
1577 for ( int i = 0; i < ids->length(); ++i )
1578 groupData._indices.insert( ids[i] );
1580 groupData._smeshObject = theSmeshObj;
1583 //================================================================================
1585 * Remove GEOM group data relating to removed smesh object
1587 //================================================================================
1589 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1591 list<TGeomGroupData>::iterator
1592 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1593 for ( ; data != dataEnd; ++data ) {
1594 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1595 _geomGroupData.erase( data );
1601 //================================================================================
1603 * \brief Return new group contents if it has been changed and update group data
1605 //================================================================================
1607 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1609 TopoDS_Shape newShape;
1612 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1613 if ( study->_is_nil() ) return newShape; // means "not changed"
1614 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1615 if ( !groupSO->_is_nil() )
1617 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1618 if ( CORBA::is_nil( groupObj )) return newShape;
1619 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1621 // get indices of group items
1622 set<int> curIndices;
1623 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1624 GEOM::GEOM_IGroupOperations_var groupOp =
1625 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1626 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1627 for ( int i = 0; i < ids->length(); ++i )
1628 curIndices.insert( ids[i] );
1630 if ( groupData._indices == curIndices )
1631 return newShape; // group not changed
1634 groupData._indices = curIndices;
1636 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1637 if ( !geomClient ) return newShape;
1638 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1639 geomClient->RemoveShapeFromBuffer( groupIOR );
1640 newShape = _gen_i->GeomObjectToShape( geomGroup );
1643 if ( newShape.IsNull() ) {
1644 // geom group becomes empty - return empty compound
1645 TopoDS_Compound compound;
1646 BRep_Builder().MakeCompound(compound);
1647 newShape = compound;
1653 //=============================================================================
1655 * \brief Storage of shape and index used in CheckGeomGroupModif()
1657 //=============================================================================
1658 struct TIndexedShape {
1660 TopoDS_Shape _shape;
1661 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1664 //=============================================================================
1666 * \brief Update objects depending on changed geom groups
1668 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1669 * issue 0020210: Update of a smesh group after modification of the associated geom group
1671 //=============================================================================
1673 void SMESH_Mesh_i::CheckGeomGroupModif()
1675 if ( !_impl->HasShapeToMesh() ) return;
1677 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1678 if ( study->_is_nil() ) return;
1680 CORBA::Long nbEntities = NbNodes() + NbElements();
1682 // Check if group contents changed
1684 typedef map< string, TopoDS_Shape > TEntry2Geom;
1685 TEntry2Geom newGroupContents;
1687 list<TGeomGroupData>::iterator
1688 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1689 for ( ; data != dataEnd; ++data )
1691 pair< TEntry2Geom::iterator, bool > it_new =
1692 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1693 bool processedGroup = !it_new.second;
1694 TopoDS_Shape& newShape = it_new.first->second;
1695 if ( !processedGroup )
1696 newShape = newGroupShape( *data );
1697 if ( newShape.IsNull() )
1698 continue; // no changes
1700 if ( processedGroup ) { // update group indices
1701 list<TGeomGroupData>::iterator data2 = data;
1702 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1703 data->_indices = data2->_indices;
1706 // Update SMESH objects according to new GEOM group contents
1708 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1709 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1711 int oldID = submesh->GetId();
1712 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1714 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1716 // update hypotheses
1717 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1718 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1719 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1721 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1722 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1724 // care of submeshes
1725 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1726 int newID = newSubmesh->GetId();
1727 if ( newID != oldID ) {
1728 _mapSubMesh [ newID ] = newSubmesh;
1729 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1730 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1731 _mapSubMesh. erase(oldID);
1732 _mapSubMesh_i. erase(oldID);
1733 _mapSubMeshIor.erase(oldID);
1734 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1739 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1740 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1741 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1743 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1745 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1746 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1747 ds->SetShape( newShape );
1752 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1753 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1755 // Remove groups and submeshes basing on removed sub-shapes
1757 TopTools_MapOfShape newShapeMap;
1758 TopoDS_Iterator shapeIt( newShape );
1759 for ( ; shapeIt.More(); shapeIt.Next() )
1760 newShapeMap.Add( shapeIt.Value() );
1762 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1763 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1765 if ( newShapeMap.Contains( shapeIt.Value() ))
1767 TopTools_IndexedMapOfShape oldShapeMap;
1768 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1769 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1771 const TopoDS_Shape& oldShape = oldShapeMap(i);
1772 int oldInd = meshDS->ShapeToIndex( oldShape );
1774 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1775 if ( i_smIor != _mapSubMeshIor.end() ) {
1776 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1779 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1780 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1782 // check if a group bases on oldInd shape
1783 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1784 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1785 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1786 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1788 RemoveGroup( i_grp->second ); // several groups can base on same shape
1789 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1794 // Reassign hypotheses and update groups after setting the new shape to mesh
1796 // collect anassigned hypotheses
1797 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1798 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1799 TShapeHypList assignedHyps;
1800 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1802 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1803 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1804 if ( !hyps.empty() ) {
1805 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1806 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1807 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1810 // collect shapes supporting groups
1811 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1812 TShapeTypeList groupData;
1813 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1814 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1815 for ( ; grIt != groups.end(); ++grIt )
1817 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1819 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1821 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1822 _impl->ShapeToMesh( newShape );
1824 // reassign hypotheses
1825 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1826 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1828 TIndexedShape& geom = indS_hyps->first;
1829 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1830 int oldID = geom._index;
1831 int newID = meshDS->ShapeToIndex( geom._shape );
1834 if ( oldID == 1 ) { // main shape
1836 geom._shape = newShape;
1838 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1839 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1840 // care of submeshes
1841 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1842 if ( newID != oldID ) {
1843 _mapSubMesh [ newID ] = newSubmesh;
1844 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1845 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1846 _mapSubMesh. erase(oldID);
1847 _mapSubMesh_i. erase(oldID);
1848 _mapSubMeshIor.erase(oldID);
1849 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1853 TShapeTypeList::iterator geomType = groupData.begin();
1854 for ( ; geomType != groupData.end(); ++geomType )
1856 const TIndexedShape& geom = geomType->first;
1857 int oldID = geom._index;
1858 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1861 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1862 CORBA::String_var name = groupSO->GetName();
1864 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1866 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1867 group_i->changeLocalId( newID );
1870 break; // everything has been updated
1873 } // loop on group data
1877 CORBA::Long newNbEntities = NbNodes() + NbElements();
1878 list< SALOMEDS::SObject_var > soToUpdateIcons;
1879 if ( newNbEntities != nbEntities )
1881 // Add all SObjects with icons
1882 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1884 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1885 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1886 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1888 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1889 i_gr != _mapGroups.end(); ++i_gr ) // groups
1890 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1893 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1894 for ( ; so != soToUpdateIcons.end(); ++so )
1895 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1898 //=============================================================================
1900 * \brief Create standalone group instead if group on geometry
1902 //=============================================================================
1904 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1906 SMESH::SMESH_Group_var aGroup;
1907 if ( theGroup->_is_nil() )
1908 return aGroup._retn();
1910 Unexpect aCatch(SALOME_SalomeException);
1912 SMESH_GroupBase_i* aGroupToRem =
1913 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1915 return aGroup._retn();
1917 int anId = aGroupToRem->GetLocalID();
1918 if ( !_impl->ConvertToStandalone( anId ) )
1919 return aGroup._retn();
1920 removeGeomGroupData( theGroup );
1922 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1924 // remove old instance of group from own map
1925 _mapGroups.erase( anId );
1927 SALOMEDS::StudyBuilder_var builder;
1928 SALOMEDS::SObject_var aGroupSO;
1929 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1930 if ( !aStudy->_is_nil() ) {
1931 builder = aStudy->NewBuilder();
1932 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1933 if ( !aGroupSO->_is_nil() ) {
1935 // remove reference to geometry
1936 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1937 for ( ; chItr->More(); chItr->Next() )
1938 // Remove group's child SObject
1939 builder->RemoveObject( chItr->Value() );
1941 // Update Python script
1942 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1943 << aGroupSO << " )";
1947 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1948 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1949 aGroupImpl->Register();
1950 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1952 // remember new group in own map
1953 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1954 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1956 // register CORBA object for persistence
1957 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1959 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1961 return aGroup._retn();
1964 //=============================================================================
1968 //=============================================================================
1970 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1972 if(MYDEBUG) MESSAGE( "createSubMesh" );
1973 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1975 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1976 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1977 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1978 SMESH::SMESH_subMesh_var subMesh
1979 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1981 _mapSubMesh[subMeshId] = mySubMesh;
1982 _mapSubMesh_i[subMeshId] = subMeshServant;
1983 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1985 // register CORBA object for persistence
1986 int nextId = _gen_i->RegisterObject( subMesh );
1987 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1989 // to track changes of GEOM groups
1990 addGeomGroupData( theSubShapeObject, subMesh );
1992 return subMesh._retn();
1995 //=======================================================================
1996 //function : getSubMesh
1998 //=======================================================================
2000 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2002 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2003 if ( it == _mapSubMeshIor.end() )
2004 return SMESH::SMESH_subMesh::_nil();
2006 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2010 //=============================================================================
2014 //=============================================================================
2016 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2017 GEOM::GEOM_Object_ptr theSubShapeObject )
2019 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2020 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2023 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2025 CORBA::Long shapeId = theSubMesh->GetId();
2026 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2028 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2031 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2032 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2033 for ( ; hyp != hyps.end(); ++hyp )
2034 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2041 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2042 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2043 removeHypothesis( theSubShapeObject, aHypList[i] );
2046 catch( const SALOME::SALOME_Exception& ) {
2047 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2049 removeGeomGroupData( theSubShapeObject );
2051 int subMeshId = theSubMesh->GetId();
2053 _mapSubMesh.erase(subMeshId);
2054 _mapSubMesh_i.erase(subMeshId);
2055 _mapSubMeshIor.erase(subMeshId);
2056 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2059 //=============================================================================
2063 //=============================================================================
2065 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2066 const char* theName,
2067 const TopoDS_Shape& theShape )
2070 SMESH::SMESH_GroupBase_var aGroup;
2071 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2072 SMESH_GroupBase_i* aGroupImpl;
2073 if ( !theShape.IsNull() )
2074 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2076 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2078 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2079 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2080 aGroupImpl->Register();
2081 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2083 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2084 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2086 // register CORBA object for persistence
2087 int nextId = _gen_i->RegisterObject( aGroup );
2088 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2090 // to track changes of GEOM groups
2091 if ( !theShape.IsNull() ) {
2092 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2093 addGeomGroupData( geom, aGroup );
2096 return aGroup._retn();
2099 //=============================================================================
2101 * SMESH_Mesh_i::removeGroup
2103 * Should be called by ~SMESH_Group_i()
2105 //=============================================================================
2107 void SMESH_Mesh_i::removeGroup( const int theId )
2109 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2110 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2111 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2112 _mapGroups.erase( theId );
2113 removeGeomGroupData( group );
2114 if (! _impl->RemoveGroup( theId ))
2116 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2117 RemoveGroup( group );
2122 //=============================================================================
2126 //=============================================================================
2128 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2129 throw(SALOME::SALOME_Exception)
2131 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2133 SMESH::log_array_var aLog;
2135 list < SMESHDS_Command * >logDS = _impl->GetLog();
2136 aLog = new SMESH::log_array;
2138 int lg = logDS.size();
2141 list < SMESHDS_Command * >::iterator its = logDS.begin();
2142 while(its != logDS.end()){
2143 SMESHDS_Command *com = *its;
2144 int comType = com->GetType();
2146 int lgcom = com->GetNumber();
2148 const list < int >&intList = com->GetIndexes();
2149 int inum = intList.size();
2151 list < int >::const_iterator ii = intList.begin();
2152 const list < double >&coordList = com->GetCoords();
2153 int rnum = coordList.size();
2155 list < double >::const_iterator ir = coordList.begin();
2156 aLog[indexLog].commandType = comType;
2157 aLog[indexLog].number = lgcom;
2158 aLog[indexLog].coords.length(rnum);
2159 aLog[indexLog].indexes.length(inum);
2160 for(int i = 0; i < rnum; i++){
2161 aLog[indexLog].coords[i] = *ir;
2162 //MESSAGE(" "<<i<<" "<<ir.Value());
2165 for(int i = 0; i < inum; i++){
2166 aLog[indexLog].indexes[i] = *ii;
2167 //MESSAGE(" "<<i<<" "<<ii.Value());
2176 catch(SALOME_Exception & S_ex){
2177 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2179 return aLog._retn();
2183 //=============================================================================
2187 //=============================================================================
2189 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2191 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2195 //=============================================================================
2199 //=============================================================================
2201 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2203 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2207 //=============================================================================
2211 //=============================================================================
2213 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2218 //=============================================================================
2221 //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
2222 // SMESH_Mesh::RemoveGroup() (issue 0020918)
2223 struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
2225 SMESH_Mesh_i* _mesh;
2226 TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2227 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2231 //=============================================================================
2235 //=============================================================================
2237 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2239 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2242 _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
2245 //=============================================================================
2249 //=============================================================================
2251 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2253 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2257 //=============================================================================
2259 * Return mesh editor
2261 //=============================================================================
2263 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2265 // Create MeshEditor
2266 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2267 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2269 // Update Python script
2270 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2272 return aMesh._retn();
2275 //=============================================================================
2277 * Return mesh edition previewer
2279 //=============================================================================
2281 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2283 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2284 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2285 return aMesh._retn();
2288 //================================================================================
2290 * \brief Return true if the mesh has been edited since a last total re-compute
2291 * and those modifications may prevent successful partial re-compute
2293 //================================================================================
2295 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2297 Unexpect aCatch(SALOME_SalomeException);
2298 return _impl->HasModificationsToDiscard();
2301 //=============================================================================
2305 //=============================================================================
2306 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2308 Unexpect aCatch(SALOME_SalomeException);
2309 _impl->SetAutoColor(theAutoColor);
2312 //=============================================================================
2316 //=============================================================================
2317 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2319 Unexpect aCatch(SALOME_SalomeException);
2320 return _impl->GetAutoColor();
2324 //=============================================================================
2326 * Export in different formats
2328 //=============================================================================
2330 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2332 return _impl->HasDuplicatedGroupNamesMED();
2335 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2337 TCollection_AsciiString aFullName ((char*)file);
2338 OSD_Path aPath (aFullName);
2339 OSD_File aFile (aPath);
2340 if (aFile.Exists()) {
2341 // existing filesystem node
2342 if (aFile.KindOfFile() == OSD_FILE) {
2343 if (aFile.IsWriteable()) {
2348 if (aFile.Failed()) {
2349 TCollection_AsciiString msg ("File ");
2350 msg += aFullName + " cannot be replaced.";
2351 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2354 TCollection_AsciiString msg ("File ");
2355 msg += aFullName + " cannot be overwritten.";
2356 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2359 TCollection_AsciiString msg ("Location ");
2360 msg += aFullName + " is not a file.";
2361 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2364 // nonexisting file; check if it can be created
2366 aFile.Build(OSD_WriteOnly, OSD_Protection());
2367 if (aFile.Failed()) {
2368 TCollection_AsciiString msg ("You cannot create the file ");
2369 msg += aFullName + ". Check the directory existance and access rights.";
2370 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2378 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2379 CORBA::Boolean auto_groups,
2380 SMESH::MED_VERSION theVersion,
2381 CORBA::Boolean overwrite)
2382 throw(SALOME::SALOME_Exception)
2384 Unexpect aCatch(SALOME_SalomeException);
2387 PrepareForWriting(file, overwrite);
2388 const char* aMeshName = "Mesh";
2389 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2390 if ( !aStudy->_is_nil() ) {
2391 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2392 if ( !aMeshSO->_is_nil() ) {
2393 aMeshName = aMeshSO->GetName();
2394 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2395 if ( !aStudy->GetProperties()->IsLocked() )
2397 SALOMEDS::GenericAttribute_var anAttr;
2398 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2399 SALOMEDS::AttributeExternalFileDef_var aFileName;
2400 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2401 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2402 ASSERT(!aFileName->_is_nil());
2403 aFileName->SetValue(file);
2404 SALOMEDS::AttributeFileType_var aFileType;
2405 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2406 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2407 ASSERT(!aFileType->_is_nil());
2408 aFileType->SetValue("FICHIERMED");
2412 // Update Python script
2413 // set name of mesh before export
2414 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2416 // check names of groups
2419 TPythonDump() << _this() << ".ExportToMEDX( r'"
2420 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2422 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2425 void SMESH_Mesh_i::ExportToMED (const char* file,
2426 CORBA::Boolean auto_groups,
2427 SMESH::MED_VERSION theVersion)
2428 throw(SALOME::SALOME_Exception)
2430 ExportToMEDX(file,auto_groups,theVersion,true);
2433 void SMESH_Mesh_i::ExportMED (const char* file,
2434 CORBA::Boolean auto_groups)
2435 throw(SALOME::SALOME_Exception)
2437 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2440 void SMESH_Mesh_i::ExportDAT (const char *file)
2441 throw(SALOME::SALOME_Exception)
2443 Unexpect aCatch(SALOME_SalomeException);
2445 // Update Python script
2446 // check names of groups
2448 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2451 PrepareForWriting(file);
2452 _impl->ExportDAT(file);
2455 void SMESH_Mesh_i::ExportUNV (const char *file)
2456 throw(SALOME::SALOME_Exception)
2458 Unexpect aCatch(SALOME_SalomeException);
2460 // Update Python script
2461 // check names of groups
2463 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2466 PrepareForWriting(file);
2467 _impl->ExportUNV(file);
2470 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2471 throw(SALOME::SALOME_Exception)
2473 Unexpect aCatch(SALOME_SalomeException);
2475 // Update Python script
2476 // check names of groups
2478 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2481 PrepareForWriting(file);
2482 _impl->ExportSTL(file, isascii);
2485 //=============================================================================
2489 //=============================================================================
2491 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2493 Unexpect aCatch(SALOME_SalomeException);
2494 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2495 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2496 return aMesh._retn();
2499 //=============================================================================
2503 //=============================================================================
2504 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2506 Unexpect aCatch(SALOME_SalomeException);
2507 return _impl->NbNodes();
2510 //=============================================================================
2514 //=============================================================================
2515 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2517 Unexpect aCatch(SALOME_SalomeException);
2518 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2521 //=============================================================================
2525 //=============================================================================
2526 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2528 Unexpect aCatch(SALOME_SalomeException);
2529 return _impl->Nb0DElements();
2532 //=============================================================================
2536 //=============================================================================
2537 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2539 Unexpect aCatch(SALOME_SalomeException);
2540 return _impl->NbEdges();
2543 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2544 throw(SALOME::SALOME_Exception)
2546 Unexpect aCatch(SALOME_SalomeException);
2547 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2550 //=============================================================================
2554 //=============================================================================
2555 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2557 Unexpect aCatch(SALOME_SalomeException);
2558 return _impl->NbFaces();
2561 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2563 Unexpect aCatch(SALOME_SalomeException);
2564 return _impl->NbTriangles();
2567 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2569 Unexpect aCatch(SALOME_SalomeException);
2570 return _impl->NbQuadrangles();
2573 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2575 Unexpect aCatch(SALOME_SalomeException);
2576 return _impl->NbPolygons();
2579 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2580 throw(SALOME::SALOME_Exception)
2582 Unexpect aCatch(SALOME_SalomeException);
2583 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2586 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2587 throw(SALOME::SALOME_Exception)
2589 Unexpect aCatch(SALOME_SalomeException);
2590 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2593 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2594 throw(SALOME::SALOME_Exception)
2596 Unexpect aCatch(SALOME_SalomeException);
2597 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2600 //=============================================================================
2604 //=============================================================================
2605 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2607 Unexpect aCatch(SALOME_SalomeException);
2608 return _impl->NbVolumes();
2611 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2613 Unexpect aCatch(SALOME_SalomeException);
2614 return _impl->NbTetras();
2617 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2619 Unexpect aCatch(SALOME_SalomeException);
2620 return _impl->NbHexas();
2623 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2625 Unexpect aCatch(SALOME_SalomeException);
2626 return _impl->NbPyramids();
2629 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2631 Unexpect aCatch(SALOME_SalomeException);
2632 return _impl->NbPrisms();
2635 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2637 Unexpect aCatch(SALOME_SalomeException);
2638 return _impl->NbPolyhedrons();
2641 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2642 throw(SALOME::SALOME_Exception)
2644 Unexpect aCatch(SALOME_SalomeException);
2645 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2648 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2649 throw(SALOME::SALOME_Exception)
2651 Unexpect aCatch(SALOME_SalomeException);
2652 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2655 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2656 throw(SALOME::SALOME_Exception)
2658 Unexpect aCatch(SALOME_SalomeException);
2659 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2662 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2663 throw(SALOME::SALOME_Exception)
2665 Unexpect aCatch(SALOME_SalomeException);
2666 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2669 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2670 throw(SALOME::SALOME_Exception)
2672 Unexpect aCatch(SALOME_SalomeException);
2673 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2676 //=============================================================================
2680 //=============================================================================
2681 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2683 Unexpect aCatch(SALOME_SalomeException);
2684 return _mapSubMesh_i.size();
2687 //=============================================================================
2691 //=============================================================================
2692 char* SMESH_Mesh_i::Dump()
2696 return CORBA::string_dup( os.str().c_str() );
2699 //=============================================================================
2703 //=============================================================================
2704 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2706 // SMESH::long_array_var aResult = new SMESH::long_array();
2707 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2708 // int aMinId = aSMESHDS_Mesh->MinElementID();
2709 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2711 // aResult->length(aMaxId - aMinId + 1);
2713 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2714 // aResult[i++] = id;
2716 // return aResult._retn();
2718 return GetElementsId();
2721 //=============================================================================
2725 //=============================================================================
2727 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2728 throw (SALOME::SALOME_Exception)
2730 Unexpect aCatch(SALOME_SalomeException);
2731 MESSAGE("SMESH_Mesh_i::GetElementsId");
2732 SMESH::long_array_var aResult = new SMESH::long_array();
2733 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2735 if ( aSMESHDS_Mesh == NULL )
2736 return aResult._retn();
2738 long nbElements = NbElements();
2739 aResult->length( nbElements );
2740 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2741 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2742 aResult[i] = anIt->next()->GetID();
2744 return aResult._retn();
2748 //=============================================================================
2752 //=============================================================================
2754 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2755 throw (SALOME::SALOME_Exception)
2757 Unexpect aCatch(SALOME_SalomeException);
2758 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2759 SMESH::long_array_var aResult = new SMESH::long_array();
2760 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2762 if ( aSMESHDS_Mesh == NULL )
2763 return aResult._retn();
2765 long nbElements = NbElements();
2767 // No sense in returning ids of elements along with ids of nodes:
2768 // when theElemType == SMESH::ALL, return node ids only if
2769 // there are no elements
2770 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2771 return GetNodesId();
2773 aResult->length( nbElements );
2777 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2778 while ( i < nbElements && anIt->more() ) {
2779 const SMDS_MeshElement* anElem = anIt->next();
2780 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2781 aResult[i++] = anElem->GetID();
2784 aResult->length( i );
2786 return aResult._retn();
2789 //=============================================================================
2793 //=============================================================================
2795 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2796 throw (SALOME::SALOME_Exception)
2798 Unexpect aCatch(SALOME_SalomeException);
2799 MESSAGE("SMESH_subMesh_i::GetNodesId");
2800 SMESH::long_array_var aResult = new SMESH::long_array();
2801 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2803 if ( aSMESHDS_Mesh == NULL )
2804 return aResult._retn();
2806 long nbNodes = NbNodes();
2807 aResult->length( nbNodes );
2808 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
2809 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2810 aResult[i] = anIt->next()->GetID();
2812 return aResult._retn();
2815 //=============================================================================
2819 //=============================================================================
2821 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2822 throw (SALOME::SALOME_Exception)
2824 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2827 //=============================================================================
2831 //=============================================================================
2833 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2834 throw (SALOME::SALOME_Exception)
2836 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2838 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2840 return ( SMESH::EntityType ) e->GetEntityType();
2843 //=============================================================================
2845 * Returns ID of elements for given submesh
2847 //=============================================================================
2848 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2849 throw (SALOME::SALOME_Exception)
2851 SMESH::long_array_var aResult = new SMESH::long_array();
2853 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2854 if(!SM) return aResult._retn();
2856 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2857 if(!SDSM) return aResult._retn();
2859 aResult->length(SDSM->NbElements());
2861 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2863 while ( eIt->more() ) {
2864 aResult[i++] = eIt->next()->GetID();
2867 return aResult._retn();
2871 //=============================================================================
2873 * Returns ID of nodes for given submesh
2874 * If param all==true - returns all nodes, else -
2875 * returns only nodes on shapes.
2877 //=============================================================================
2878 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2879 throw (SALOME::SALOME_Exception)
2881 SMESH::long_array_var aResult = new SMESH::long_array();
2883 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2884 if(!SM) return aResult._retn();
2886 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2887 if(!SDSM) return aResult._retn();
2890 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2891 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2892 while ( nIt->more() ) {
2893 const SMDS_MeshNode* elem = nIt->next();
2894 theElems.insert( elem->GetID() );
2897 else { // all nodes of submesh elements
2898 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2899 while ( eIt->more() ) {
2900 const SMDS_MeshElement* anElem = eIt->next();
2901 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2902 while ( nIt->more() ) {
2903 const SMDS_MeshElement* elem = nIt->next();
2904 theElems.insert( elem->GetID() );
2909 aResult->length(theElems.size());
2910 set<int>::iterator itElem;
2912 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2913 aResult[i++] = *itElem;
2915 return aResult._retn();
2919 //=============================================================================
2921 * Returns type of elements for given submesh
2923 //=============================================================================
2924 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2925 throw (SALOME::SALOME_Exception)
2927 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2928 if(!SM) return SMESH::ALL;
2930 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2931 if(!SDSM) return SMESH::ALL;
2933 if(SDSM->NbElements()==0)
2934 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2936 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2937 const SMDS_MeshElement* anElem = eIt->next();
2938 return ( SMESH::ElementType ) anElem->GetType();
2942 //=============================================================================
2946 //=============================================================================
2948 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2950 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2952 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2957 //=============================================================================
2959 * Get XYZ coordinates of node as list of double
2960 * If there is not node for given ID - returns empty list
2962 //=============================================================================
2964 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2966 SMESH::double_array_var aResult = new SMESH::double_array();
2967 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2968 if ( aSMESHDS_Mesh == NULL )
2969 return aResult._retn();
2972 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2974 return aResult._retn();
2978 aResult[0] = aNode->X();
2979 aResult[1] = aNode->Y();
2980 aResult[2] = aNode->Z();
2981 return aResult._retn();
2985 //=============================================================================
2987 * For given node returns list of IDs of inverse elements
2988 * If there is not node for given ID - returns empty list
2990 //=============================================================================
2992 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2994 SMESH::long_array_var aResult = new SMESH::long_array();
2995 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2996 if ( aSMESHDS_Mesh == NULL )
2997 return aResult._retn();
3000 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3002 return aResult._retn();
3004 // find inverse elements
3005 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3006 TColStd_SequenceOfInteger IDs;
3007 while(eIt->more()) {
3008 const SMDS_MeshElement* elem = eIt->next();
3009 IDs.Append(elem->GetID());
3011 if(IDs.Length()>0) {
3012 aResult->length(IDs.Length());
3014 for(; i<=IDs.Length(); i++) {
3015 aResult[i-1] = IDs.Value(i);
3018 return aResult._retn();
3021 //=============================================================================
3023 * \brief Return position of a node on shape
3025 //=============================================================================
3027 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3029 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3030 aNodePosition->shapeID = 0;
3031 aNodePosition->shapeType = GEOM::SHAPE;
3033 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3034 if ( !mesh ) return aNodePosition;
3036 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3038 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3040 aNodePosition->shapeID = pos->GetShapeId();
3041 switch ( pos->GetTypeOfPosition() ) {
3043 aNodePosition->shapeType = GEOM::EDGE;
3044 aNodePosition->params.length(1);
3045 aNodePosition->params[0] =
3046 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
3049 aNodePosition->shapeType = GEOM::FACE;
3050 aNodePosition->params.length(2);
3051 aNodePosition->params[0] =
3052 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
3053 aNodePosition->params[1] =
3054 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
3056 case SMDS_TOP_VERTEX:
3057 aNodePosition->shapeType = GEOM::VERTEX;
3059 case SMDS_TOP_3DSPACE:
3060 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3061 aNodePosition->shapeType = GEOM::SOLID;
3062 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3063 aNodePosition->shapeType = GEOM::SHELL;
3069 return aNodePosition;
3072 //=============================================================================
3074 * If given element is node returns IDs of shape from position
3075 * If there is not node for given ID - returns -1
3077 //=============================================================================
3079 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3081 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3082 if ( aSMESHDS_Mesh == NULL )
3086 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3088 SMDS_PositionPtr pos = aNode->GetPosition();
3092 return pos->GetShapeId();
3099 //=============================================================================
3101 * For given element returns ID of result shape after
3102 * ::FindShape() from SMESH_MeshEditor
3103 * If there is not element for given ID - returns -1
3105 //=============================================================================
3107 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3109 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3110 if ( aSMESHDS_Mesh == NULL )
3113 // try to find element
3114 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3118 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3119 ::SMESH_MeshEditor aMeshEditor(_impl);
3120 int index = aMeshEditor.FindShape( elem );
3128 //=============================================================================
3130 * Returns number of nodes for given element
3131 * If there is not element for given ID - returns -1
3133 //=============================================================================
3135 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3137 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3138 if ( aSMESHDS_Mesh == NULL ) return -1;
3139 // try to find element
3140 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3141 if(!elem) return -1;
3142 return elem->NbNodes();
3146 //=============================================================================
3148 * Returns ID of node by given index for given element
3149 * If there is not element for given ID - returns -1
3150 * If there is not node for given index - returns -2
3152 //=============================================================================
3154 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3156 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3157 if ( aSMESHDS_Mesh == NULL ) return -1;
3158 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3159 if(!elem) return -1;
3160 if( index>=elem->NbNodes() || index<0 ) return -1;
3161 return elem->GetNode(index)->GetID();
3164 //=============================================================================
3166 * Returns IDs of nodes of given element
3168 //=============================================================================
3170 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3172 SMESH::long_array_var aResult = new SMESH::long_array();
3173 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3175 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3177 aResult->length( elem->NbNodes() );
3178 for ( int i = 0; i < elem->NbNodes(); ++i )
3179 aResult[ i ] = elem->GetNode( i )->GetID();
3182 return aResult._retn();
3185 //=============================================================================
3187 * Returns true if given node is medium node
3188 * in given quadratic element
3190 //=============================================================================
3192 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3194 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3195 if ( aSMESHDS_Mesh == NULL ) return false;
3197 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3198 if(!aNode) return false;
3199 // try to find element
3200 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3201 if(!elem) return false;
3203 return elem->IsMediumNode(aNode);
3207 //=============================================================================
3209 * Returns true if given node is medium node
3210 * in one of quadratic elements
3212 //=============================================================================
3214 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3215 SMESH::ElementType theElemType)
3217 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3218 if ( aSMESHDS_Mesh == NULL ) return false;
3221 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3222 if(!aNode) return false;
3224 SMESH_MesherHelper aHelper( *(_impl) );
3226 SMDSAbs_ElementType aType;
3227 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3228 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3229 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3230 else aType = SMDSAbs_All;
3232 return aHelper.IsMedium(aNode,aType);
3236 //=============================================================================
3238 * Returns number of edges for given element
3240 //=============================================================================
3242 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3244 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3245 if ( aSMESHDS_Mesh == NULL ) return -1;
3246 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3247 if(!elem) return -1;
3248 return elem->NbEdges();
3252 //=============================================================================
3254 * Returns number of faces for given element
3256 //=============================================================================
3258 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3260 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3261 if ( aSMESHDS_Mesh == NULL ) return -1;
3262 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3263 if(!elem) return -1;
3264 return elem->NbFaces();
3267 //=======================================================================
3268 //function : GetElemFaceNodes
3269 //purpose : Returns nodes of given face (counted from zero) for given element.
3270 //=======================================================================
3272 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3273 CORBA::Short faceIndex)
3275 SMESH::long_array_var aResult = new SMESH::long_array();
3276 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3278 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3280 SMDS_VolumeTool vtool( elem );
3281 if ( faceIndex < vtool.NbFaces() )
3283 aResult->length( vtool.NbFaceNodes( faceIndex ));
3284 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3285 for ( int i = 0; i < aResult->length(); ++i )
3286 aResult[ i ] = nn[ i ]->GetID();
3290 return aResult._retn();
3293 //=======================================================================
3294 //function : FindElementByNodes
3295 //purpose : Returns an element based on all given nodes.
3296 //=======================================================================
3298 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3300 CORBA::Long elemID(0);
3301 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3303 vector< const SMDS_MeshNode * > nn( nodes.length() );
3304 for ( int i = 0; i < nodes.length(); ++i )
3305 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3308 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3309 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3310 _impl->NbFaces( ORDER_QUADRATIC ) ||
3311 _impl->NbVolumes( ORDER_QUADRATIC )))
3312 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3314 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3319 //=============================================================================
3321 * Returns true if given element is polygon
3323 //=============================================================================
3325 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3327 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3328 if ( aSMESHDS_Mesh == NULL ) return false;
3329 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3330 if(!elem) return false;
3331 return elem->IsPoly();
3335 //=============================================================================
3337 * Returns true if given element is quadratic
3339 //=============================================================================
3341 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3343 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3344 if ( aSMESHDS_Mesh == NULL ) return false;
3345 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3346 if(!elem) return false;
3347 return elem->IsQuadratic();
3351 //=============================================================================
3353 * Returns bary center for given element
3355 //=============================================================================
3357 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3359 SMESH::double_array_var aResult = new SMESH::double_array();
3360 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3361 if ( aSMESHDS_Mesh == NULL )
3362 return aResult._retn();
3364 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3366 return aResult._retn();
3368 if(elem->GetType()==SMDSAbs_Volume) {
3369 SMDS_VolumeTool aTool;
3370 if(aTool.Set(elem)) {
3372 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3377 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3379 double x=0., y=0., z=0.;
3380 for(; anIt->more(); ) {
3382 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3396 return aResult._retn();
3400 //=============================================================================
3402 * Create and publish group servants if any groups were imported or created anyhow
3404 //=============================================================================
3406 void SMESH_Mesh_i::CreateGroupServants()
3408 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3411 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3412 while ( groupIt->more() )
3414 ::SMESH_Group* group = groupIt->next();
3415 int anId = group->GetGroupDS()->GetID();
3417 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3418 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3420 addedIDs.insert( anId );
3422 SMESH_GroupBase_i* aGroupImpl;
3424 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3425 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3427 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3428 shape = groupOnGeom->GetShape();
3431 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3434 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3435 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3436 aGroupImpl->Register();
3438 SMESH::SMESH_GroupBase_var groupVar =
3439 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3440 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3442 // register CORBA object for persistence
3443 int nextId = _gen_i->RegisterObject( groupVar );
3444 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3446 // publishing the groups in the study
3447 if ( !aStudy->_is_nil() ) {
3448 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3449 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3452 if ( !addedIDs.empty() )
3455 set<int>::iterator id = addedIDs.begin();
3456 for ( ; id != addedIDs.end(); ++id )
3458 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3459 int i = std::distance( _mapGroups.begin(), it );
3460 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3465 //=============================================================================
3467 * \brief Return groups cantained in _mapGroups by their IDs
3469 //=============================================================================
3471 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3473 int nbGroups = groupIDs.size();
3474 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3475 aList->length( nbGroups );
3477 list<int>::const_iterator ids = groupIDs.begin();
3478 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3480 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3481 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3482 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3484 aList->length( nbGroups );
3485 return aList._retn();
3488 //=============================================================================
3490 * \brief Return information about imported file
3492 //=============================================================================
3494 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3496 SALOME_MED::MedFileInfo_var res( myFileInfo );
3497 if ( !res.operator->() ) {
3498 res = new SALOME_MED::MedFileInfo;
3500 res->fileSize = res->major = res->minor = res->release = -1;
3505 //=============================================================================
3507 * \brief Check and correct names of mesh groups
3509 //=============================================================================
3511 void SMESH_Mesh_i::checkGroupNames()
3513 int nbGrp = NbGroups();
3517 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3518 if ( aStudy->_is_nil() )
3519 return; // nothing to do
3521 SMESH::ListOfGroups* grpList = 0;
3522 // avoid dump of "GetGroups"
3524 // store python dump into a local variable inside local scope
3525 SMESH::TPythonDump pDump; // do not delete this line of code
3526 grpList = GetGroups();
3529 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3530 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3533 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3534 if ( aGrpSO->_is_nil() )
3536 // correct name of the mesh group if necessary
3537 const char* guiName = aGrpSO->GetName();
3538 if ( strcmp(guiName, aGrp->GetName()) )
3539 aGrp->SetName( guiName );
3543 //=============================================================================
3545 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3547 //=============================================================================
3548 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3550 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3551 CORBA::string_dup(theParameters));
3554 //=============================================================================
3556 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3558 //=============================================================================
3559 char* SMESH_Mesh_i::GetParameters()
3561 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3562 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3565 //=============================================================================
3567 * \brief Returns list of notebook variables used for last Mesh operation
3569 //=============================================================================
3570 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3572 SMESH::string_array_var aResult = new SMESH::string_array();
3573 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3575 char *aParameters = GetParameters();
3576 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3577 if(!aStudy->_is_nil()) {
3578 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3579 if(aSections->length() > 0) {
3580 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3581 aResult->length(aVars.length());
3582 for(int i = 0;i < aVars.length();i++)
3583 aResult[i] = CORBA::string_dup( aVars[i]);
3587 return aResult._retn();
3590 //=======================================================================
3591 //function : GetTypes
3592 //purpose : Returns types of elements it contains
3593 //=======================================================================
3595 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3597 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3601 if (_impl->NbEdges())
3602 types[nbTypes++] = SMESH::EDGE;
3603 if (_impl->NbFaces())
3604 types[nbTypes++] = SMESH::FACE;
3605 if (_impl->NbVolumes())
3606 types[nbTypes++] = SMESH::VOLUME;
3607 if (_impl->Nb0DElements())
3608 types[nbTypes++] = SMESH::ELEM0D;
3609 types->length( nbTypes );
3611 return types._retn();
3614 //=======================================================================
3615 //function : GetMesh
3616 //purpose : Returns self
3617 //=======================================================================
3619 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3621 return SMESH::SMESH_Mesh::_duplicate( _this() );
3624 //=============================================================================
3626 * \brief Returns statistic of mesh elements
3628 //=============================================================================
3629 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3631 SMESH::long_array_var aRes = new SMESH::long_array();
3632 aRes->length(SMESH::Entity_Last);
3633 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3635 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3637 return aRes._retn();
3638 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3639 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3640 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3641 return aRes._retn();
3644 //=============================================================================
3646 * \brief Collect statistic of mesh elements given by iterator
3648 //=============================================================================
3649 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3650 SMESH::long_array& theInfo)
3652 if (!theItr) return;
3653 while (theItr->more())
3654 theInfo[ theItr->next()->GetEntityType() ]++;
3657 //=============================================================================
3659 * \brief mapping of mesh dimension into shape type
3661 //=============================================================================
3662 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3664 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3666 case 0: aType = TopAbs_VERTEX; break;
3667 case 1: aType = TopAbs_EDGE; break;
3668 case 2: aType = TopAbs_FACE; break;
3670 default:aType = TopAbs_SOLID; break;
3675 //=============================================================================
3677 * \brief Internal structure used to find concurent submeshes
3679 * It represents a pair < submesh, concurent dimension >, where
3680 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3681 * with another submesh. In other words, it is dimension of a hypothesis assigned
3684 //=============================================================================
3690 int _dim; //!< a dimension the algo can build (concurrent dimension)
3691 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3692 TopTools_MapOfShape _shapeMap;
3693 SMESH_subMesh* _subMesh;
3694 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3697 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3699 const TopoDS_Shape& theShape)
3701 _subMesh = (SMESH_subMesh*)theSubMesh;
3702 SetShape( theDim, theShape );
3706 void SetShape(const int theDim,
3707 const TopoDS_Shape& theShape)
3710 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3711 if (_dim >= _ownDim)
3712 _shapeMap.Add( theShape );
3714 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3715 for( ; anExp.More(); anExp.Next() )
3716 _shapeMap.Add( anExp.Current() );
3720 //! Check sharing of sub shapes
3721 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3722 const TopTools_MapOfShape& theToFind,
3723 const TopAbs_ShapeEnum theType)
3725 bool isShared = false;
3726 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3727 for (; !isShared && anItr.More(); anItr.Next() ) {
3728 const TopoDS_Shape aSubSh = anItr.Key();
3729 // check for case when concurrent dimensions are same
3730 isShared = theToFind.Contains( aSubSh );
3731 // check for subshape with concurrent dimension
3732 TopExp_Explorer anExp( aSubSh, theType );
3733 for ( ; !isShared && anExp.More(); anExp.Next() )
3734 isShared = theToFind.Contains( anExp.Current() );
3739 //! check algorithms
3740 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3741 const SMESHDS_Hypothesis* theA2)
3743 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3744 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3745 return false; // one of the hypothesis is not algorithm
3746 // check algorithm names (should be equal)
3747 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3751 //! Check if subshape hypotheses are concurrent
3752 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3754 if ( _subMesh == theOther->_subMesh )
3755 return false; // same subshape - should not be
3757 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3758 // any of the two submeshes is not on COMPOUND shape )
3759 // -> no concurrency
3760 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3761 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3762 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3765 // bool checkSubShape = ( _dim >= theOther->_dim )
3766 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3767 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3768 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3769 if ( !checkSubShape )
3772 // check algorithms to be same
3773 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3774 return true; // different algorithms
3776 // check hypothesises for concurrence (skip first as algorithm)
3778 // pointers should be same, becase it is referenes from mesh hypothesis partition
3779 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3780 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3781 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3782 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3784 // the submeshes are concurrent if their algorithms has different parameters
3785 return nbSame != theOther->_hypothesises.size() - 1;
3788 }; // end of SMESH_DimHyp
3790 typedef list<SMESH_DimHyp*> TDimHypList;
3792 static void addDimHypInstance(const int theDim,
3793 const TopoDS_Shape& theShape,
3794 const SMESH_Algo* theAlgo,
3795 const SMESH_subMesh* theSubMesh,
3796 const list <const SMESHDS_Hypothesis*>& theHypList,
3797 TDimHypList* theDimHypListArr )
3799 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3800 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3801 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3802 listOfdimHyp.push_back( dimHyp );
3805 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3806 dimHyp->_hypothesises.push_front(theAlgo);
3807 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3808 for( ; hypIt != theHypList.end(); hypIt++ )
3809 dimHyp->_hypothesises.push_back( *hypIt );
3812 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3813 const TDimHypList& theListOfDimHyp,
3814 TListOfInt& theListOfConcurr )
3816 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3817 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3818 const SMESH_DimHyp* curDimHyp = *rIt;
3819 if ( curDimHyp == theDimHyp )
3820 break; // meet own dimHyp pointer in same dimension
3821 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3822 if ( find( theListOfConcurr.begin(),
3823 theListOfConcurr.end(),
3824 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3825 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3829 static void unionLists(TListOfInt& theListOfId,
3830 TListOfListOfInt& theListOfListOfId,
3833 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3834 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3836 continue; //skip already treated lists
3837 // check if other list has any same submesh object
3838 TListOfInt& otherListOfId = *it;
3839 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3840 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3843 // union two lists (from source into target)
3844 TListOfInt::iterator it2 = otherListOfId.begin();
3845 for ( ; it2 != otherListOfId.end(); it2++ ) {
3846 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3847 theListOfId.push_back(*it2);
3849 // clear source list
3850 otherListOfId.clear();
3854 //! free memory allocated for dimension-hypothesis objects
3855 static void removeDimHyps( TDimHypList* theArrOfList )
3857 for (int i = 0; i < 4; i++ ) {
3858 TDimHypList& listOfdimHyp = theArrOfList[i];
3859 TDimHypList::const_iterator it = listOfdimHyp.begin();
3860 for ( ; it != listOfdimHyp.end(); it++ )
3865 //=============================================================================
3867 * \brief Return submesh objects list in meshing order
3869 //=============================================================================
3871 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3873 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3875 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3877 return aResult._retn();
3879 ::SMESH_Mesh& mesh = GetImpl();
3880 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3881 if ( !anOrder.size() ) {
3883 // collect submeshes detecting concurrent algorithms and hypothesises
3884 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3886 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3887 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3888 ::SMESH_subMesh* sm = (*i_sm).second;
3890 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3892 // list of assigned hypothesises
3893 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3894 // Find out dimensions where the submesh can be concurrent.
3895 // We define the dimensions by algo of each of hypotheses in hypList
3896 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3897 for( ; hypIt != hypList.end(); hypIt++ ) {
3898 SMESH_Algo* anAlgo = 0;
3899 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3900 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3901 // hyp it-self is algo
3902 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3904 // try to find algorithm with help of subshapes
3905 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3906 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3907 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3910 continue; // no assigned algorithm to current submesh
3912 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3913 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3915 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3916 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3917 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3919 } // end iterations on submesh
3921 // iterate on created dimension-hypotheses and check for concurrents
3922 for ( int i = 0; i < 4; i++ ) {
3923 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3924 // check for concurrents in own and other dimensions (step-by-step)
3925 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3926 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3927 const SMESH_DimHyp* dimHyp = *dhIt;
3928 TListOfInt listOfConcurr;
3929 // looking for concurrents and collect into own list
3930 for ( int j = i; j < 4; j++ )
3931 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3932 // check if any concurrents found
3933 if ( listOfConcurr.size() > 0 ) {
3934 // add own submesh to list of concurrent
3935 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3936 anOrder.push_back( listOfConcurr );
3941 removeDimHyps(dimHypListArr);
3943 // now, minimise the number of concurrent groups
3944 // Here we assume that lists of submhes can has same submesh
3945 // in case of multi-dimension algorithms, as result
3946 // list with common submesh have to be union into one list
3948 TListOfListOfInt::iterator listIt = anOrder.begin();
3949 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3950 unionLists( *listIt, anOrder, listIndx + 1 );
3952 // convert submesh ids into interface instances
3953 // and dump command into python
3954 convertMeshOrder( anOrder, aResult, true );
3956 return aResult._retn();
3959 //=============================================================================
3961 * \brief find common submeshes with given submesh
3962 * \param theSubMeshList list of already collected submesh to check
3963 * \param theSubMesh given submesh to intersect with other
3964 * \param theCommonSubMeshes collected common submeshes
3966 //=============================================================================
3968 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
3969 const SMESH_subMesh* theSubMesh,
3970 set<const SMESH_subMesh*>& theCommon )
3974 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
3975 for ( ; it != theSubMeshList.end(); it++ )
3976 theSubMesh->FindIntersection( *it, theCommon );
3977 theSubMeshList.push_back( theSubMesh );
3978 //theCommon.insert( theSubMesh );
3981 //=============================================================================
3983 * \brief Set submesh object order
3984 * \param theSubMeshArray submesh array order
3986 //=============================================================================
3988 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
3991 ::SMESH_Mesh& mesh = GetImpl();
3993 TPythonDump aPythonDump; // prevent dump of called methods
3994 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
3996 TListOfListOfInt subMeshOrder;
3997 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
3999 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4000 TListOfInt subMeshIds;
4001 aPythonDump << "[ ";
4002 // Collect subMeshes which should be clear
4003 // do it list-by-list, because modification of submesh order
4004 // take effect between concurrent submeshes only
4005 set<const SMESH_subMesh*> subMeshToClear;
4006 list<const SMESH_subMesh*> subMeshList;
4007 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4009 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4011 aPythonDump << ", ";
4012 aPythonDump << subMesh;
4013 subMeshIds.push_back( subMesh->GetId() );
4014 // detect common parts of submeshes
4015 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4016 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4018 aPythonDump << " ]";
4019 subMeshOrder.push_back( subMeshIds );
4021 // clear collected submeshes
4022 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4023 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4024 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4026 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4027 // ClearSubMesh( *clrIt );
4030 aPythonDump << " ])";
4032 mesh.SetMeshOrder( subMeshOrder );
4038 //=============================================================================
4040 * \brief Convert submesh ids into submesh interfaces
4042 //=============================================================================
4044 void SMESH_Mesh_i::convertMeshOrder
4045 (const TListOfListOfInt& theIdsOrder,
4046 SMESH::submesh_array_array& theResOrder,
4047 const bool theIsDump)
4049 int nbSet = theIdsOrder.size();
4050 TPythonDump aPythonDump; // prevent dump of called methods
4052 aPythonDump << "[ ";
4053 theResOrder.length(nbSet);
4054 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4056 for( ; it != theIdsOrder.end(); it++ ) {
4057 // translate submesh identificators into submesh objects
4058 // takeing into account real number of concurrent lists
4059 const TListOfInt& aSubOrder = (*it);
4060 if (!aSubOrder.size())
4063 aPythonDump << "[ ";
4064 // convert shape indeces into interfaces
4065 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4066 aResSubSet->length(aSubOrder.size());
4067 TListOfInt::const_iterator subIt = aSubOrder.begin();
4068 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4069 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4071 SMESH::SMESH_subMesh_var subMesh =
4072 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4075 aPythonDump << ", ";
4076 aPythonDump << subMesh;
4078 aResSubSet[ j++ ] = subMesh;
4081 aPythonDump << " ]";
4082 theResOrder[ listIndx++ ] = aResSubSet;
4084 // correct number of lists
4085 theResOrder.length( listIndx );
4088 // finilise python dump
4089 aPythonDump << " ]";
4090 aPythonDump << " = " << _this() << ".GetMeshOrder()";