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");
125 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
126 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
127 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
129 // this method is called from destructor of group (PAL6331)
130 //_impl->RemoveGroup( aGroup->GetLocalID() );
131 #ifdef WITHGENERICOBJ
138 #ifdef WITHGENERICOBJ
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
142 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
147 _mapSubMeshIor.clear();
149 // destroy hypotheses
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
163 //=============================================================================
167 * Associates <this> mesh with <theShape> and puts a reference
168 * to <theShape> into the current study;
169 * the previous shape is substituted by the new one.
171 //=============================================================================
173 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
174 throw (SALOME::SALOME_Exception)
176 Unexpect aCatch(SALOME_SalomeException);
178 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
180 catch(SALOME_Exception & S_ex) {
181 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
183 // to track changes of GEOM groups
184 addGeomGroupData( theShapeObject, _this() );
187 //================================================================================
189 * \brief return true if mesh has a shape to build a shape on
191 //================================================================================
193 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
194 throw (SALOME::SALOME_Exception)
196 Unexpect aCatch(SALOME_SalomeException);
199 res = _impl->HasShapeToMesh();
201 catch(SALOME_Exception & S_ex) {
202 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
207 //=======================================================================
208 //function : GetShapeToMesh
210 //=======================================================================
212 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
213 throw (SALOME::SALOME_Exception)
215 Unexpect aCatch(SALOME_SalomeException);
216 GEOM::GEOM_Object_var aShapeObj;
218 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
220 aShapeObj = _gen_i->ShapeToGeomObject( S );
222 catch(SALOME_Exception & S_ex) {
223 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
225 return aShapeObj._retn();
228 //================================================================================
230 * \brief Remove all nodes and elements
232 //================================================================================
234 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
236 Unexpect aCatch(SALOME_SalomeException);
239 CheckGeomGroupModif(); // issue 20145
241 catch(SALOME_Exception & S_ex) {
242 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
244 TPythonDump() << _this() << ".Clear()";
247 //================================================================================
249 * \brief Remove all nodes and elements for indicated shape
251 //================================================================================
253 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
254 throw (SALOME::SALOME_Exception)
256 Unexpect aCatch(SALOME_SalomeException);
258 _impl->ClearSubMesh( ShapeID );
260 catch(SALOME_Exception & S_ex) {
261 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
265 //=============================================================================
269 //=============================================================================
271 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
273 SMESH::DriverMED_ReadStatus res;
276 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
277 res = SMESH::DRS_OK; break;
278 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
279 res = SMESH::DRS_EMPTY; break;
280 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
281 res = SMESH::DRS_WARN_RENUMBER; break;
282 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
283 res = SMESH::DRS_WARN_SKIP_ELEM; break;
284 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
286 res = SMESH::DRS_FAIL; break;
291 //=============================================================================
295 * Imports mesh data from MED file
297 //=============================================================================
299 SMESH::DriverMED_ReadStatus
300 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
301 throw ( SALOME::SALOME_Exception )
303 Unexpect aCatch(SALOME_SalomeException);
306 status = _impl->MEDToMesh( theFileName, theMeshName );
308 catch( SALOME_Exception& S_ex ) {
309 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
312 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
315 CreateGroupServants();
317 int major, minor, release;
318 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
319 major = minor = release = -1;
320 myFileInfo = new SALOME_MED::MedFileInfo();
321 myFileInfo->fileName = theFileName;
322 myFileInfo->fileSize = 0;
325 if ( ::_stati64( theFileName, &d ) != -1 )
328 if ( ::stat64( theFileName, &d ) != -1 )
330 myFileInfo->fileSize = d.st_size;
331 myFileInfo->major = major;
332 myFileInfo->minor = minor;
333 myFileInfo->release = release;
335 return ConvertDriverMEDReadStatus(status);
338 //================================================================================
340 * \brief Return string representation of a MED file version comprising nbDigits
342 //================================================================================
344 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
346 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
348 return CORBA::string_dup( ver.c_str() );
351 //=============================================================================
355 * Imports mesh data from MED file
357 //=============================================================================
359 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
360 throw ( SALOME::SALOME_Exception )
362 // Read mesh with name = <theMeshName> into SMESH_Mesh
363 _impl->UNVToMesh( theFileName );
365 CreateGroupServants();
370 //=============================================================================
374 * Imports mesh data from STL file
376 //=============================================================================
377 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
378 throw ( SALOME::SALOME_Exception )
380 // Read mesh with name = <theMeshName> into SMESH_Mesh
381 _impl->STLToMesh( theFileName );
386 //=============================================================================
390 * Imports mesh data from MED file
392 //=============================================================================
394 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
396 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
397 // int status = _impl->MEDToMesh( theFileName, theMeshName );
398 // CreateGroupServants();
403 //=============================================================================
407 //=============================================================================
409 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
411 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
412 (SMESH_Hypothesis::Hypothesis_Status theStatus)
415 RETURNCASE( HYP_OK );
416 RETURNCASE( HYP_MISSING );
417 RETURNCASE( HYP_CONCURENT );
418 RETURNCASE( HYP_BAD_PARAMETER );
419 RETURNCASE( HYP_HIDDEN_ALGO );
420 RETURNCASE( HYP_HIDING_ALGO );
421 RETURNCASE( HYP_UNKNOWN_FATAL );
422 RETURNCASE( HYP_INCOMPATIBLE );
423 RETURNCASE( HYP_NOTCONFORM );
424 RETURNCASE( HYP_ALREADY_EXIST );
425 RETURNCASE( HYP_BAD_DIM );
426 RETURNCASE( HYP_BAD_SUBSHAPE );
427 RETURNCASE( HYP_BAD_GEOMETRY );
428 RETURNCASE( HYP_NEED_SHAPE );
431 return SMESH::HYP_UNKNOWN_FATAL;
434 //=============================================================================
438 * calls internal addHypothesis() and then adds a reference to <anHyp> under
439 * the SObject actually having a reference to <aSubShape>.
440 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
442 //=============================================================================
444 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
445 SMESH::SMESH_Hypothesis_ptr anHyp)
446 throw(SALOME::SALOME_Exception)
448 Unexpect aCatch(SALOME_SalomeException);
449 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
451 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
452 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
453 aSubShapeObject, anHyp );
455 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
457 // Update Python script
458 if(_impl->HasShapeToMesh()) {
459 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
460 << aSubShapeObject << ", " << anHyp << " )";
463 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
466 return ConvertHypothesisStatus(status);
469 //=============================================================================
473 //=============================================================================
475 SMESH_Hypothesis::Hypothesis_Status
476 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
477 SMESH::SMESH_Hypothesis_ptr anHyp)
479 if(MYDEBUG) MESSAGE("addHypothesis");
481 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
482 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
485 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
486 if (CORBA::is_nil(myHyp))
487 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
490 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
493 TopoDS_Shape myLocSubShape;
494 //use PseudoShape in case if mesh has no shape
496 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
498 myLocSubShape = _impl->GetShapeToMesh();
500 int hypId = myHyp->GetId();
501 status = _impl->AddHypothesis(myLocSubShape, hypId);
502 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
503 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
504 #ifdef WITHGENERICOBJ
505 _mapHypo[hypId]->Register();
507 // assure there is a corresponding submesh
508 if ( !_impl->IsMainShape( myLocSubShape )) {
509 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
510 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
511 createSubMesh( aSubShapeObject );
515 catch(SALOME_Exception & S_ex)
517 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
522 //=============================================================================
526 //=============================================================================
528 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
529 SMESH::SMESH_Hypothesis_ptr anHyp)
530 throw(SALOME::SALOME_Exception)
532 Unexpect aCatch(SALOME_SalomeException);
533 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
535 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
536 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
537 aSubShapeObject, anHyp );
539 // Update Python script
540 // Update Python script
541 if(_impl->HasShapeToMesh()) {
542 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
543 << aSubShapeObject << ", " << anHyp << " )";
546 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
550 return ConvertHypothesisStatus(status);
553 //=============================================================================
557 //=============================================================================
559 SMESH_Hypothesis::Hypothesis_Status
560 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
561 SMESH::SMESH_Hypothesis_ptr anHyp)
563 if(MYDEBUG) MESSAGE("removeHypothesis()");
564 // **** proposer liste de subShape (selection multiple)
566 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
567 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
569 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
570 if (CORBA::is_nil(myHyp))
571 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
573 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
576 TopoDS_Shape myLocSubShape;
577 //use PseudoShape in case if mesh has no shape
579 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
581 myLocSubShape = _impl->GetShapeToMesh();
583 int hypId = myHyp->GetId();
584 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
585 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
586 // _mapHypo.erase( hypId );
588 catch(SALOME_Exception & S_ex)
590 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
595 //=============================================================================
599 //=============================================================================
601 SMESH::ListOfHypothesis *
602 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
603 throw(SALOME::SALOME_Exception)
605 Unexpect aCatch(SALOME_SalomeException);
606 if (MYDEBUG) MESSAGE("GetHypothesisList");
607 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
608 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
610 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
613 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
614 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
615 myLocSubShape = _impl->GetShapeToMesh();
616 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
617 int i = 0, n = aLocalList.size();
620 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
621 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
622 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
623 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
628 catch(SALOME_Exception & S_ex) {
629 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
632 return aList._retn();
635 //=============================================================================
639 //=============================================================================
640 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
641 const char* theName )
642 throw(SALOME::SALOME_Exception)
644 Unexpect aCatch(SALOME_SalomeException);
645 MESSAGE("SMESH_Mesh_i::GetSubMesh");
646 if (CORBA::is_nil(aSubShapeObject))
647 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
650 SMESH::SMESH_subMesh_var subMesh;
651 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
653 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
655 //Get or Create the SMESH_subMesh object implementation
657 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
659 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
660 subMesh = getSubMesh( subMeshId );
662 // create a new subMesh object servant if there is none for the shape
663 if ( subMesh->_is_nil() )
664 subMesh = createSubMesh( aSubShapeObject );
665 if ( _gen_i->CanPublishInStudy( subMesh )) {
666 SALOMEDS::SObject_var aSO =
667 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
668 subMesh, aSubShapeObject, theName );
669 if ( !aSO->_is_nil()) {
670 // Update Python script
671 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
672 << aSubShapeObject << ", '" << theName << "' )";
676 catch(SALOME_Exception & S_ex) {
677 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
679 return subMesh._retn();
682 //=============================================================================
686 //=============================================================================
688 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
689 throw (SALOME::SALOME_Exception)
691 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
692 if ( theSubMesh->_is_nil() )
695 GEOM::GEOM_Object_var aSubShapeObject;
696 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
697 if ( !aStudy->_is_nil() ) {
698 // Remove submesh's SObject
699 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
700 if ( !anSO->_is_nil() ) {
701 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
702 SALOMEDS::SObject_var anObj, aRef;
703 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
704 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
706 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
707 // aSubShapeObject = theSubMesh->GetSubShape();
709 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
711 // Update Python script
712 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
716 removeSubMesh( theSubMesh, aSubShapeObject.in() );
719 //=============================================================================
723 //=============================================================================
724 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
725 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
727 switch (theElemType) {
732 CASE2STRING( VOLUME );
738 //=============================================================================
742 //=============================================================================
744 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
745 const char* theName )
746 throw(SALOME::SALOME_Exception)
748 Unexpect aCatch(SALOME_SalomeException);
749 SMESH::SMESH_Group_var aNewGroup =
750 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
752 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
753 SALOMEDS::SObject_var aSO =
754 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
755 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
756 if ( !aSO->_is_nil()) {
757 // Update Python script
758 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
759 << ElementTypeString(theElemType) << ", '" << theName << "' )";
762 return aNewGroup._retn();
766 //=============================================================================
770 //=============================================================================
771 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
773 GEOM::GEOM_Object_ptr theGeomObj)
774 throw(SALOME::SALOME_Exception)
776 Unexpect aCatch(SALOME_SalomeException);
777 SMESH::SMESH_GroupOnGeom_var aNewGroup;
779 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
780 if ( !aShape.IsNull() )
782 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
783 ( createGroup( theElemType, theName, aShape ));
785 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
786 SALOMEDS::SObject_var aSO =
787 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
788 aNewGroup, theGeomObj, theName);
789 if ( !aSO->_is_nil()) {
790 // Update Python script
791 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
792 << ElementTypeString(theElemType) << ", '" << theName << "', "
793 << theGeomObj << " )";
798 return aNewGroup._retn();
801 //=============================================================================
805 //=============================================================================
807 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
808 throw (SALOME::SALOME_Exception)
810 if ( theGroup->_is_nil() )
813 SMESH_GroupBase_i* aGroup =
814 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
818 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
819 if ( !aStudy->_is_nil() ) {
820 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
822 if ( !aGroupSO->_is_nil() ) {
823 // Update Python script
824 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
826 // Remove group's SObject
827 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
831 // Remove the group from SMESH data structures
832 removeGroup( aGroup->GetLocalID() );
835 //=============================================================================
836 /*! RemoveGroupWithContents
837 * Remove group with its contents
839 //=============================================================================
840 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
841 throw (SALOME::SALOME_Exception)
843 if ( theGroup->_is_nil() )
846 SMESH_GroupBase_i* aGroup =
847 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
851 SMESH::long_array_var anIds = aGroup->GetListOfID();
852 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
854 // Update Python script
855 TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
858 if ( aGroup->GetType() == SMESH::NODE )
859 aMeshEditor->RemoveNodes( anIds );
861 aMeshEditor->RemoveElements( anIds );
864 RemoveGroup( theGroup );
866 // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
867 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
868 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
872 //================================================================================
874 * \brief Get the list of groups existing in the mesh
875 * \retval SMESH::ListOfGroups * - list of groups
877 //================================================================================
879 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
881 Unexpect aCatch(SALOME_SalomeException);
882 if (MYDEBUG) MESSAGE("GetGroups");
884 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
887 TPythonDump aPythonDump;
888 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
892 aList->length( _mapGroups.size() );
894 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
895 for ( ; it != _mapGroups.end(); it++ ) {
896 if ( CORBA::is_nil( it->second )) continue;
897 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
899 if (i > 1) aPythonDump << ", ";
900 aPythonDump << it->second;
904 catch(SALOME_Exception & S_ex) {
905 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
908 // Update Python script
909 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
910 aPythonDump << " ] = " << _this() << ".GetGroups()";
912 return aList._retn();
914 //=============================================================================
916 * Get number of groups existing in the mesh
918 //=============================================================================
920 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
922 Unexpect aCatch(SALOME_SalomeException);
923 return _mapGroups.size();
926 //=============================================================================
928 * New group is created. All mesh elements that are
929 * present in initial groups are added to the new one
931 //=============================================================================
932 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
933 SMESH::SMESH_GroupBase_ptr theGroup2,
934 const char* theName )
935 throw (SALOME::SALOME_Exception)
939 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
940 theGroup1->GetType() != theGroup2->GetType() )
941 return SMESH::SMESH_Group::_nil();
944 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
945 if ( aResGrp->_is_nil() )
946 return SMESH::SMESH_Group::_nil();
948 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
949 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
951 TColStd_MapOfInteger aResMap;
953 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
954 aResMap.Add( anIds1[ i1 ] );
956 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
957 aResMap.Add( anIds2[ i2 ] );
959 SMESH::long_array_var aResIds = new SMESH::long_array;
960 aResIds->length( aResMap.Extent() );
963 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
964 for( ; anIter.More(); anIter.Next() )
965 aResIds[ resI++ ] = anIter.Key();
967 aResGrp->Add( aResIds );
969 // Clear python lines, created by CreateGroup() and Add()
970 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
971 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
972 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
974 // Update Python script
975 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
976 << theGroup1 << ", " << theGroup2 << ", '"
979 return aResGrp._retn();
983 return SMESH::SMESH_Group::_nil();
987 //=============================================================================
989 \brief Union list of groups. New group is created. All mesh elements that are
990 present in initial groups are added to the new one.
991 \param theGroups list of groups
992 \param theName name of group to be created
993 \return pointer on the group
995 //=============================================================================
996 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
997 const char* theName )
998 throw (SALOME::SALOME_Exception)
1001 return SMESH::SMESH_Group::_nil();
1005 NCollection_Map< int > anIds;
1006 SMESH::ElementType aType = SMESH::ALL;
1007 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1009 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1010 if ( CORBA::is_nil( aGrp ) )
1014 SMESH::ElementType aCurrType = aGrp->GetType();
1015 if ( aType == SMESH::ALL )
1019 if ( aType != aCurrType )
1020 return SMESH::SMESH_Group::_nil();
1024 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1025 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1027 int aCurrId = aCurrIds[ i ];
1028 anIds.Add( aCurrId );
1033 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1034 if ( aResGrp->_is_nil() )
1035 return SMESH::SMESH_Group::_nil();
1037 // Create array of identifiers
1038 SMESH::long_array_var aResIds = new SMESH::long_array;
1039 aResIds->length( anIds.Extent() );
1041 NCollection_Map< int >::Iterator anIter( anIds );
1042 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1044 aResIds[ i ] = anIter.Value();
1046 aResGrp->Add( aResIds );
1048 // Clear python lines, created by CreateGroup() and Add()
1049 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1050 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1051 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1053 // Update Python script
1055 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1056 << &theGroups << ", '" << theName << "' )";
1058 return aResGrp._retn();
1062 return SMESH::SMESH_Group::_nil();
1066 //=============================================================================
1068 * New group is created. All mesh elements that are
1069 * present in both initial groups are added to the new one.
1071 //=============================================================================
1072 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1073 SMESH::SMESH_GroupBase_ptr theGroup2,
1074 const char* theName )
1075 throw (SALOME::SALOME_Exception)
1077 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1078 theGroup1->GetType() != theGroup2->GetType() )
1079 return SMESH::SMESH_Group::_nil();
1081 // Create Intersection
1082 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1083 if ( aResGrp->_is_nil() )
1086 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1087 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1089 TColStd_MapOfInteger aMap1;
1091 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1092 aMap1.Add( anIds1[ i1 ] );
1094 TColStd_SequenceOfInteger aSeq;
1096 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1097 if ( aMap1.Contains( anIds2[ i2 ] ) )
1098 aSeq.Append( anIds2[ i2 ] );
1100 SMESH::long_array_var aResIds = new SMESH::long_array;
1101 aResIds->length( aSeq.Length() );
1103 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1104 aResIds[ resI ] = aSeq( resI + 1 );
1106 aResGrp->Add( aResIds );
1108 // Clear python lines, created by CreateGroup() and Add()
1109 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1110 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1111 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1113 // Update Python script
1114 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1115 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1117 return aResGrp._retn();
1120 //=============================================================================
1122 \brief Intersect list of groups. New group is created. All mesh elements that
1123 are present in all initial groups simultaneously are added to the new one.
1124 \param theGroups list of groups
1125 \param theName name of group to be created
1126 \return pointer on the group
1128 //=============================================================================
1129 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1130 const SMESH::ListOfGroups& theGroups, const char* theName )
1131 throw (SALOME::SALOME_Exception)
1134 return SMESH::SMESH_Group::_nil();
1138 NCollection_DataMap< int, int > anIdToCount;
1139 SMESH::ElementType aType = SMESH::ALL;
1140 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1142 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1143 if ( CORBA::is_nil( aGrp ) )
1147 SMESH::ElementType aCurrType = aGrp->GetType();
1148 if ( aType == SMESH::ALL )
1152 if ( aType != aCurrType )
1153 return SMESH::SMESH_Group::_nil();
1156 // calculates number of occurance ids in groups
1157 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1158 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1160 int aCurrId = aCurrIds[ i ];
1161 if ( !anIdToCount.IsBound( aCurrId ) )
1162 anIdToCount.Bind( aCurrId, 1 );
1164 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1168 // create map of ids
1169 int nbGrp = theGroups.length();
1170 NCollection_Map< int > anIds;
1171 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1172 for ( ; anIter.More(); anIter.Next() )
1174 int aCurrId = anIter.Key();
1175 int aCurrNb = anIter.Value();
1176 if ( aCurrNb == nbGrp )
1177 anIds.Add( aCurrId );
1181 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1182 if ( aResGrp->_is_nil() )
1183 return SMESH::SMESH_Group::_nil();
1185 // Create array of identifiers
1186 SMESH::long_array_var aResIds = new SMESH::long_array;
1187 aResIds->length( anIds.Extent() );
1189 NCollection_Map< int >::Iterator aListIter( anIds );
1190 for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1192 aResIds[ i ] = aListIter.Value();
1194 aResGrp->Add( aResIds );
1196 // Clear python lines, created by CreateGroup() and Add()
1197 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1198 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1199 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1201 // Update Python script
1203 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1204 << &theGroups << ", '" << theName << "' )";
1206 return aResGrp._retn();
1210 return SMESH::SMESH_Group::_nil();
1214 //=============================================================================
1216 * New group is created. All mesh elements that are present in
1217 * main group but do not present in tool group are added to the new one
1219 //=============================================================================
1220 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1221 SMESH::SMESH_GroupBase_ptr theGroup2,
1222 const char* theName )
1223 throw (SALOME::SALOME_Exception)
1225 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1226 theGroup1->GetType() != theGroup2->GetType() )
1227 return SMESH::SMESH_Group::_nil();
1230 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1231 if ( aResGrp->_is_nil() )
1234 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1235 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1237 TColStd_MapOfInteger aMap2;
1239 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1240 aMap2.Add( anIds2[ i2 ] );
1242 TColStd_SequenceOfInteger aSeq;
1243 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1244 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1245 aSeq.Append( anIds1[ i1 ] );
1247 SMESH::long_array_var aResIds = new SMESH::long_array;
1248 aResIds->length( aSeq.Length() );
1250 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1251 aResIds[ resI ] = aSeq( resI + 1 );
1253 aResGrp->Add( aResIds );
1255 // Clear python lines, created by CreateGroup() and Add()
1256 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1257 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1258 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1260 // Update Python script
1261 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1262 << theGroup1 << ", " << theGroup2 << ", '"
1263 << theName << "' )";
1265 return aResGrp._retn();
1268 //=============================================================================
1270 \brief Cut lists of groups. New group is created. All mesh elements that are
1271 present in main groups but do not present in tool groups are added to the new one
1272 \param theMainGroups list of main groups
1273 \param theToolGroups list of tool groups
1274 \param theName name of group to be created
1275 \return pointer on the group
1277 //=============================================================================
1278 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1279 const SMESH::ListOfGroups& theMainGroups,
1280 const SMESH::ListOfGroups& theToolGroups,
1281 const char* theName )
1282 throw (SALOME::SALOME_Exception)
1285 return SMESH::SMESH_Group::_nil();
1289 NCollection_Map< int > aToolIds;
1290 SMESH::ElementType aType = SMESH::ALL;
1292 // iterate through tool groups
1293 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1295 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1296 if ( CORBA::is_nil( aGrp ) )
1300 SMESH::ElementType aCurrType = aGrp->GetType();
1301 if ( aType == SMESH::ALL )
1305 if ( aType != aCurrType )
1306 return SMESH::SMESH_Group::_nil();
1310 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1311 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1313 int aCurrId = aCurrIds[ i ];
1314 aToolIds.Add( aCurrId );
1318 NCollection_Map< int > anIds; // result
1320 // Iterate through main group
1321 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1323 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1324 if ( CORBA::is_nil( aGrp ) )
1328 SMESH::ElementType aCurrType = aGrp->GetType();
1329 if ( aType == SMESH::ALL )
1333 if ( aType != aCurrType )
1334 return SMESH::SMESH_Group::_nil();
1338 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1339 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1341 int aCurrId = aCurrIds[ i ];
1342 if ( !aToolIds.Contains( aCurrId ) )
1343 anIds.Add( aCurrId );
1348 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1349 if ( aResGrp->_is_nil() )
1350 return SMESH::SMESH_Group::_nil();
1352 // Create array of identifiers
1353 SMESH::long_array_var aResIds = new SMESH::long_array;
1354 aResIds->length( anIds.Extent() );
1356 NCollection_Map< int >::Iterator anIter( anIds );
1357 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1359 aResIds[ i ] = anIter.Value();
1361 aResGrp->Add( aResIds );
1363 // Clear python lines, created by CreateGroup() and Add()
1364 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1365 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1366 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1368 // Update Python script
1370 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1371 << &theMainGroups << ", " << &theToolGroups << ", '"
1372 << theName << "' )";
1374 return aResGrp._retn();
1378 return SMESH::SMESH_Group::_nil();
1382 //=============================================================================
1384 \brief Create groups of entities from existing groups of superior dimensions
1386 1) extract all nodes from each group,
1387 2) combine all elements of specified dimension laying on these nodes.
1388 \param theGroups list of source groups
1389 \param theElemType dimension of elements
1390 \param theName name of new group
1391 \return pointer on new group
1393 //=============================================================================
1394 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1395 const SMESH::ListOfGroups& theGroups,
1396 SMESH::ElementType theElemType,
1397 const char* theName )
1398 throw (SALOME::SALOME_Exception)
1400 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1402 if ( !theName || !aMeshDS )
1403 return SMESH::SMESH_Group::_nil();
1405 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1409 // Create map of nodes from all groups
1411 NCollection_Map< int > aNodeMap;
1413 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1415 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1416 if ( CORBA::is_nil( aGrp ) )
1419 SMESH::ElementType aType = aGrp->GetType();
1420 if ( aType == SMESH::ALL )
1422 else if ( aType == SMESH::NODE )
1424 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1425 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1427 int aCurrId = aCurrIds[ i ];
1428 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1430 aNodeMap.Add( aNode->GetID() );
1435 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1436 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1438 int aCurrId = aCurrIds[ i ];
1439 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1442 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1443 while( aNodeIter->more() )
1445 const SMDS_MeshNode* aNode =
1446 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1448 aNodeMap.Add( aNode->GetID() );
1454 // Get result identifiers
1456 NCollection_Map< int > aResultIds;
1457 if ( theElemType == SMESH::NODE )
1459 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1460 for ( ; aNodeIter.More(); aNodeIter.Next() )
1461 aResultIds.Add( aNodeIter.Value() );
1465 // Create list of elements of given dimension constructed on the nodes
1466 NCollection_Map< int > anElemList;
1467 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1468 for ( ; aNodeIter.More(); aNodeIter.Next() )
1470 const SMDS_MeshElement* aNode =
1471 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1475 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1476 while( anElemIter->more() )
1478 const SMDS_MeshElement* anElem =
1479 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1480 if ( anElem && anElem->GetType() == anElemType )
1481 anElemList.Add( anElem->GetID() );
1485 // check whether all nodes of elements are present in nodes map
1486 NCollection_Map< int >::Iterator anIter( anElemList );
1487 for ( ; anIter.More(); anIter.Next() )
1489 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1494 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1495 while( aNodeIter->more() )
1497 const SMDS_MeshNode* aNode =
1498 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1499 if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1506 aResultIds.Add( anElem->GetID() );
1512 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1513 if ( aResGrp->_is_nil() )
1514 return SMESH::SMESH_Group::_nil();
1516 // Create array of identifiers
1517 SMESH::long_array_var aResIds = new SMESH::long_array;
1518 aResIds->length( aResultIds.Extent() );
1520 NCollection_Map< int >::Iterator aResIter( aResultIds );
1521 for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1522 aResIds[ i ] = aResIter.Value();
1523 aResGrp->Add( aResIds );
1525 // Remove strings corresponding to group creation
1526 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1527 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1528 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1530 // Update Python script
1532 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1533 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1535 return aResGrp._retn();
1539 return SMESH::SMESH_Group::_nil();
1543 //================================================================================
1545 * \brief Remember GEOM group data
1547 //================================================================================
1549 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1550 CORBA::Object_ptr theSmeshObj)
1552 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1555 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1556 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1557 if ( groupSO->_is_nil() )
1560 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1561 GEOM::GEOM_IGroupOperations_var groupOp =
1562 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1563 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1566 _geomGroupData.push_back( TGeomGroupData() );
1567 TGeomGroupData & groupData = _geomGroupData.back();
1569 CORBA::String_var entry = groupSO->GetID();
1570 groupData._groupEntry = entry.in();
1572 for ( int i = 0; i < ids->length(); ++i )
1573 groupData._indices.insert( ids[i] );
1575 groupData._smeshObject = theSmeshObj;
1578 //================================================================================
1580 * Remove GEOM group data relating to removed smesh object
1582 //================================================================================
1584 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1586 list<TGeomGroupData>::iterator
1587 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1588 for ( ; data != dataEnd; ++data ) {
1589 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1590 _geomGroupData.erase( data );
1596 //================================================================================
1598 * \brief Return new group contents if it has been changed and update group data
1600 //================================================================================
1602 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1604 TopoDS_Shape newShape;
1607 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1608 if ( study->_is_nil() ) return newShape; // means "not changed"
1609 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1610 if ( !groupSO->_is_nil() )
1612 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1613 if ( CORBA::is_nil( groupObj )) return newShape;
1614 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1616 // get indices of group items
1617 set<int> curIndices;
1618 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1619 GEOM::GEOM_IGroupOperations_var groupOp =
1620 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1621 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1622 for ( int i = 0; i < ids->length(); ++i )
1623 curIndices.insert( ids[i] );
1625 if ( groupData._indices == curIndices )
1626 return newShape; // group not changed
1629 groupData._indices = curIndices;
1631 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1632 if ( !geomClient ) return newShape;
1633 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1634 geomClient->RemoveShapeFromBuffer( groupIOR );
1635 newShape = _gen_i->GeomObjectToShape( geomGroup );
1638 if ( newShape.IsNull() ) {
1639 // geom group becomes empty - return empty compound
1640 TopoDS_Compound compound;
1641 BRep_Builder().MakeCompound(compound);
1642 newShape = compound;
1648 //=============================================================================
1650 * \brief Storage of shape and index used in CheckGeomGroupModif()
1652 //=============================================================================
1653 struct TIndexedShape {
1655 TopoDS_Shape _shape;
1656 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1659 //=============================================================================
1661 * \brief Update objects depending on changed geom groups
1663 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1664 * issue 0020210: Update of a smesh group after modification of the associated geom group
1666 //=============================================================================
1668 void SMESH_Mesh_i::CheckGeomGroupModif()
1670 if ( !_impl->HasShapeToMesh() ) return;
1672 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1673 if ( study->_is_nil() ) return;
1675 CORBA::Long nbEntities = NbNodes() + NbElements();
1677 // Check if group contents changed
1679 typedef map< string, TopoDS_Shape > TEntry2Geom;
1680 TEntry2Geom newGroupContents;
1682 list<TGeomGroupData>::iterator
1683 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1684 for ( ; data != dataEnd; ++data )
1686 pair< TEntry2Geom::iterator, bool > it_new =
1687 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1688 bool processedGroup = !it_new.second;
1689 TopoDS_Shape& newShape = it_new.first->second;
1690 if ( !processedGroup )
1691 newShape = newGroupShape( *data );
1692 if ( newShape.IsNull() )
1693 continue; // no changes
1695 if ( processedGroup ) { // update group indices
1696 list<TGeomGroupData>::iterator data2 = data;
1697 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1698 data->_indices = data2->_indices;
1701 // Update SMESH objects according to new GEOM group contents
1703 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1704 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1706 int oldID = submesh->GetId();
1707 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1709 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1711 // update hypotheses
1712 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1713 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1714 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1716 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1717 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1719 // care of submeshes
1720 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1721 int newID = newSubmesh->GetId();
1722 if ( newID != oldID ) {
1723 _mapSubMesh [ newID ] = newSubmesh;
1724 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1725 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1726 _mapSubMesh. erase(oldID);
1727 _mapSubMesh_i. erase(oldID);
1728 _mapSubMeshIor.erase(oldID);
1729 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1734 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1735 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1736 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1738 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1740 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1741 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1742 ds->SetShape( newShape );
1747 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1748 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1750 // Remove groups and submeshes basing on removed sub-shapes
1752 TopTools_MapOfShape newShapeMap;
1753 TopoDS_Iterator shapeIt( newShape );
1754 for ( ; shapeIt.More(); shapeIt.Next() )
1755 newShapeMap.Add( shapeIt.Value() );
1757 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1758 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1760 if ( newShapeMap.Contains( shapeIt.Value() ))
1762 TopTools_IndexedMapOfShape oldShapeMap;
1763 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1764 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1766 const TopoDS_Shape& oldShape = oldShapeMap(i);
1767 int oldInd = meshDS->ShapeToIndex( oldShape );
1769 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1770 if ( i_smIor != _mapSubMeshIor.end() ) {
1771 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1774 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1775 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1777 // check if a group bases on oldInd shape
1778 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1779 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1780 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1781 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1783 RemoveGroup( i_grp->second ); // several groups can base on same shape
1784 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1789 // Reassign hypotheses and update groups after setting the new shape to mesh
1791 // collect anassigned hypotheses
1792 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1793 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1794 TShapeHypList assignedHyps;
1795 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1797 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1798 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1799 if ( !hyps.empty() ) {
1800 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1801 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1802 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1805 // collect shapes supporting groups
1806 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1807 TShapeTypeList groupData;
1808 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1809 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1810 for ( ; grIt != groups.end(); ++grIt )
1812 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1814 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1816 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1817 _impl->ShapeToMesh( newShape );
1819 // reassign hypotheses
1820 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1821 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1823 TIndexedShape& geom = indS_hyps->first;
1824 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1825 int oldID = geom._index;
1826 int newID = meshDS->ShapeToIndex( geom._shape );
1829 if ( oldID == 1 ) { // main shape
1831 geom._shape = newShape;
1833 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1834 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1835 // care of submeshes
1836 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1837 if ( newID != oldID ) {
1838 _mapSubMesh [ newID ] = newSubmesh;
1839 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1840 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1841 _mapSubMesh. erase(oldID);
1842 _mapSubMesh_i. erase(oldID);
1843 _mapSubMeshIor.erase(oldID);
1844 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1848 TShapeTypeList::iterator geomType = groupData.begin();
1849 for ( ; geomType != groupData.end(); ++geomType )
1851 const TIndexedShape& geom = geomType->first;
1852 int oldID = geom._index;
1853 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1856 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1857 CORBA::String_var name = groupSO->GetName();
1859 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1861 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1862 group_i->changeLocalId( newID );
1865 break; // everything has been updated
1868 } // loop on group data
1872 CORBA::Long newNbEntities = NbNodes() + NbElements();
1873 list< SALOMEDS::SObject_var > soToUpdateIcons;
1874 if ( newNbEntities != nbEntities )
1876 // Add all SObjects with icons
1877 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1879 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1880 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1881 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1883 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1884 i_gr != _mapGroups.end(); ++i_gr ) // groups
1885 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1888 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1889 for ( ; so != soToUpdateIcons.end(); ++so )
1890 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1893 //=============================================================================
1895 * \brief Create standalone group instead if group on geometry
1897 //=============================================================================
1899 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1901 SMESH::SMESH_Group_var aGroup;
1902 if ( theGroup->_is_nil() )
1903 return aGroup._retn();
1905 Unexpect aCatch(SALOME_SalomeException);
1907 SMESH_GroupBase_i* aGroupToRem =
1908 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1910 return aGroup._retn();
1912 int anId = aGroupToRem->GetLocalID();
1913 if ( !_impl->ConvertToStandalone( anId ) )
1914 return aGroup._retn();
1915 removeGeomGroupData( theGroup );
1917 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1919 // remove old instance of group from own map
1920 _mapGroups.erase( anId );
1922 SALOMEDS::StudyBuilder_var builder;
1923 SALOMEDS::SObject_var aGroupSO;
1924 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1925 if ( !aStudy->_is_nil() ) {
1926 builder = aStudy->NewBuilder();
1927 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1928 if ( !aGroupSO->_is_nil() ) {
1930 // remove reference to geometry
1931 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1932 for ( ; chItr->More(); chItr->Next() )
1933 // Remove group's child SObject
1934 builder->RemoveObject( chItr->Value() );
1936 // Update Python script
1937 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1938 << aGroupSO << " )";
1942 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1943 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1944 aGroupImpl->Register();
1945 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1947 // remember new group in own map
1948 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1949 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1951 // register CORBA object for persistence
1952 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1954 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1956 return aGroup._retn();
1959 //=============================================================================
1963 //=============================================================================
1965 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1967 if(MYDEBUG) MESSAGE( "createSubMesh" );
1968 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1970 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1971 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1972 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1973 SMESH::SMESH_subMesh_var subMesh
1974 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1976 _mapSubMesh[subMeshId] = mySubMesh;
1977 _mapSubMesh_i[subMeshId] = subMeshServant;
1978 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1980 // register CORBA object for persistence
1981 int nextId = _gen_i->RegisterObject( subMesh );
1982 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1984 // to track changes of GEOM groups
1985 addGeomGroupData( theSubShapeObject, subMesh );
1987 return subMesh._retn();
1990 //=======================================================================
1991 //function : getSubMesh
1993 //=======================================================================
1995 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1997 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1998 if ( it == _mapSubMeshIor.end() )
1999 return SMESH::SMESH_subMesh::_nil();
2001 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2005 //=============================================================================
2009 //=============================================================================
2011 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2012 GEOM::GEOM_Object_ptr theSubShapeObject )
2014 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2015 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2018 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2020 CORBA::Long shapeId = theSubMesh->GetId();
2021 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2023 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2026 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2027 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2028 for ( ; hyp != hyps.end(); ++hyp )
2029 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2036 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2037 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2038 removeHypothesis( theSubShapeObject, aHypList[i] );
2041 catch( const SALOME::SALOME_Exception& ) {
2042 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2044 removeGeomGroupData( theSubShapeObject );
2046 int subMeshId = theSubMesh->GetId();
2048 _mapSubMesh.erase(subMeshId);
2049 _mapSubMesh_i.erase(subMeshId);
2050 _mapSubMeshIor.erase(subMeshId);
2051 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2054 //=============================================================================
2058 //=============================================================================
2060 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2061 const char* theName,
2062 const TopoDS_Shape& theShape )
2065 SMESH::SMESH_GroupBase_var aGroup;
2066 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2067 SMESH_GroupBase_i* aGroupImpl;
2068 if ( !theShape.IsNull() )
2069 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2071 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2073 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2074 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2075 aGroupImpl->Register();
2076 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2078 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2079 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2081 // register CORBA object for persistence
2082 int nextId = _gen_i->RegisterObject( aGroup );
2083 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2085 // to track changes of GEOM groups
2086 if ( !theShape.IsNull() ) {
2087 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2088 addGeomGroupData( geom, aGroup );
2091 return aGroup._retn();
2094 //=============================================================================
2096 * SMESH_Mesh_i::removeGroup
2098 * Should be called by ~SMESH_Group_i()
2100 //=============================================================================
2102 void SMESH_Mesh_i::removeGroup( const int theId )
2104 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2105 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2106 removeGeomGroupData( _mapGroups[theId] );
2107 _mapGroups.erase( theId );
2108 _impl->RemoveGroup( theId );
2113 //=============================================================================
2117 //=============================================================================
2119 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2120 throw(SALOME::SALOME_Exception)
2122 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2124 SMESH::log_array_var aLog;
2126 list < SMESHDS_Command * >logDS = _impl->GetLog();
2127 aLog = new SMESH::log_array;
2129 int lg = logDS.size();
2132 list < SMESHDS_Command * >::iterator its = logDS.begin();
2133 while(its != logDS.end()){
2134 SMESHDS_Command *com = *its;
2135 int comType = com->GetType();
2137 int lgcom = com->GetNumber();
2139 const list < int >&intList = com->GetIndexes();
2140 int inum = intList.size();
2142 list < int >::const_iterator ii = intList.begin();
2143 const list < double >&coordList = com->GetCoords();
2144 int rnum = coordList.size();
2146 list < double >::const_iterator ir = coordList.begin();
2147 aLog[indexLog].commandType = comType;
2148 aLog[indexLog].number = lgcom;
2149 aLog[indexLog].coords.length(rnum);
2150 aLog[indexLog].indexes.length(inum);
2151 for(int i = 0; i < rnum; i++){
2152 aLog[indexLog].coords[i] = *ir;
2153 //MESSAGE(" "<<i<<" "<<ir.Value());
2156 for(int i = 0; i < inum; i++){
2157 aLog[indexLog].indexes[i] = *ii;
2158 //MESSAGE(" "<<i<<" "<<ii.Value());
2167 catch(SALOME_Exception & S_ex){
2168 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2170 return aLog._retn();
2174 //=============================================================================
2178 //=============================================================================
2180 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2182 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2186 //=============================================================================
2190 //=============================================================================
2192 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2194 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2198 //=============================================================================
2202 //=============================================================================
2204 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2209 //=============================================================================
2213 //=============================================================================
2215 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2217 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2221 //=============================================================================
2225 //=============================================================================
2227 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2229 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2233 //=============================================================================
2235 * Return mesh editor
2237 //=============================================================================
2239 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2241 // Create MeshEditor
2242 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2243 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2245 // Update Python script
2246 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2248 return aMesh._retn();
2251 //=============================================================================
2253 * Return mesh edition previewer
2255 //=============================================================================
2257 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2259 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2260 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2261 return aMesh._retn();
2264 //================================================================================
2266 * \brief Return true if the mesh has been edited since a last total re-compute
2267 * and those modifications may prevent successful partial re-compute
2269 //================================================================================
2271 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2273 Unexpect aCatch(SALOME_SalomeException);
2274 return _impl->HasModificationsToDiscard();
2277 //=============================================================================
2281 //=============================================================================
2282 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2284 Unexpect aCatch(SALOME_SalomeException);
2285 _impl->SetAutoColor(theAutoColor);
2288 //=============================================================================
2292 //=============================================================================
2293 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2295 Unexpect aCatch(SALOME_SalomeException);
2296 return _impl->GetAutoColor();
2300 //=============================================================================
2302 * Export in different formats
2304 //=============================================================================
2306 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2308 return _impl->HasDuplicatedGroupNamesMED();
2311 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2313 TCollection_AsciiString aFullName ((char*)file);
2314 OSD_Path aPath (aFullName);
2315 OSD_File aFile (aPath);
2316 if (aFile.Exists()) {
2317 // existing filesystem node
2318 if (aFile.KindOfFile() == OSD_FILE) {
2319 if (aFile.IsWriteable()) {
2324 if (aFile.Failed()) {
2325 TCollection_AsciiString msg ("File ");
2326 msg += aFullName + " cannot be replaced.";
2327 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2330 TCollection_AsciiString msg ("File ");
2331 msg += aFullName + " cannot be overwritten.";
2332 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2335 TCollection_AsciiString msg ("Location ");
2336 msg += aFullName + " is not a file.";
2337 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2340 // nonexisting file; check if it can be created
2342 aFile.Build(OSD_WriteOnly, OSD_Protection());
2343 if (aFile.Failed()) {
2344 TCollection_AsciiString msg ("You cannot create the file ");
2345 msg += aFullName + ". Check the directory existance and access rights.";
2346 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2354 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2355 CORBA::Boolean auto_groups,
2356 SMESH::MED_VERSION theVersion,
2357 CORBA::Boolean overwrite)
2358 throw(SALOME::SALOME_Exception)
2360 Unexpect aCatch(SALOME_SalomeException);
2363 PrepareForWriting(file, overwrite);
2364 const char* aMeshName = "Mesh";
2365 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2366 if ( !aStudy->_is_nil() ) {
2367 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2368 if ( !aMeshSO->_is_nil() ) {
2369 aMeshName = aMeshSO->GetName();
2370 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2371 if ( !aStudy->GetProperties()->IsLocked() )
2373 SALOMEDS::GenericAttribute_var anAttr;
2374 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2375 SALOMEDS::AttributeExternalFileDef_var aFileName;
2376 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2377 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2378 ASSERT(!aFileName->_is_nil());
2379 aFileName->SetValue(file);
2380 SALOMEDS::AttributeFileType_var aFileType;
2381 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2382 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2383 ASSERT(!aFileType->_is_nil());
2384 aFileType->SetValue("FICHIERMED");
2388 // Update Python script
2389 // set name of mesh before export
2390 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2392 // check names of groups
2395 TPythonDump() << _this() << ".ExportToMEDX( r'"
2396 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2398 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2401 void SMESH_Mesh_i::ExportToMED (const char* file,
2402 CORBA::Boolean auto_groups,
2403 SMESH::MED_VERSION theVersion)
2404 throw(SALOME::SALOME_Exception)
2406 ExportToMEDX(file,auto_groups,theVersion,true);
2409 void SMESH_Mesh_i::ExportMED (const char* file,
2410 CORBA::Boolean auto_groups)
2411 throw(SALOME::SALOME_Exception)
2413 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2416 void SMESH_Mesh_i::ExportDAT (const char *file)
2417 throw(SALOME::SALOME_Exception)
2419 Unexpect aCatch(SALOME_SalomeException);
2421 // Update Python script
2422 // check names of groups
2424 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2427 PrepareForWriting(file);
2428 _impl->ExportDAT(file);
2431 void SMESH_Mesh_i::ExportUNV (const char *file)
2432 throw(SALOME::SALOME_Exception)
2434 Unexpect aCatch(SALOME_SalomeException);
2436 // Update Python script
2437 // check names of groups
2439 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2442 PrepareForWriting(file);
2443 _impl->ExportUNV(file);
2446 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2447 throw(SALOME::SALOME_Exception)
2449 Unexpect aCatch(SALOME_SalomeException);
2451 // Update Python script
2452 // check names of groups
2454 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2457 PrepareForWriting(file);
2458 _impl->ExportSTL(file, isascii);
2461 //=============================================================================
2465 //=============================================================================
2467 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2469 Unexpect aCatch(SALOME_SalomeException);
2470 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2471 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2472 return aMesh._retn();
2475 //=============================================================================
2479 //=============================================================================
2480 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2482 Unexpect aCatch(SALOME_SalomeException);
2483 return _impl->NbNodes();
2486 //=============================================================================
2490 //=============================================================================
2491 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2493 Unexpect aCatch(SALOME_SalomeException);
2494 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2497 //=============================================================================
2501 //=============================================================================
2502 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2504 Unexpect aCatch(SALOME_SalomeException);
2505 return _impl->Nb0DElements();
2508 //=============================================================================
2512 //=============================================================================
2513 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2515 Unexpect aCatch(SALOME_SalomeException);
2516 return _impl->NbEdges();
2519 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2520 throw(SALOME::SALOME_Exception)
2522 Unexpect aCatch(SALOME_SalomeException);
2523 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2526 //=============================================================================
2530 //=============================================================================
2531 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2533 Unexpect aCatch(SALOME_SalomeException);
2534 return _impl->NbFaces();
2537 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2539 Unexpect aCatch(SALOME_SalomeException);
2540 return _impl->NbTriangles();
2543 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2545 Unexpect aCatch(SALOME_SalomeException);
2546 return _impl->NbQuadrangles();
2549 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2551 Unexpect aCatch(SALOME_SalomeException);
2552 return _impl->NbPolygons();
2555 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2556 throw(SALOME::SALOME_Exception)
2558 Unexpect aCatch(SALOME_SalomeException);
2559 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2562 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2563 throw(SALOME::SALOME_Exception)
2565 Unexpect aCatch(SALOME_SalomeException);
2566 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2569 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2570 throw(SALOME::SALOME_Exception)
2572 Unexpect aCatch(SALOME_SalomeException);
2573 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2576 //=============================================================================
2580 //=============================================================================
2581 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2583 Unexpect aCatch(SALOME_SalomeException);
2584 return _impl->NbVolumes();
2587 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2589 Unexpect aCatch(SALOME_SalomeException);
2590 return _impl->NbTetras();
2593 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2595 Unexpect aCatch(SALOME_SalomeException);
2596 return _impl->NbHexas();
2599 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2601 Unexpect aCatch(SALOME_SalomeException);
2602 return _impl->NbPyramids();
2605 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2607 Unexpect aCatch(SALOME_SalomeException);
2608 return _impl->NbPrisms();
2611 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2613 Unexpect aCatch(SALOME_SalomeException);
2614 return _impl->NbPolyhedrons();
2617 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2618 throw(SALOME::SALOME_Exception)
2620 Unexpect aCatch(SALOME_SalomeException);
2621 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2624 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2625 throw(SALOME::SALOME_Exception)
2627 Unexpect aCatch(SALOME_SalomeException);
2628 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2631 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2632 throw(SALOME::SALOME_Exception)
2634 Unexpect aCatch(SALOME_SalomeException);
2635 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2638 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2639 throw(SALOME::SALOME_Exception)
2641 Unexpect aCatch(SALOME_SalomeException);
2642 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2645 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2646 throw(SALOME::SALOME_Exception)
2648 Unexpect aCatch(SALOME_SalomeException);
2649 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2652 //=============================================================================
2656 //=============================================================================
2657 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2659 Unexpect aCatch(SALOME_SalomeException);
2660 return _mapSubMesh_i.size();
2663 //=============================================================================
2667 //=============================================================================
2668 char* SMESH_Mesh_i::Dump()
2672 return CORBA::string_dup( os.str().c_str() );
2675 //=============================================================================
2679 //=============================================================================
2680 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2682 // SMESH::long_array_var aResult = new SMESH::long_array();
2683 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2684 // int aMinId = aSMESHDS_Mesh->MinElementID();
2685 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2687 // aResult->length(aMaxId - aMinId + 1);
2689 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2690 // aResult[i++] = id;
2692 // return aResult._retn();
2694 return GetElementsId();
2697 //=============================================================================
2701 //=============================================================================
2703 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2704 throw (SALOME::SALOME_Exception)
2706 Unexpect aCatch(SALOME_SalomeException);
2707 MESSAGE("SMESH_Mesh_i::GetElementsId");
2708 SMESH::long_array_var aResult = new SMESH::long_array();
2709 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2711 if ( aSMESHDS_Mesh == NULL )
2712 return aResult._retn();
2714 long nbElements = NbElements();
2715 aResult->length( nbElements );
2716 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2717 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2718 aResult[i] = anIt->next()->GetID();
2720 return aResult._retn();
2724 //=============================================================================
2728 //=============================================================================
2730 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2731 throw (SALOME::SALOME_Exception)
2733 Unexpect aCatch(SALOME_SalomeException);
2734 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2735 SMESH::long_array_var aResult = new SMESH::long_array();
2736 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2738 if ( aSMESHDS_Mesh == NULL )
2739 return aResult._retn();
2741 long nbElements = NbElements();
2743 // No sense in returning ids of elements along with ids of nodes:
2744 // when theElemType == SMESH::ALL, return node ids only if
2745 // there are no elements
2746 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2747 return GetNodesId();
2749 aResult->length( nbElements );
2753 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2754 while ( i < nbElements && anIt->more() ) {
2755 const SMDS_MeshElement* anElem = anIt->next();
2756 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2757 aResult[i++] = anElem->GetID();
2760 aResult->length( i );
2762 return aResult._retn();
2765 //=============================================================================
2769 //=============================================================================
2771 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2772 throw (SALOME::SALOME_Exception)
2774 Unexpect aCatch(SALOME_SalomeException);
2775 MESSAGE("SMESH_subMesh_i::GetNodesId");
2776 SMESH::long_array_var aResult = new SMESH::long_array();
2777 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2779 if ( aSMESHDS_Mesh == NULL )
2780 return aResult._retn();
2782 long nbNodes = NbNodes();
2783 aResult->length( nbNodes );
2784 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2785 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2786 aResult[i] = anIt->next()->GetID();
2788 return aResult._retn();
2791 //=============================================================================
2795 //=============================================================================
2797 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2798 throw (SALOME::SALOME_Exception)
2800 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2803 //=============================================================================
2807 //=============================================================================
2809 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2810 throw (SALOME::SALOME_Exception)
2812 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2814 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2816 return ( SMESH::EntityType ) e->GetEntityType();
2819 //=============================================================================
2821 * Returns ID of elements for given submesh
2823 //=============================================================================
2824 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2825 throw (SALOME::SALOME_Exception)
2827 SMESH::long_array_var aResult = new SMESH::long_array();
2829 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2830 if(!SM) return aResult._retn();
2832 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2833 if(!SDSM) return aResult._retn();
2835 aResult->length(SDSM->NbElements());
2837 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2839 while ( eIt->more() ) {
2840 aResult[i++] = eIt->next()->GetID();
2843 return aResult._retn();
2847 //=============================================================================
2849 * Returns ID of nodes for given submesh
2850 * If param all==true - returns all nodes, else -
2851 * returns only nodes on shapes.
2853 //=============================================================================
2854 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2855 throw (SALOME::SALOME_Exception)
2857 SMESH::long_array_var aResult = new SMESH::long_array();
2859 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2860 if(!SM) return aResult._retn();
2862 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2863 if(!SDSM) return aResult._retn();
2866 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2867 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2868 while ( nIt->more() ) {
2869 const SMDS_MeshNode* elem = nIt->next();
2870 theElems.insert( elem->GetID() );
2873 else { // all nodes of submesh elements
2874 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2875 while ( eIt->more() ) {
2876 const SMDS_MeshElement* anElem = eIt->next();
2877 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2878 while ( nIt->more() ) {
2879 const SMDS_MeshElement* elem = nIt->next();
2880 theElems.insert( elem->GetID() );
2885 aResult->length(theElems.size());
2886 set<int>::iterator itElem;
2888 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2889 aResult[i++] = *itElem;
2891 return aResult._retn();
2895 //=============================================================================
2897 * Returns type of elements for given submesh
2899 //=============================================================================
2900 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2901 throw (SALOME::SALOME_Exception)
2903 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2904 if(!SM) return SMESH::ALL;
2906 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2907 if(!SDSM) return SMESH::ALL;
2909 if(SDSM->NbElements()==0)
2910 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2912 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2913 const SMDS_MeshElement* anElem = eIt->next();
2914 return ( SMESH::ElementType ) anElem->GetType();
2918 //=============================================================================
2922 //=============================================================================
2924 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2926 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2928 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2933 //=============================================================================
2935 * Get XYZ coordinates of node as list of double
2936 * If there is not node for given ID - returns empty list
2938 //=============================================================================
2940 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2942 SMESH::double_array_var aResult = new SMESH::double_array();
2943 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2944 if ( aSMESHDS_Mesh == NULL )
2945 return aResult._retn();
2948 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2950 return aResult._retn();
2954 aResult[0] = aNode->X();
2955 aResult[1] = aNode->Y();
2956 aResult[2] = aNode->Z();
2957 return aResult._retn();
2961 //=============================================================================
2963 * For given node returns list of IDs of inverse elements
2964 * If there is not node for given ID - returns empty list
2966 //=============================================================================
2968 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2970 SMESH::long_array_var aResult = new SMESH::long_array();
2971 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2972 if ( aSMESHDS_Mesh == NULL )
2973 return aResult._retn();
2976 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2978 return aResult._retn();
2980 // find inverse elements
2981 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2982 TColStd_SequenceOfInteger IDs;
2983 while(eIt->more()) {
2984 const SMDS_MeshElement* elem = eIt->next();
2985 IDs.Append(elem->GetID());
2987 if(IDs.Length()>0) {
2988 aResult->length(IDs.Length());
2990 for(; i<=IDs.Length(); i++) {
2991 aResult[i-1] = IDs.Value(i);
2994 return aResult._retn();
2997 //=============================================================================
2999 * \brief Return position of a node on shape
3001 //=============================================================================
3003 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3005 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3006 aNodePosition->shapeID = 0;
3007 aNodePosition->shapeType = GEOM::SHAPE;
3009 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3010 if ( !mesh ) return aNodePosition;
3012 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3014 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3016 aNodePosition->shapeID = pos->GetShapeId();
3017 switch ( pos->GetTypeOfPosition() ) {
3019 aNodePosition->shapeType = GEOM::EDGE;
3020 aNodePosition->params.length(1);
3021 aNodePosition->params[0] =
3022 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
3025 aNodePosition->shapeType = GEOM::FACE;
3026 aNodePosition->params.length(2);
3027 aNodePosition->params[0] =
3028 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
3029 aNodePosition->params[1] =
3030 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
3032 case SMDS_TOP_VERTEX:
3033 aNodePosition->shapeType = GEOM::VERTEX;
3035 case SMDS_TOP_3DSPACE:
3036 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3037 aNodePosition->shapeType = GEOM::SOLID;
3038 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3039 aNodePosition->shapeType = GEOM::SHELL;
3045 return aNodePosition;
3048 //=============================================================================
3050 * If given element is node returns IDs of shape from position
3051 * If there is not node for given ID - returns -1
3053 //=============================================================================
3055 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3057 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3058 if ( aSMESHDS_Mesh == NULL )
3062 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3064 SMDS_PositionPtr pos = aNode->GetPosition();
3068 return pos->GetShapeId();
3075 //=============================================================================
3077 * For given element returns ID of result shape after
3078 * ::FindShape() from SMESH_MeshEditor
3079 * If there is not element for given ID - returns -1
3081 //=============================================================================
3083 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3085 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3086 if ( aSMESHDS_Mesh == NULL )
3089 // try to find element
3090 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3094 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3095 ::SMESH_MeshEditor aMeshEditor(_impl);
3096 int index = aMeshEditor.FindShape( elem );
3104 //=============================================================================
3106 * Returns number of nodes for given element
3107 * If there is not element for given ID - returns -1
3109 //=============================================================================
3111 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3113 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3114 if ( aSMESHDS_Mesh == NULL ) return -1;
3115 // try to find element
3116 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3117 if(!elem) return -1;
3118 return elem->NbNodes();
3122 //=============================================================================
3124 * Returns ID of node by given index for given element
3125 * If there is not element for given ID - returns -1
3126 * If there is not node for given index - returns -2
3128 //=============================================================================
3130 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3132 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3133 if ( aSMESHDS_Mesh == NULL ) return -1;
3134 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3135 if(!elem) return -1;
3136 if( index>=elem->NbNodes() || index<0 ) return -1;
3137 return elem->GetNode(index)->GetID();
3140 //=============================================================================
3142 * Returns IDs of nodes of given element
3144 //=============================================================================
3146 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3148 SMESH::long_array_var aResult = new SMESH::long_array();
3149 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3151 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3153 aResult->length( elem->NbNodes() );
3154 for ( int i = 0; i < elem->NbNodes(); ++i )
3155 aResult[ i ] = elem->GetNode( i )->GetID();
3158 return aResult._retn();
3161 //=============================================================================
3163 * Returns true if given node is medium node
3164 * in given quadratic element
3166 //=============================================================================
3168 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3170 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3171 if ( aSMESHDS_Mesh == NULL ) return false;
3173 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3174 if(!aNode) return false;
3175 // try to find element
3176 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3177 if(!elem) return false;
3179 return elem->IsMediumNode(aNode);
3183 //=============================================================================
3185 * Returns true if given node is medium node
3186 * in one of quadratic elements
3188 //=============================================================================
3190 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3191 SMESH::ElementType theElemType)
3193 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3194 if ( aSMESHDS_Mesh == NULL ) return false;
3197 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3198 if(!aNode) return false;
3200 SMESH_MesherHelper aHelper( *(_impl) );
3202 SMDSAbs_ElementType aType;
3203 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3204 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3205 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3206 else aType = SMDSAbs_All;
3208 return aHelper.IsMedium(aNode,aType);
3212 //=============================================================================
3214 * Returns number of edges for given element
3216 //=============================================================================
3218 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3220 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3221 if ( aSMESHDS_Mesh == NULL ) return -1;
3222 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3223 if(!elem) return -1;
3224 return elem->NbEdges();
3228 //=============================================================================
3230 * Returns number of faces for given element
3232 //=============================================================================
3234 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3236 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3237 if ( aSMESHDS_Mesh == NULL ) return -1;
3238 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3239 if(!elem) return -1;
3240 return elem->NbFaces();
3243 //=======================================================================
3244 //function : GetElemFaceNodes
3245 //purpose : Returns nodes of given face (counted from zero) for given element.
3246 //=======================================================================
3248 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3249 CORBA::Short faceIndex)
3251 SMESH::long_array_var aResult = new SMESH::long_array();
3252 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3254 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3256 SMDS_VolumeTool vtool( elem );
3257 if ( faceIndex < vtool.NbFaces() )
3259 aResult->length( vtool.NbFaceNodes( faceIndex ));
3260 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3261 for ( int i = 0; i < aResult->length(); ++i )
3262 aResult[ i ] = nn[ i ]->GetID();
3266 return aResult._retn();
3269 //=======================================================================
3270 //function : FindElementByNodes
3271 //purpose : Returns an element based on all given nodes.
3272 //=======================================================================
3274 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3276 CORBA::Long elemID(0);
3277 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3279 vector< const SMDS_MeshNode * > nn( nodes.length() );
3280 for ( int i = 0; i < nodes.length(); ++i )
3281 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3284 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3285 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3286 _impl->NbFaces( ORDER_QUADRATIC ) ||
3287 _impl->NbVolumes( ORDER_QUADRATIC )))
3288 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3290 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3295 //=============================================================================
3297 * Returns true if given element is polygon
3299 //=============================================================================
3301 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3303 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3304 if ( aSMESHDS_Mesh == NULL ) return false;
3305 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3306 if(!elem) return false;
3307 return elem->IsPoly();
3311 //=============================================================================
3313 * Returns true if given element is quadratic
3315 //=============================================================================
3317 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3319 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3320 if ( aSMESHDS_Mesh == NULL ) return false;
3321 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3322 if(!elem) return false;
3323 return elem->IsQuadratic();
3327 //=============================================================================
3329 * Returns bary center for given element
3331 //=============================================================================
3333 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3335 SMESH::double_array_var aResult = new SMESH::double_array();
3336 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3337 if ( aSMESHDS_Mesh == NULL )
3338 return aResult._retn();
3340 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3342 return aResult._retn();
3344 if(elem->GetType()==SMDSAbs_Volume) {
3345 SMDS_VolumeTool aTool;
3346 if(aTool.Set(elem)) {
3348 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3353 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3355 double x=0., y=0., z=0.;
3356 for(; anIt->more(); ) {
3358 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3372 return aResult._retn();
3376 //=============================================================================
3378 * Create and publish group servants if any groups were imported or created anyhow
3380 //=============================================================================
3382 void SMESH_Mesh_i::CreateGroupServants()
3384 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3386 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3387 while ( groupIt->more() )
3389 ::SMESH_Group* group = groupIt->next();
3390 int anId = group->GetGroupDS()->GetID();
3392 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3393 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3396 SMESH_GroupBase_i* aGroupImpl;
3398 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3399 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3401 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3402 shape = groupOnGeom->GetShape();
3405 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3408 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3409 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3410 aGroupImpl->Register();
3412 SMESH::SMESH_GroupBase_var groupVar =
3413 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3414 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3416 // register CORBA object for persistence
3417 int nextId = _gen_i->RegisterObject( groupVar );
3418 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3420 // publishing of the groups in the study
3421 if ( !aStudy->_is_nil() ) {
3422 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3423 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3428 //=============================================================================
3430 * \brief Return groups cantained in _mapGroups by their IDs
3432 //=============================================================================
3434 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3436 int nbGroups = groupIDs.size();
3437 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3438 aList->length( nbGroups );
3440 list<int>::const_iterator ids = groupIDs.begin();
3441 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3443 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3444 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3445 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3447 aList->length( nbGroups );
3448 return aList._retn();
3451 //=============================================================================
3453 * \brief Return information about imported file
3455 //=============================================================================
3457 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3459 SALOME_MED::MedFileInfo_var res( myFileInfo );
3460 if ( !res.operator->() ) {
3461 res = new SALOME_MED::MedFileInfo;
3463 res->fileSize = res->major = res->minor = res->release = -1;
3468 //=============================================================================
3470 * \brief Check and correct names of mesh groups
3472 //=============================================================================
3474 void SMESH_Mesh_i::checkGroupNames()
3476 int nbGrp = NbGroups();
3480 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3481 if ( aStudy->_is_nil() )
3482 return; // nothing to do
3484 SMESH::ListOfGroups* grpList = 0;
3485 // avoid dump of "GetGroups"
3487 // store python dump into a local variable inside local scope
3488 SMESH::TPythonDump pDump; // do not delete this line of code
3489 grpList = GetGroups();
3492 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3493 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3496 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3497 if ( aGrpSO->_is_nil() )
3499 // correct name of the mesh group if necessary
3500 const char* guiName = aGrpSO->GetName();
3501 if ( strcmp(guiName, aGrp->GetName()) )
3502 aGrp->SetName( guiName );
3506 //=============================================================================
3508 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3510 //=============================================================================
3511 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3513 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3514 CORBA::string_dup(theParameters));
3517 //=============================================================================
3519 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3521 //=============================================================================
3522 char* SMESH_Mesh_i::GetParameters()
3524 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3525 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3528 //=============================================================================
3530 * \brief Returns list of notebook variables used for last Mesh operation
3532 //=============================================================================
3533 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3535 SMESH::string_array_var aResult = new SMESH::string_array();
3536 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3538 char *aParameters = GetParameters();
3539 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3540 if(!aStudy->_is_nil()) {
3541 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3542 if(aSections->length() > 0) {
3543 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3544 aResult->length(aVars.length());
3545 for(int i = 0;i < aVars.length();i++)
3546 aResult[i] = CORBA::string_dup( aVars[i]);
3550 return aResult._retn();
3553 //=======================================================================
3554 //function : GetTypes
3555 //purpose : Returns types of elements it contains
3556 //=======================================================================
3558 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3560 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3564 if (_impl->NbEdges())
3565 types[nbTypes++] = SMESH::EDGE;
3566 if (_impl->NbFaces())
3567 types[nbTypes++] = SMESH::FACE;
3568 if (_impl->NbVolumes())
3569 types[nbTypes++] = SMESH::VOLUME;
3570 if (_impl->Nb0DElements())
3571 types[nbTypes++] = SMESH::ELEM0D;
3572 types->length( nbTypes );
3574 return types._retn();
3577 //=============================================================================
3579 * \brief Returns statistic of mesh elements
3581 //=============================================================================
3582 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3584 SMESH::long_array_var aRes = new SMESH::long_array();
3585 aRes->length(SMESH::Entity_Last);
3586 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3588 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3590 return aRes._retn();
3591 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3592 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3593 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3594 return aRes._retn();
3597 //=============================================================================
3599 * \brief Collect statistic of mesh elements given by iterator
3601 //=============================================================================
3602 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3603 SMESH::long_array& theInfo)
3605 if (!theItr) return;
3606 while (theItr->more())
3607 theInfo[ theItr->next()->GetEntityType() ]++;
3610 //=============================================================================
3612 * \brief mapping of mesh dimension into shape type
3614 //=============================================================================
3615 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3617 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3619 case 0: aType = TopAbs_VERTEX; break;
3620 case 1: aType = TopAbs_EDGE; break;
3621 case 2: aType = TopAbs_FACE; break;
3623 default:aType = TopAbs_SOLID; break;
3628 //=============================================================================
3630 * \brief Internal structure used to find concurent submeshes
3632 * It represents a pair < submesh, concurent dimension >, where
3633 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3634 * with another submesh. In other words, it is dimension of a hypothesis assigned
3637 //=============================================================================
3643 int _dim; //!< a dimension the algo can build (concurrent dimension)
3644 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3645 TopTools_MapOfShape _shapeMap;
3646 SMESH_subMesh* _subMesh;
3647 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3650 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3652 const TopoDS_Shape& theShape)
3654 _subMesh = (SMESH_subMesh*)theSubMesh;
3655 SetShape( theDim, theShape );
3659 void SetShape(const int theDim,
3660 const TopoDS_Shape& theShape)
3663 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3664 if (_dim >= _ownDim)
3665 _shapeMap.Add( theShape );
3667 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3668 for( ; anExp.More(); anExp.Next() )
3669 _shapeMap.Add( anExp.Current() );
3673 //! Check sharing of sub shapes
3674 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3675 const TopTools_MapOfShape& theToFind,
3676 const TopAbs_ShapeEnum theType)
3678 bool isShared = false;
3679 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3680 for (; !isShared && anItr.More(); anItr.Next() ) {
3681 const TopoDS_Shape aSubSh = anItr.Key();
3682 // check for case when concurrent dimensions are same
3683 isShared = theToFind.Contains( aSubSh );
3684 // check for subshape with concurrent dimension
3685 TopExp_Explorer anExp( aSubSh, theType );
3686 for ( ; !isShared && anExp.More(); anExp.Next() )
3687 isShared = theToFind.Contains( anExp.Current() );
3692 //! check algorithms
3693 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3694 const SMESHDS_Hypothesis* theA2)
3696 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3697 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3698 return false; // one of the hypothesis is not algorithm
3699 // check algorithm names (should be equal)
3700 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3704 //! Check if subshape hypotheses are concurrent
3705 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3707 if ( _subMesh == theOther->_subMesh )
3708 return false; // same subshape - should not be
3710 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3711 // any of the two submeshes is not on COMPOUND shape )
3712 // -> no concurrency
3713 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3714 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3715 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3718 // bool checkSubShape = ( _dim >= theOther->_dim )
3719 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3720 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3721 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3722 if ( !checkSubShape )
3725 // check algorithms to be same
3726 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3727 return true; // different algorithms
3729 // check hypothesises for concurrence (skip first as algorithm)
3731 // pointers should be same, becase it is referenes from mesh hypothesis partition
3732 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3733 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3734 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3735 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3737 // the submeshes are concurrent if their algorithms has different parameters
3738 return nbSame != theOther->_hypothesises.size() - 1;
3741 }; // end of SMESH_DimHyp
3743 typedef list<SMESH_DimHyp*> TDimHypList;
3745 static void addDimHypInstance(const int theDim,
3746 const TopoDS_Shape& theShape,
3747 const SMESH_Algo* theAlgo,
3748 const SMESH_subMesh* theSubMesh,
3749 const list <const SMESHDS_Hypothesis*>& theHypList,
3750 TDimHypList* theDimHypListArr )
3752 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3753 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3754 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3755 listOfdimHyp.push_back( dimHyp );
3758 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3759 dimHyp->_hypothesises.push_front(theAlgo);
3760 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3761 for( ; hypIt != theHypList.end(); hypIt++ )
3762 dimHyp->_hypothesises.push_back( *hypIt );
3765 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3766 const TDimHypList& theListOfDimHyp,
3767 TListOfInt& theListOfConcurr )
3769 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3770 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3771 const SMESH_DimHyp* curDimHyp = *rIt;
3772 if ( curDimHyp == theDimHyp )
3773 break; // meet own dimHyp pointer in same dimension
3774 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3775 if ( find( theListOfConcurr.begin(),
3776 theListOfConcurr.end(),
3777 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3778 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3782 static void unionLists(TListOfInt& theListOfId,
3783 TListOfListOfInt& theListOfListOfId,
3786 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3787 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3789 continue; //skip already treated lists
3790 // check if other list has any same submesh object
3791 TListOfInt& otherListOfId = *it;
3792 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3793 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3796 // union two lists (from source into target)
3797 TListOfInt::iterator it2 = otherListOfId.begin();
3798 for ( ; it2 != otherListOfId.end(); it2++ ) {
3799 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3800 theListOfId.push_back(*it2);
3802 // clear source list
3803 otherListOfId.clear();
3807 //! free memory allocated for dimension-hypothesis objects
3808 static void removeDimHyps( TDimHypList* theArrOfList )
3810 for (int i = 0; i < 4; i++ ) {
3811 TDimHypList& listOfdimHyp = theArrOfList[i];
3812 TDimHypList::const_iterator it = listOfdimHyp.begin();
3813 for ( ; it != listOfdimHyp.end(); it++ )
3818 //=============================================================================
3820 * \brief Return submesh objects list in meshing order
3822 //=============================================================================
3824 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3826 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3828 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3830 return aResult._retn();
3832 ::SMESH_Mesh& mesh = GetImpl();
3833 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3834 if ( !anOrder.size() ) {
3836 // collect submeshes detecting concurrent algorithms and hypothesises
3837 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3839 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3840 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3841 ::SMESH_subMesh* sm = (*i_sm).second;
3843 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3845 // list of assigned hypothesises
3846 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3847 // Find out dimensions where the submesh can be concurrent.
3848 // We define the dimensions by algo of each of hypotheses in hypList
3849 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3850 for( ; hypIt != hypList.end(); hypIt++ ) {
3851 SMESH_Algo* anAlgo = 0;
3852 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3853 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3854 // hyp it-self is algo
3855 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3857 // try to find algorithm with help of subshapes
3858 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3859 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3860 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3863 continue; // no assigned algorithm to current submesh
3865 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3866 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3868 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3869 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3870 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3872 } // end iterations on submesh
3874 // iterate on created dimension-hypotheses and check for concurrents
3875 for ( int i = 0; i < 4; i++ ) {
3876 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3877 // check for concurrents in own and other dimensions (step-by-step)
3878 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3879 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3880 const SMESH_DimHyp* dimHyp = *dhIt;
3881 TListOfInt listOfConcurr;
3882 // looking for concurrents and collect into own list
3883 for ( int j = i; j < 4; j++ )
3884 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3885 // check if any concurrents found
3886 if ( listOfConcurr.size() > 0 ) {
3887 // add own submesh to list of concurrent
3888 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3889 anOrder.push_back( listOfConcurr );
3894 removeDimHyps(dimHypListArr);
3896 // now, minimise the number of concurrent groups
3897 // Here we assume that lists of submhes can has same submesh
3898 // in case of multi-dimension algorithms, as result
3899 // list with common submesh have to be union into one list
3901 TListOfListOfInt::iterator listIt = anOrder.begin();
3902 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3903 unionLists( *listIt, anOrder, listIndx + 1 );
3905 // convert submesh ids into interface instances
3906 // and dump command into python
3907 convertMeshOrder( anOrder, aResult, true );
3909 return aResult._retn();
3912 //=============================================================================
3914 * \brief find common submeshes with given submesh
3915 * \param theSubMeshList list of already collected submesh to check
3916 * \param theSubMesh given submesh to intersect with other
3917 * \param theCommonSubMeshes collected common submeshes
3919 //=============================================================================
3921 static void findCommonSubMesh
3922 (list<const SMESH_subMesh*>& theSubMeshList,
3923 const SMESH_subMesh* theSubMesh,
3924 set<const SMESH_subMesh*>& theCommon )
3928 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
3929 for ( ; it != theSubMeshList.end(); it++ )
3930 theSubMesh->FindIntersection( *it, theCommon );
3931 theSubMeshList.push_back( theSubMesh );
3932 //theCommon.insert( theSubMesh );
3935 //=============================================================================
3937 * \brief Set submesh object order
3938 * \param theSubMeshArray submesh array order
3940 //=============================================================================
3942 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
3945 ::SMESH_Mesh& mesh = GetImpl();
3947 TPythonDump aPythonDump; // prevent dump of called methods
3948 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
3950 TListOfListOfInt subMeshOrder;
3951 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
3953 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
3954 TListOfInt subMeshIds;
3955 aPythonDump << "[ ";
3956 // Collect subMeshes which should be clear
3957 // do it list-by-list, because modification of submesh order
3958 // take effect between concurrent submeshes only
3959 set<const SMESH_subMesh*> subMeshToClear;
3960 list<const SMESH_subMesh*> subMeshList;
3961 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
3963 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
3965 aPythonDump << ", ";
3966 aPythonDump << subMesh;
3967 subMeshIds.push_back( subMesh->GetId() );
3968 // detect common parts of submeshes
3969 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
3970 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
3972 aPythonDump << " ]";
3973 subMeshOrder.push_back( subMeshIds );
3975 // clear collected submeshes
3976 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
3977 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
3978 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
3980 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
3981 // ClearSubMesh( *clrIt );
3984 aPythonDump << " ])";
3986 mesh.SetMeshOrder( subMeshOrder );
3992 //=============================================================================
3994 * \brief Convert submesh ids into submesh interfaces
3996 //=============================================================================
3998 void SMESH_Mesh_i::convertMeshOrder
3999 (const TListOfListOfInt& theIdsOrder,
4000 SMESH::submesh_array_array& theResOrder,
4001 const bool theIsDump)
4003 int nbSet = theIdsOrder.size();
4004 TPythonDump aPythonDump; // prevent dump of called methods
4006 aPythonDump << "[ ";
4007 theResOrder.length(nbSet);
4008 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4010 for( ; it != theIdsOrder.end(); it++ ) {
4011 // translate submesh identificators into submesh objects
4012 // takeing into account real number of concurrent lists
4013 const TListOfInt& aSubOrder = (*it);
4014 if (!aSubOrder.size())
4017 aPythonDump << "[ ";
4018 // convert shape indeces into interfaces
4019 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4020 aResSubSet->length(aSubOrder.size());
4021 TListOfInt::const_iterator subIt = aSubOrder.begin();
4022 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4023 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4025 SMESH::SMESH_subMesh_var subMesh =
4026 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4029 aPythonDump << ", ";
4030 aPythonDump << subMesh;
4032 aResSubSet[ j++ ] = subMesh;
4035 aPythonDump << " ]";
4036 theResOrder[ listIndx++ ] = aResSubSet;
4038 // correct number of lists
4039 theResOrder.length( listIndx );
4042 // finilise python dump
4043 aPythonDump << " ]";
4044 aPythonDump << " = " << _this() << ".GetMeshOrder()";