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 );
658 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
659 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
661 subMesh = getSubMesh( subMeshId );
663 // create a new subMesh object servant if there is none for the shape
664 if ( subMesh->_is_nil() )
665 subMesh = createSubMesh( aSubShapeObject );
666 if ( _gen_i->CanPublishInStudy( subMesh )) {
667 SALOMEDS::SObject_var aSO =
668 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
669 subMesh, aSubShapeObject, theName );
670 if ( !aSO->_is_nil()) {
671 // Update Python script
672 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
673 << aSubShapeObject << ", '" << theName << "' )";
677 catch(SALOME_Exception & S_ex) {
678 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
680 return subMesh._retn();
683 //=============================================================================
687 //=============================================================================
689 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
690 throw (SALOME::SALOME_Exception)
692 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
693 if ( theSubMesh->_is_nil() )
696 GEOM::GEOM_Object_var aSubShapeObject;
697 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
698 if ( !aStudy->_is_nil() ) {
699 // Remove submesh's SObject
700 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
701 if ( !anSO->_is_nil() ) {
702 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
703 SALOMEDS::SObject_var anObj, aRef;
704 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
705 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
707 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
708 // aSubShapeObject = theSubMesh->GetSubShape();
710 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
712 // Update Python script
713 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
717 removeSubMesh( theSubMesh, aSubShapeObject.in() );
720 //=============================================================================
724 //=============================================================================
725 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
726 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
728 switch (theElemType) {
733 CASE2STRING( VOLUME );
734 CASE2STRING( ELEM0D );
740 //=============================================================================
744 //=============================================================================
746 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
747 const char* theName )
748 throw(SALOME::SALOME_Exception)
750 Unexpect aCatch(SALOME_SalomeException);
751 SMESH::SMESH_Group_var aNewGroup =
752 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
754 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
755 SALOMEDS::SObject_var aSO =
756 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
757 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
758 if ( !aSO->_is_nil()) {
759 // Update Python script
760 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
761 << ElementTypeString(theElemType) << ", '" << theName << "' )";
764 return aNewGroup._retn();
768 //=============================================================================
772 //=============================================================================
773 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
775 GEOM::GEOM_Object_ptr theGeomObj)
776 throw(SALOME::SALOME_Exception)
778 Unexpect aCatch(SALOME_SalomeException);
779 SMESH::SMESH_GroupOnGeom_var aNewGroup;
781 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
782 if ( !aShape.IsNull() )
784 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
785 ( createGroup( theElemType, theName, aShape ));
787 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
788 SALOMEDS::SObject_var aSO =
789 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
790 aNewGroup, theGeomObj, theName);
791 if ( !aSO->_is_nil()) {
792 // Update Python script
793 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
794 << ElementTypeString(theElemType) << ", '" << theName << "', "
795 << theGeomObj << " )";
800 return aNewGroup._retn();
803 //=============================================================================
807 //=============================================================================
809 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
810 throw (SALOME::SALOME_Exception)
812 if ( theGroup->_is_nil() )
815 SMESH_GroupBase_i* aGroup =
816 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
820 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
821 if ( !aStudy->_is_nil() ) {
822 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
824 if ( !aGroupSO->_is_nil() ) {
825 // Update Python script
826 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
828 // Remove group's SObject
829 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
833 // Remove the group from SMESH data structures
834 removeGroup( aGroup->GetLocalID() );
837 //=============================================================================
838 /*! RemoveGroupWithContents
839 * Remove group with its contents
841 //=============================================================================
842 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
843 throw (SALOME::SALOME_Exception)
845 if ( theGroup->_is_nil() )
848 SMESH_GroupBase_i* aGroup =
849 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
853 SMESH::long_array_var anIds = aGroup->GetListOfID();
854 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
856 // Update Python script
857 TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
860 if ( aGroup->GetType() == SMESH::NODE )
861 aMeshEditor->RemoveNodes( anIds );
863 aMeshEditor->RemoveElements( anIds );
866 RemoveGroup( theGroup );
868 // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
869 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
870 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
874 //================================================================================
876 * \brief Get the list of groups existing in the mesh
877 * \retval SMESH::ListOfGroups * - list of groups
879 //================================================================================
881 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
883 Unexpect aCatch(SALOME_SalomeException);
884 if (MYDEBUG) MESSAGE("GetGroups");
886 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
889 TPythonDump aPythonDump;
890 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
894 aList->length( _mapGroups.size() );
896 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
897 for ( ; it != _mapGroups.end(); it++ ) {
898 if ( CORBA::is_nil( it->second )) continue;
899 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
901 if (i > 1) aPythonDump << ", ";
902 aPythonDump << it->second;
906 catch(SALOME_Exception & S_ex) {
907 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
910 // Update Python script
911 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
912 aPythonDump << " ] = " << _this() << ".GetGroups()";
914 return aList._retn();
916 //=============================================================================
918 * Get number of groups existing in the mesh
920 //=============================================================================
922 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
924 Unexpect aCatch(SALOME_SalomeException);
925 return _mapGroups.size();
928 //=============================================================================
930 * New group is created. All mesh elements that are
931 * present in initial groups are added to the new one
933 //=============================================================================
934 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
935 SMESH::SMESH_GroupBase_ptr theGroup2,
936 const char* theName )
937 throw (SALOME::SALOME_Exception)
941 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
942 theGroup1->GetType() != theGroup2->GetType() )
943 return SMESH::SMESH_Group::_nil();
946 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
947 if ( aResGrp->_is_nil() )
948 return SMESH::SMESH_Group::_nil();
950 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
951 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
953 TColStd_MapOfInteger aResMap;
955 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
956 aResMap.Add( anIds1[ i1 ] );
958 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
959 aResMap.Add( anIds2[ i2 ] );
961 SMESH::long_array_var aResIds = new SMESH::long_array;
962 aResIds->length( aResMap.Extent() );
965 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
966 for( ; anIter.More(); anIter.Next() )
967 aResIds[ resI++ ] = anIter.Key();
969 aResGrp->Add( aResIds );
971 // Clear python lines, created by CreateGroup() and Add()
972 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
973 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
974 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
976 // Update Python script
977 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
978 << theGroup1 << ", " << theGroup2 << ", '"
981 return aResGrp._retn();
985 return SMESH::SMESH_Group::_nil();
989 //=============================================================================
991 \brief Union list of groups. New group is created. All mesh elements that are
992 present in initial groups are added to the new one.
993 \param theGroups list of groups
994 \param theName name of group to be created
995 \return pointer on the group
997 //=============================================================================
998 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
999 const char* theName )
1000 throw (SALOME::SALOME_Exception)
1003 return SMESH::SMESH_Group::_nil();
1007 NCollection_Map< int > anIds;
1008 SMESH::ElementType aType = SMESH::ALL;
1009 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1011 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1012 if ( CORBA::is_nil( aGrp ) )
1016 SMESH::ElementType aCurrType = aGrp->GetType();
1017 if ( aType == SMESH::ALL )
1021 if ( aType != aCurrType )
1022 return SMESH::SMESH_Group::_nil();
1026 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1027 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1029 int aCurrId = aCurrIds[ i ];
1030 anIds.Add( aCurrId );
1035 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1036 if ( aResGrp->_is_nil() )
1037 return SMESH::SMESH_Group::_nil();
1039 // Create array of identifiers
1040 SMESH::long_array_var aResIds = new SMESH::long_array;
1041 aResIds->length( anIds.Extent() );
1043 NCollection_Map< int >::Iterator anIter( anIds );
1044 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1046 aResIds[ i ] = anIter.Value();
1048 aResGrp->Add( aResIds );
1050 // Clear python lines, created by CreateGroup() and Add()
1051 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1052 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1053 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1055 // Update Python script
1057 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1058 << &theGroups << ", '" << theName << "' )";
1060 return aResGrp._retn();
1064 return SMESH::SMESH_Group::_nil();
1068 //=============================================================================
1070 * New group is created. All mesh elements that are
1071 * present in both initial groups are added to the new one.
1073 //=============================================================================
1074 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1075 SMESH::SMESH_GroupBase_ptr theGroup2,
1076 const char* theName )
1077 throw (SALOME::SALOME_Exception)
1079 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1080 theGroup1->GetType() != theGroup2->GetType() )
1081 return SMESH::SMESH_Group::_nil();
1083 // Create Intersection
1084 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1085 if ( aResGrp->_is_nil() )
1088 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1089 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1091 TColStd_MapOfInteger aMap1;
1093 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1094 aMap1.Add( anIds1[ i1 ] );
1096 TColStd_SequenceOfInteger aSeq;
1098 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1099 if ( aMap1.Contains( anIds2[ i2 ] ) )
1100 aSeq.Append( anIds2[ i2 ] );
1102 SMESH::long_array_var aResIds = new SMESH::long_array;
1103 aResIds->length( aSeq.Length() );
1105 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1106 aResIds[ resI ] = aSeq( resI + 1 );
1108 aResGrp->Add( aResIds );
1110 // Clear python lines, created by CreateGroup() and Add()
1111 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1112 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1113 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1115 // Update Python script
1116 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1117 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1119 return aResGrp._retn();
1122 //=============================================================================
1124 \brief Intersect list of groups. New group is created. All mesh elements that
1125 are present in all initial groups simultaneously are added to the new one.
1126 \param theGroups list of groups
1127 \param theName name of group to be created
1128 \return pointer on the group
1130 //=============================================================================
1131 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1132 const SMESH::ListOfGroups& theGroups, const char* theName )
1133 throw (SALOME::SALOME_Exception)
1136 return SMESH::SMESH_Group::_nil();
1140 NCollection_DataMap< int, int > anIdToCount;
1141 SMESH::ElementType aType = SMESH::ALL;
1142 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1144 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1145 if ( CORBA::is_nil( aGrp ) )
1149 SMESH::ElementType aCurrType = aGrp->GetType();
1150 if ( aType == SMESH::ALL )
1154 if ( aType != aCurrType )
1155 return SMESH::SMESH_Group::_nil();
1158 // calculates number of occurance ids in groups
1159 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1160 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1162 int aCurrId = aCurrIds[ i ];
1163 if ( !anIdToCount.IsBound( aCurrId ) )
1164 anIdToCount.Bind( aCurrId, 1 );
1166 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1170 // create map of ids
1171 int nbGrp = theGroups.length();
1172 NCollection_Map< int > anIds;
1173 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1174 for ( ; anIter.More(); anIter.Next() )
1176 int aCurrId = anIter.Key();
1177 int aCurrNb = anIter.Value();
1178 if ( aCurrNb == nbGrp )
1179 anIds.Add( aCurrId );
1183 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1184 if ( aResGrp->_is_nil() )
1185 return SMESH::SMESH_Group::_nil();
1187 // Create array of identifiers
1188 SMESH::long_array_var aResIds = new SMESH::long_array;
1189 aResIds->length( anIds.Extent() );
1191 NCollection_Map< int >::Iterator aListIter( anIds );
1192 for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1194 aResIds[ i ] = aListIter.Value();
1196 aResGrp->Add( aResIds );
1198 // Clear python lines, created by CreateGroup() and Add()
1199 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1200 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1201 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1203 // Update Python script
1205 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1206 << &theGroups << ", '" << theName << "' )";
1208 return aResGrp._retn();
1212 return SMESH::SMESH_Group::_nil();
1216 //=============================================================================
1218 * New group is created. All mesh elements that are present in
1219 * main group but do not present in tool group are added to the new one
1221 //=============================================================================
1222 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1223 SMESH::SMESH_GroupBase_ptr theGroup2,
1224 const char* theName )
1225 throw (SALOME::SALOME_Exception)
1227 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1228 theGroup1->GetType() != theGroup2->GetType() )
1229 return SMESH::SMESH_Group::_nil();
1232 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1233 if ( aResGrp->_is_nil() )
1236 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1237 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1239 TColStd_MapOfInteger aMap2;
1241 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1242 aMap2.Add( anIds2[ i2 ] );
1244 TColStd_SequenceOfInteger aSeq;
1245 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1246 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1247 aSeq.Append( anIds1[ i1 ] );
1249 SMESH::long_array_var aResIds = new SMESH::long_array;
1250 aResIds->length( aSeq.Length() );
1252 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1253 aResIds[ resI ] = aSeq( resI + 1 );
1255 aResGrp->Add( aResIds );
1257 // Clear python lines, created by CreateGroup() and Add()
1258 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1259 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1260 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1262 // Update Python script
1263 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1264 << theGroup1 << ", " << theGroup2 << ", '"
1265 << theName << "' )";
1267 return aResGrp._retn();
1270 //=============================================================================
1272 \brief Cut lists of groups. New group is created. All mesh elements that are
1273 present in main groups but do not present in tool groups are added to the new one
1274 \param theMainGroups list of main groups
1275 \param theToolGroups list of tool groups
1276 \param theName name of group to be created
1277 \return pointer on the group
1279 //=============================================================================
1280 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1281 const SMESH::ListOfGroups& theMainGroups,
1282 const SMESH::ListOfGroups& theToolGroups,
1283 const char* theName )
1284 throw (SALOME::SALOME_Exception)
1287 return SMESH::SMESH_Group::_nil();
1291 NCollection_Map< int > aToolIds;
1292 SMESH::ElementType aType = SMESH::ALL;
1294 // iterate through tool groups
1295 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1297 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1298 if ( CORBA::is_nil( aGrp ) )
1302 SMESH::ElementType aCurrType = aGrp->GetType();
1303 if ( aType == SMESH::ALL )
1307 if ( aType != aCurrType )
1308 return SMESH::SMESH_Group::_nil();
1312 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1313 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1315 int aCurrId = aCurrIds[ i ];
1316 aToolIds.Add( aCurrId );
1320 NCollection_Map< int > anIds; // result
1322 // Iterate through main group
1323 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1325 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1326 if ( CORBA::is_nil( aGrp ) )
1330 SMESH::ElementType aCurrType = aGrp->GetType();
1331 if ( aType == SMESH::ALL )
1335 if ( aType != aCurrType )
1336 return SMESH::SMESH_Group::_nil();
1340 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1341 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1343 int aCurrId = aCurrIds[ i ];
1344 if ( !aToolIds.Contains( aCurrId ) )
1345 anIds.Add( aCurrId );
1350 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1351 if ( aResGrp->_is_nil() )
1352 return SMESH::SMESH_Group::_nil();
1354 // Create array of identifiers
1355 SMESH::long_array_var aResIds = new SMESH::long_array;
1356 aResIds->length( anIds.Extent() );
1358 NCollection_Map< int >::Iterator anIter( anIds );
1359 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1361 aResIds[ i ] = anIter.Value();
1363 aResGrp->Add( aResIds );
1365 // Clear python lines, created by CreateGroup() and Add()
1366 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1367 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1368 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1370 // Update Python script
1372 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1373 << &theMainGroups << ", " << &theToolGroups << ", '"
1374 << theName << "' )";
1376 return aResGrp._retn();
1380 return SMESH::SMESH_Group::_nil();
1384 //=============================================================================
1386 \brief Create groups of entities from existing groups of superior dimensions
1388 1) extract all nodes from each group,
1389 2) combine all elements of specified dimension laying on these nodes.
1390 \param theGroups list of source groups
1391 \param theElemType dimension of elements
1392 \param theName name of new group
1393 \return pointer on new group
1395 //=============================================================================
1396 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1397 const SMESH::ListOfGroups& theGroups,
1398 SMESH::ElementType theElemType,
1399 const char* theName )
1400 throw (SALOME::SALOME_Exception)
1402 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1404 if ( !theName || !aMeshDS )
1405 return SMESH::SMESH_Group::_nil();
1407 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1411 // Create map of nodes from all groups
1413 NCollection_Map< int > aNodeMap;
1415 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1417 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1418 if ( CORBA::is_nil( aGrp ) )
1421 SMESH::ElementType aType = aGrp->GetType();
1422 if ( aType == SMESH::ALL )
1424 else if ( aType == SMESH::NODE )
1426 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1427 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1429 int aCurrId = aCurrIds[ i ];
1430 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1432 aNodeMap.Add( aNode->GetID() );
1437 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1438 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1440 int aCurrId = aCurrIds[ i ];
1441 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1444 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1445 while( aNodeIter->more() )
1447 const SMDS_MeshNode* aNode =
1448 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1450 aNodeMap.Add( aNode->GetID() );
1456 // Get result identifiers
1458 NCollection_Map< int > aResultIds;
1459 if ( theElemType == SMESH::NODE )
1461 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1462 for ( ; aNodeIter.More(); aNodeIter.Next() )
1463 aResultIds.Add( aNodeIter.Value() );
1467 // Create list of elements of given dimension constructed on the nodes
1468 NCollection_Map< int > anElemList;
1469 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1470 for ( ; aNodeIter.More(); aNodeIter.Next() )
1472 const SMDS_MeshElement* aNode =
1473 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1477 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1478 while( anElemIter->more() )
1480 const SMDS_MeshElement* anElem =
1481 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1482 if ( anElem && anElem->GetType() == anElemType )
1483 anElemList.Add( anElem->GetID() );
1487 // check whether all nodes of elements are present in nodes map
1488 NCollection_Map< int >::Iterator anIter( anElemList );
1489 for ( ; anIter.More(); anIter.Next() )
1491 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1496 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1497 while( aNodeIter->more() )
1499 const SMDS_MeshNode* aNode =
1500 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1501 if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1508 aResultIds.Add( anElem->GetID() );
1514 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1515 if ( aResGrp->_is_nil() )
1516 return SMESH::SMESH_Group::_nil();
1518 // Create array of identifiers
1519 SMESH::long_array_var aResIds = new SMESH::long_array;
1520 aResIds->length( aResultIds.Extent() );
1522 NCollection_Map< int >::Iterator aResIter( aResultIds );
1523 for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1524 aResIds[ i ] = aResIter.Value();
1525 aResGrp->Add( aResIds );
1527 // Remove strings corresponding to group creation
1528 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1529 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1530 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1532 // Update Python script
1534 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1535 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1537 return aResGrp._retn();
1541 return SMESH::SMESH_Group::_nil();
1545 //================================================================================
1547 * \brief Remember GEOM group data
1549 //================================================================================
1551 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1552 CORBA::Object_ptr theSmeshObj)
1554 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1557 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1558 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1559 if ( groupSO->_is_nil() )
1562 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1563 GEOM::GEOM_IGroupOperations_var groupOp =
1564 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1565 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1568 _geomGroupData.push_back( TGeomGroupData() );
1569 TGeomGroupData & groupData = _geomGroupData.back();
1571 CORBA::String_var entry = groupSO->GetID();
1572 groupData._groupEntry = entry.in();
1574 for ( int i = 0; i < ids->length(); ++i )
1575 groupData._indices.insert( ids[i] );
1577 groupData._smeshObject = theSmeshObj;
1580 //================================================================================
1582 * Remove GEOM group data relating to removed smesh object
1584 //================================================================================
1586 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1588 list<TGeomGroupData>::iterator
1589 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1590 for ( ; data != dataEnd; ++data ) {
1591 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1592 _geomGroupData.erase( data );
1598 //================================================================================
1600 * \brief Return new group contents if it has been changed and update group data
1602 //================================================================================
1604 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1606 TopoDS_Shape newShape;
1609 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1610 if ( study->_is_nil() ) return newShape; // means "not changed"
1611 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1612 if ( !groupSO->_is_nil() )
1614 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1615 if ( CORBA::is_nil( groupObj )) return newShape;
1616 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1618 // get indices of group items
1619 set<int> curIndices;
1620 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1621 GEOM::GEOM_IGroupOperations_var groupOp =
1622 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1623 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1624 for ( int i = 0; i < ids->length(); ++i )
1625 curIndices.insert( ids[i] );
1627 if ( groupData._indices == curIndices )
1628 return newShape; // group not changed
1631 groupData._indices = curIndices;
1633 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1634 if ( !geomClient ) return newShape;
1635 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1636 geomClient->RemoveShapeFromBuffer( groupIOR );
1637 newShape = _gen_i->GeomObjectToShape( geomGroup );
1640 if ( newShape.IsNull() ) {
1641 // geom group becomes empty - return empty compound
1642 TopoDS_Compound compound;
1643 BRep_Builder().MakeCompound(compound);
1644 newShape = compound;
1650 //=============================================================================
1652 * \brief Storage of shape and index used in CheckGeomGroupModif()
1654 //=============================================================================
1655 struct TIndexedShape {
1657 TopoDS_Shape _shape;
1658 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1661 //=============================================================================
1663 * \brief Update objects depending on changed geom groups
1665 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1666 * issue 0020210: Update of a smesh group after modification of the associated geom group
1668 //=============================================================================
1670 void SMESH_Mesh_i::CheckGeomGroupModif()
1672 if ( !_impl->HasShapeToMesh() ) return;
1674 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1675 if ( study->_is_nil() ) return;
1677 CORBA::Long nbEntities = NbNodes() + NbElements();
1679 // Check if group contents changed
1681 typedef map< string, TopoDS_Shape > TEntry2Geom;
1682 TEntry2Geom newGroupContents;
1684 list<TGeomGroupData>::iterator
1685 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1686 for ( ; data != dataEnd; ++data )
1688 pair< TEntry2Geom::iterator, bool > it_new =
1689 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1690 bool processedGroup = !it_new.second;
1691 TopoDS_Shape& newShape = it_new.first->second;
1692 if ( !processedGroup )
1693 newShape = newGroupShape( *data );
1694 if ( newShape.IsNull() )
1695 continue; // no changes
1697 if ( processedGroup ) { // update group indices
1698 list<TGeomGroupData>::iterator data2 = data;
1699 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1700 data->_indices = data2->_indices;
1703 // Update SMESH objects according to new GEOM group contents
1705 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1706 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1708 int oldID = submesh->GetId();
1709 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1711 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1713 // update hypotheses
1714 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1715 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1716 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1718 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1719 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1721 // care of submeshes
1722 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1723 int newID = newSubmesh->GetId();
1724 if ( newID != oldID ) {
1725 _mapSubMesh [ newID ] = newSubmesh;
1726 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1727 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1728 _mapSubMesh. erase(oldID);
1729 _mapSubMesh_i. erase(oldID);
1730 _mapSubMeshIor.erase(oldID);
1731 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1736 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1737 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1738 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1740 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1742 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1743 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1744 ds->SetShape( newShape );
1749 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1750 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1752 // Remove groups and submeshes basing on removed sub-shapes
1754 TopTools_MapOfShape newShapeMap;
1755 TopoDS_Iterator shapeIt( newShape );
1756 for ( ; shapeIt.More(); shapeIt.Next() )
1757 newShapeMap.Add( shapeIt.Value() );
1759 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1760 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1762 if ( newShapeMap.Contains( shapeIt.Value() ))
1764 TopTools_IndexedMapOfShape oldShapeMap;
1765 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1766 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1768 const TopoDS_Shape& oldShape = oldShapeMap(i);
1769 int oldInd = meshDS->ShapeToIndex( oldShape );
1771 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1772 if ( i_smIor != _mapSubMeshIor.end() ) {
1773 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1776 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1777 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1779 // check if a group bases on oldInd shape
1780 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1781 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1782 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1783 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1785 RemoveGroup( i_grp->second ); // several groups can base on same shape
1786 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1791 // Reassign hypotheses and update groups after setting the new shape to mesh
1793 // collect anassigned hypotheses
1794 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1795 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1796 TShapeHypList assignedHyps;
1797 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1799 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1800 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1801 if ( !hyps.empty() ) {
1802 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1803 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1804 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1807 // collect shapes supporting groups
1808 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1809 TShapeTypeList groupData;
1810 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1811 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1812 for ( ; grIt != groups.end(); ++grIt )
1814 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1816 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1818 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1819 _impl->ShapeToMesh( newShape );
1821 // reassign hypotheses
1822 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1823 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1825 TIndexedShape& geom = indS_hyps->first;
1826 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1827 int oldID = geom._index;
1828 int newID = meshDS->ShapeToIndex( geom._shape );
1831 if ( oldID == 1 ) { // main shape
1833 geom._shape = newShape;
1835 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1836 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1837 // care of submeshes
1838 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1839 if ( newID != oldID ) {
1840 _mapSubMesh [ newID ] = newSubmesh;
1841 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1842 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1843 _mapSubMesh. erase(oldID);
1844 _mapSubMesh_i. erase(oldID);
1845 _mapSubMeshIor.erase(oldID);
1846 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1850 TShapeTypeList::iterator geomType = groupData.begin();
1851 for ( ; geomType != groupData.end(); ++geomType )
1853 const TIndexedShape& geom = geomType->first;
1854 int oldID = geom._index;
1855 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1858 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1859 CORBA::String_var name = groupSO->GetName();
1861 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1863 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1864 group_i->changeLocalId( newID );
1867 break; // everything has been updated
1870 } // loop on group data
1874 CORBA::Long newNbEntities = NbNodes() + NbElements();
1875 list< SALOMEDS::SObject_var > soToUpdateIcons;
1876 if ( newNbEntities != nbEntities )
1878 // Add all SObjects with icons
1879 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1881 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1882 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1883 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1885 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1886 i_gr != _mapGroups.end(); ++i_gr ) // groups
1887 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1890 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1891 for ( ; so != soToUpdateIcons.end(); ++so )
1892 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1895 //=============================================================================
1897 * \brief Create standalone group instead if group on geometry
1899 //=============================================================================
1901 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1903 SMESH::SMESH_Group_var aGroup;
1904 if ( theGroup->_is_nil() )
1905 return aGroup._retn();
1907 Unexpect aCatch(SALOME_SalomeException);
1909 SMESH_GroupBase_i* aGroupToRem =
1910 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1912 return aGroup._retn();
1914 int anId = aGroupToRem->GetLocalID();
1915 if ( !_impl->ConvertToStandalone( anId ) )
1916 return aGroup._retn();
1917 removeGeomGroupData( theGroup );
1919 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1921 // remove old instance of group from own map
1922 _mapGroups.erase( anId );
1924 SALOMEDS::StudyBuilder_var builder;
1925 SALOMEDS::SObject_var aGroupSO;
1926 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1927 if ( !aStudy->_is_nil() ) {
1928 builder = aStudy->NewBuilder();
1929 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1930 if ( !aGroupSO->_is_nil() ) {
1932 // remove reference to geometry
1933 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1934 for ( ; chItr->More(); chItr->Next() )
1935 // Remove group's child SObject
1936 builder->RemoveObject( chItr->Value() );
1938 // Update Python script
1939 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1940 << aGroupSO << " )";
1944 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1945 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1946 aGroupImpl->Register();
1947 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1949 // remember new group in own map
1950 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1951 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1953 // register CORBA object for persistence
1954 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1956 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1958 return aGroup._retn();
1961 //=============================================================================
1965 //=============================================================================
1967 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1969 if(MYDEBUG) MESSAGE( "createSubMesh" );
1970 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1972 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1973 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1974 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1975 SMESH::SMESH_subMesh_var subMesh
1976 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1978 _mapSubMesh[subMeshId] = mySubMesh;
1979 _mapSubMesh_i[subMeshId] = subMeshServant;
1980 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1982 // register CORBA object for persistence
1983 int nextId = _gen_i->RegisterObject( subMesh );
1984 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1986 // to track changes of GEOM groups
1987 addGeomGroupData( theSubShapeObject, subMesh );
1989 return subMesh._retn();
1992 //=======================================================================
1993 //function : getSubMesh
1995 //=======================================================================
1997 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1999 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2000 if ( it == _mapSubMeshIor.end() )
2001 return SMESH::SMESH_subMesh::_nil();
2003 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2007 //=============================================================================
2011 //=============================================================================
2013 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2014 GEOM::GEOM_Object_ptr theSubShapeObject )
2016 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2017 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2020 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2022 CORBA::Long shapeId = theSubMesh->GetId();
2023 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2025 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2028 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2029 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2030 for ( ; hyp != hyps.end(); ++hyp )
2031 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2038 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2039 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2040 removeHypothesis( theSubShapeObject, aHypList[i] );
2043 catch( const SALOME::SALOME_Exception& ) {
2044 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2046 removeGeomGroupData( theSubShapeObject );
2048 int subMeshId = theSubMesh->GetId();
2050 _mapSubMesh.erase(subMeshId);
2051 _mapSubMesh_i.erase(subMeshId);
2052 _mapSubMeshIor.erase(subMeshId);
2053 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2056 //=============================================================================
2060 //=============================================================================
2062 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2063 const char* theName,
2064 const TopoDS_Shape& theShape )
2067 SMESH::SMESH_GroupBase_var aGroup;
2068 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2069 SMESH_GroupBase_i* aGroupImpl;
2070 if ( !theShape.IsNull() )
2071 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2073 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2075 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2076 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2077 aGroupImpl->Register();
2078 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2080 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2081 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2083 // register CORBA object for persistence
2084 int nextId = _gen_i->RegisterObject( aGroup );
2085 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2087 // to track changes of GEOM groups
2088 if ( !theShape.IsNull() ) {
2089 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2090 addGeomGroupData( geom, aGroup );
2093 return aGroup._retn();
2096 //=============================================================================
2098 * SMESH_Mesh_i::removeGroup
2100 * Should be called by ~SMESH_Group_i()
2102 //=============================================================================
2104 void SMESH_Mesh_i::removeGroup( const int theId )
2106 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2107 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2108 removeGeomGroupData( _mapGroups[theId] );
2109 _mapGroups.erase( theId );
2110 _impl->RemoveGroup( theId );
2115 //=============================================================================
2119 //=============================================================================
2121 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2122 throw(SALOME::SALOME_Exception)
2124 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2126 SMESH::log_array_var aLog;
2128 list < SMESHDS_Command * >logDS = _impl->GetLog();
2129 aLog = new SMESH::log_array;
2131 int lg = logDS.size();
2134 list < SMESHDS_Command * >::iterator its = logDS.begin();
2135 while(its != logDS.end()){
2136 SMESHDS_Command *com = *its;
2137 int comType = com->GetType();
2139 int lgcom = com->GetNumber();
2141 const list < int >&intList = com->GetIndexes();
2142 int inum = intList.size();
2144 list < int >::const_iterator ii = intList.begin();
2145 const list < double >&coordList = com->GetCoords();
2146 int rnum = coordList.size();
2148 list < double >::const_iterator ir = coordList.begin();
2149 aLog[indexLog].commandType = comType;
2150 aLog[indexLog].number = lgcom;
2151 aLog[indexLog].coords.length(rnum);
2152 aLog[indexLog].indexes.length(inum);
2153 for(int i = 0; i < rnum; i++){
2154 aLog[indexLog].coords[i] = *ir;
2155 //MESSAGE(" "<<i<<" "<<ir.Value());
2158 for(int i = 0; i < inum; i++){
2159 aLog[indexLog].indexes[i] = *ii;
2160 //MESSAGE(" "<<i<<" "<<ii.Value());
2169 catch(SALOME_Exception & S_ex){
2170 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2172 return aLog._retn();
2176 //=============================================================================
2180 //=============================================================================
2182 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2184 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2188 //=============================================================================
2192 //=============================================================================
2194 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2196 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2200 //=============================================================================
2204 //=============================================================================
2206 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2211 //=============================================================================
2215 //=============================================================================
2217 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2219 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2223 //=============================================================================
2227 //=============================================================================
2229 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2231 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2235 //=============================================================================
2237 * Return mesh editor
2239 //=============================================================================
2241 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2243 // Create MeshEditor
2244 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2245 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2247 // Update Python script
2248 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2250 return aMesh._retn();
2253 //=============================================================================
2255 * Return mesh edition previewer
2257 //=============================================================================
2259 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2261 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2262 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2263 return aMesh._retn();
2266 //================================================================================
2268 * \brief Return true if the mesh has been edited since a last total re-compute
2269 * and those modifications may prevent successful partial re-compute
2271 //================================================================================
2273 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2275 Unexpect aCatch(SALOME_SalomeException);
2276 return _impl->HasModificationsToDiscard();
2279 //=============================================================================
2283 //=============================================================================
2284 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2286 Unexpect aCatch(SALOME_SalomeException);
2287 _impl->SetAutoColor(theAutoColor);
2290 //=============================================================================
2294 //=============================================================================
2295 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2297 Unexpect aCatch(SALOME_SalomeException);
2298 return _impl->GetAutoColor();
2302 //=============================================================================
2304 * Export in different formats
2306 //=============================================================================
2308 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2310 return _impl->HasDuplicatedGroupNamesMED();
2313 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2315 TCollection_AsciiString aFullName ((char*)file);
2316 OSD_Path aPath (aFullName);
2317 OSD_File aFile (aPath);
2318 if (aFile.Exists()) {
2319 // existing filesystem node
2320 if (aFile.KindOfFile() == OSD_FILE) {
2321 if (aFile.IsWriteable()) {
2326 if (aFile.Failed()) {
2327 TCollection_AsciiString msg ("File ");
2328 msg += aFullName + " cannot be replaced.";
2329 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2332 TCollection_AsciiString msg ("File ");
2333 msg += aFullName + " cannot be overwritten.";
2334 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2337 TCollection_AsciiString msg ("Location ");
2338 msg += aFullName + " is not a file.";
2339 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2342 // nonexisting file; check if it can be created
2344 aFile.Build(OSD_WriteOnly, OSD_Protection());
2345 if (aFile.Failed()) {
2346 TCollection_AsciiString msg ("You cannot create the file ");
2347 msg += aFullName + ". Check the directory existance and access rights.";
2348 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2356 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2357 CORBA::Boolean auto_groups,
2358 SMESH::MED_VERSION theVersion,
2359 CORBA::Boolean overwrite)
2360 throw(SALOME::SALOME_Exception)
2362 Unexpect aCatch(SALOME_SalomeException);
2365 PrepareForWriting(file, overwrite);
2366 const char* aMeshName = "Mesh";
2367 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2368 if ( !aStudy->_is_nil() ) {
2369 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2370 if ( !aMeshSO->_is_nil() ) {
2371 aMeshName = aMeshSO->GetName();
2372 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2373 if ( !aStudy->GetProperties()->IsLocked() )
2375 SALOMEDS::GenericAttribute_var anAttr;
2376 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2377 SALOMEDS::AttributeExternalFileDef_var aFileName;
2378 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2379 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2380 ASSERT(!aFileName->_is_nil());
2381 aFileName->SetValue(file);
2382 SALOMEDS::AttributeFileType_var aFileType;
2383 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2384 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2385 ASSERT(!aFileType->_is_nil());
2386 aFileType->SetValue("FICHIERMED");
2390 // Update Python script
2391 // set name of mesh before export
2392 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2394 // check names of groups
2397 TPythonDump() << _this() << ".ExportToMEDX( r'"
2398 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2400 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2403 void SMESH_Mesh_i::ExportToMED (const char* file,
2404 CORBA::Boolean auto_groups,
2405 SMESH::MED_VERSION theVersion)
2406 throw(SALOME::SALOME_Exception)
2408 ExportToMEDX(file,auto_groups,theVersion,true);
2411 void SMESH_Mesh_i::ExportMED (const char* file,
2412 CORBA::Boolean auto_groups)
2413 throw(SALOME::SALOME_Exception)
2415 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2418 void SMESH_Mesh_i::ExportDAT (const char *file)
2419 throw(SALOME::SALOME_Exception)
2421 Unexpect aCatch(SALOME_SalomeException);
2423 // Update Python script
2424 // check names of groups
2426 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2429 PrepareForWriting(file);
2430 _impl->ExportDAT(file);
2433 void SMESH_Mesh_i::ExportUNV (const char *file)
2434 throw(SALOME::SALOME_Exception)
2436 Unexpect aCatch(SALOME_SalomeException);
2438 // Update Python script
2439 // check names of groups
2441 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2444 PrepareForWriting(file);
2445 _impl->ExportUNV(file);
2448 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2449 throw(SALOME::SALOME_Exception)
2451 Unexpect aCatch(SALOME_SalomeException);
2453 // Update Python script
2454 // check names of groups
2456 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2459 PrepareForWriting(file);
2460 _impl->ExportSTL(file, isascii);
2463 //=============================================================================
2467 //=============================================================================
2469 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2471 Unexpect aCatch(SALOME_SalomeException);
2472 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2473 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2474 return aMesh._retn();
2477 //=============================================================================
2481 //=============================================================================
2482 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2484 Unexpect aCatch(SALOME_SalomeException);
2485 return _impl->NbNodes();
2488 //=============================================================================
2492 //=============================================================================
2493 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2495 Unexpect aCatch(SALOME_SalomeException);
2496 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2499 //=============================================================================
2503 //=============================================================================
2504 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2506 Unexpect aCatch(SALOME_SalomeException);
2507 return _impl->Nb0DElements();
2510 //=============================================================================
2514 //=============================================================================
2515 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2517 Unexpect aCatch(SALOME_SalomeException);
2518 return _impl->NbEdges();
2521 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2522 throw(SALOME::SALOME_Exception)
2524 Unexpect aCatch(SALOME_SalomeException);
2525 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2528 //=============================================================================
2532 //=============================================================================
2533 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2535 Unexpect aCatch(SALOME_SalomeException);
2536 return _impl->NbFaces();
2539 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2541 Unexpect aCatch(SALOME_SalomeException);
2542 return _impl->NbTriangles();
2545 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2547 Unexpect aCatch(SALOME_SalomeException);
2548 return _impl->NbQuadrangles();
2551 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2553 Unexpect aCatch(SALOME_SalomeException);
2554 return _impl->NbPolygons();
2557 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2558 throw(SALOME::SALOME_Exception)
2560 Unexpect aCatch(SALOME_SalomeException);
2561 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2564 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2565 throw(SALOME::SALOME_Exception)
2567 Unexpect aCatch(SALOME_SalomeException);
2568 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2571 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2572 throw(SALOME::SALOME_Exception)
2574 Unexpect aCatch(SALOME_SalomeException);
2575 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2578 //=============================================================================
2582 //=============================================================================
2583 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2585 Unexpect aCatch(SALOME_SalomeException);
2586 return _impl->NbVolumes();
2589 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2591 Unexpect aCatch(SALOME_SalomeException);
2592 return _impl->NbTetras();
2595 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2597 Unexpect aCatch(SALOME_SalomeException);
2598 return _impl->NbHexas();
2601 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2603 Unexpect aCatch(SALOME_SalomeException);
2604 return _impl->NbPyramids();
2607 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2609 Unexpect aCatch(SALOME_SalomeException);
2610 return _impl->NbPrisms();
2613 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2615 Unexpect aCatch(SALOME_SalomeException);
2616 return _impl->NbPolyhedrons();
2619 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2620 throw(SALOME::SALOME_Exception)
2622 Unexpect aCatch(SALOME_SalomeException);
2623 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2626 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2627 throw(SALOME::SALOME_Exception)
2629 Unexpect aCatch(SALOME_SalomeException);
2630 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2633 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2634 throw(SALOME::SALOME_Exception)
2636 Unexpect aCatch(SALOME_SalomeException);
2637 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2640 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2641 throw(SALOME::SALOME_Exception)
2643 Unexpect aCatch(SALOME_SalomeException);
2644 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2647 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2648 throw(SALOME::SALOME_Exception)
2650 Unexpect aCatch(SALOME_SalomeException);
2651 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2654 //=============================================================================
2658 //=============================================================================
2659 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2661 Unexpect aCatch(SALOME_SalomeException);
2662 return _mapSubMesh_i.size();
2665 //=============================================================================
2669 //=============================================================================
2670 char* SMESH_Mesh_i::Dump()
2674 return CORBA::string_dup( os.str().c_str() );
2677 //=============================================================================
2681 //=============================================================================
2682 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2684 // SMESH::long_array_var aResult = new SMESH::long_array();
2685 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2686 // int aMinId = aSMESHDS_Mesh->MinElementID();
2687 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2689 // aResult->length(aMaxId - aMinId + 1);
2691 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2692 // aResult[i++] = id;
2694 // return aResult._retn();
2696 return GetElementsId();
2699 //=============================================================================
2703 //=============================================================================
2705 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2706 throw (SALOME::SALOME_Exception)
2708 Unexpect aCatch(SALOME_SalomeException);
2709 MESSAGE("SMESH_Mesh_i::GetElementsId");
2710 SMESH::long_array_var aResult = new SMESH::long_array();
2711 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2713 if ( aSMESHDS_Mesh == NULL )
2714 return aResult._retn();
2716 long nbElements = NbElements();
2717 aResult->length( nbElements );
2718 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2719 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2720 aResult[i] = anIt->next()->GetID();
2722 return aResult._retn();
2726 //=============================================================================
2730 //=============================================================================
2732 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2733 throw (SALOME::SALOME_Exception)
2735 Unexpect aCatch(SALOME_SalomeException);
2736 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2737 SMESH::long_array_var aResult = new SMESH::long_array();
2738 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2740 if ( aSMESHDS_Mesh == NULL )
2741 return aResult._retn();
2743 long nbElements = NbElements();
2745 // No sense in returning ids of elements along with ids of nodes:
2746 // when theElemType == SMESH::ALL, return node ids only if
2747 // there are no elements
2748 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2749 return GetNodesId();
2751 aResult->length( nbElements );
2755 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2756 while ( i < nbElements && anIt->more() ) {
2757 const SMDS_MeshElement* anElem = anIt->next();
2758 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2759 aResult[i++] = anElem->GetID();
2762 aResult->length( i );
2764 return aResult._retn();
2767 //=============================================================================
2771 //=============================================================================
2773 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2774 throw (SALOME::SALOME_Exception)
2776 Unexpect aCatch(SALOME_SalomeException);
2777 MESSAGE("SMESH_subMesh_i::GetNodesId");
2778 SMESH::long_array_var aResult = new SMESH::long_array();
2779 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2781 if ( aSMESHDS_Mesh == NULL )
2782 return aResult._retn();
2784 long nbNodes = NbNodes();
2785 aResult->length( nbNodes );
2786 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2787 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2788 aResult[i] = anIt->next()->GetID();
2790 return aResult._retn();
2793 //=============================================================================
2797 //=============================================================================
2799 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2800 throw (SALOME::SALOME_Exception)
2802 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2805 //=============================================================================
2809 //=============================================================================
2811 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2812 throw (SALOME::SALOME_Exception)
2814 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2816 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2818 return ( SMESH::EntityType ) e->GetEntityType();
2821 //=============================================================================
2823 * Returns ID of elements for given submesh
2825 //=============================================================================
2826 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2827 throw (SALOME::SALOME_Exception)
2829 SMESH::long_array_var aResult = new SMESH::long_array();
2831 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2832 if(!SM) return aResult._retn();
2834 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2835 if(!SDSM) return aResult._retn();
2837 aResult->length(SDSM->NbElements());
2839 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2841 while ( eIt->more() ) {
2842 aResult[i++] = eIt->next()->GetID();
2845 return aResult._retn();
2849 //=============================================================================
2851 * Returns ID of nodes for given submesh
2852 * If param all==true - returns all nodes, else -
2853 * returns only nodes on shapes.
2855 //=============================================================================
2856 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2857 throw (SALOME::SALOME_Exception)
2859 SMESH::long_array_var aResult = new SMESH::long_array();
2861 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2862 if(!SM) return aResult._retn();
2864 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2865 if(!SDSM) return aResult._retn();
2868 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2869 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2870 while ( nIt->more() ) {
2871 const SMDS_MeshNode* elem = nIt->next();
2872 theElems.insert( elem->GetID() );
2875 else { // all nodes of submesh elements
2876 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2877 while ( eIt->more() ) {
2878 const SMDS_MeshElement* anElem = eIt->next();
2879 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2880 while ( nIt->more() ) {
2881 const SMDS_MeshElement* elem = nIt->next();
2882 theElems.insert( elem->GetID() );
2887 aResult->length(theElems.size());
2888 set<int>::iterator itElem;
2890 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2891 aResult[i++] = *itElem;
2893 return aResult._retn();
2897 //=============================================================================
2899 * Returns type of elements for given submesh
2901 //=============================================================================
2902 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2903 throw (SALOME::SALOME_Exception)
2905 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2906 if(!SM) return SMESH::ALL;
2908 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2909 if(!SDSM) return SMESH::ALL;
2911 if(SDSM->NbElements()==0)
2912 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2914 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2915 const SMDS_MeshElement* anElem = eIt->next();
2916 return ( SMESH::ElementType ) anElem->GetType();
2920 //=============================================================================
2924 //=============================================================================
2926 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2928 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2930 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2935 //=============================================================================
2937 * Get XYZ coordinates of node as list of double
2938 * If there is not node for given ID - returns empty list
2940 //=============================================================================
2942 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2944 SMESH::double_array_var aResult = new SMESH::double_array();
2945 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2946 if ( aSMESHDS_Mesh == NULL )
2947 return aResult._retn();
2950 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2952 return aResult._retn();
2956 aResult[0] = aNode->X();
2957 aResult[1] = aNode->Y();
2958 aResult[2] = aNode->Z();
2959 return aResult._retn();
2963 //=============================================================================
2965 * For given node returns list of IDs of inverse elements
2966 * If there is not node for given ID - returns empty list
2968 //=============================================================================
2970 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2972 SMESH::long_array_var aResult = new SMESH::long_array();
2973 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2974 if ( aSMESHDS_Mesh == NULL )
2975 return aResult._retn();
2978 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2980 return aResult._retn();
2982 // find inverse elements
2983 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2984 TColStd_SequenceOfInteger IDs;
2985 while(eIt->more()) {
2986 const SMDS_MeshElement* elem = eIt->next();
2987 IDs.Append(elem->GetID());
2989 if(IDs.Length()>0) {
2990 aResult->length(IDs.Length());
2992 for(; i<=IDs.Length(); i++) {
2993 aResult[i-1] = IDs.Value(i);
2996 return aResult._retn();
2999 //=============================================================================
3001 * \brief Return position of a node on shape
3003 //=============================================================================
3005 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3007 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3008 aNodePosition->shapeID = 0;
3009 aNodePosition->shapeType = GEOM::SHAPE;
3011 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3012 if ( !mesh ) return aNodePosition;
3014 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3016 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3018 aNodePosition->shapeID = pos->GetShapeId();
3019 switch ( pos->GetTypeOfPosition() ) {
3021 aNodePosition->shapeType = GEOM::EDGE;
3022 aNodePosition->params.length(1);
3023 aNodePosition->params[0] =
3024 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
3027 aNodePosition->shapeType = GEOM::FACE;
3028 aNodePosition->params.length(2);
3029 aNodePosition->params[0] =
3030 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
3031 aNodePosition->params[1] =
3032 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
3034 case SMDS_TOP_VERTEX:
3035 aNodePosition->shapeType = GEOM::VERTEX;
3037 case SMDS_TOP_3DSPACE:
3038 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3039 aNodePosition->shapeType = GEOM::SOLID;
3040 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3041 aNodePosition->shapeType = GEOM::SHELL;
3047 return aNodePosition;
3050 //=============================================================================
3052 * If given element is node returns IDs of shape from position
3053 * If there is not node for given ID - returns -1
3055 //=============================================================================
3057 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3059 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3060 if ( aSMESHDS_Mesh == NULL )
3064 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3066 SMDS_PositionPtr pos = aNode->GetPosition();
3070 return pos->GetShapeId();
3077 //=============================================================================
3079 * For given element returns ID of result shape after
3080 * ::FindShape() from SMESH_MeshEditor
3081 * If there is not element for given ID - returns -1
3083 //=============================================================================
3085 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3087 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3088 if ( aSMESHDS_Mesh == NULL )
3091 // try to find element
3092 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3096 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3097 ::SMESH_MeshEditor aMeshEditor(_impl);
3098 int index = aMeshEditor.FindShape( elem );
3106 //=============================================================================
3108 * Returns number of nodes for given element
3109 * If there is not element for given ID - returns -1
3111 //=============================================================================
3113 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3115 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3116 if ( aSMESHDS_Mesh == NULL ) return -1;
3117 // try to find element
3118 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3119 if(!elem) return -1;
3120 return elem->NbNodes();
3124 //=============================================================================
3126 * Returns ID of node by given index for given element
3127 * If there is not element for given ID - returns -1
3128 * If there is not node for given index - returns -2
3130 //=============================================================================
3132 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3134 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3135 if ( aSMESHDS_Mesh == NULL ) return -1;
3136 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3137 if(!elem) return -1;
3138 if( index>=elem->NbNodes() || index<0 ) return -1;
3139 return elem->GetNode(index)->GetID();
3142 //=============================================================================
3144 * Returns IDs of nodes of given element
3146 //=============================================================================
3148 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3150 SMESH::long_array_var aResult = new SMESH::long_array();
3151 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3153 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3155 aResult->length( elem->NbNodes() );
3156 for ( int i = 0; i < elem->NbNodes(); ++i )
3157 aResult[ i ] = elem->GetNode( i )->GetID();
3160 return aResult._retn();
3163 //=============================================================================
3165 * Returns true if given node is medium node
3166 * in given quadratic element
3168 //=============================================================================
3170 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3172 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3173 if ( aSMESHDS_Mesh == NULL ) return false;
3175 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3176 if(!aNode) return false;
3177 // try to find element
3178 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3179 if(!elem) return false;
3181 return elem->IsMediumNode(aNode);
3185 //=============================================================================
3187 * Returns true if given node is medium node
3188 * in one of quadratic elements
3190 //=============================================================================
3192 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3193 SMESH::ElementType theElemType)
3195 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3196 if ( aSMESHDS_Mesh == NULL ) return false;
3199 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3200 if(!aNode) return false;
3202 SMESH_MesherHelper aHelper( *(_impl) );
3204 SMDSAbs_ElementType aType;
3205 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3206 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3207 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3208 else aType = SMDSAbs_All;
3210 return aHelper.IsMedium(aNode,aType);
3214 //=============================================================================
3216 * Returns number of edges for given element
3218 //=============================================================================
3220 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3222 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3223 if ( aSMESHDS_Mesh == NULL ) return -1;
3224 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3225 if(!elem) return -1;
3226 return elem->NbEdges();
3230 //=============================================================================
3232 * Returns number of faces for given element
3234 //=============================================================================
3236 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3238 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3239 if ( aSMESHDS_Mesh == NULL ) return -1;
3240 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3241 if(!elem) return -1;
3242 return elem->NbFaces();
3245 //=======================================================================
3246 //function : GetElemFaceNodes
3247 //purpose : Returns nodes of given face (counted from zero) for given element.
3248 //=======================================================================
3250 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3251 CORBA::Short faceIndex)
3253 SMESH::long_array_var aResult = new SMESH::long_array();
3254 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3256 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3258 SMDS_VolumeTool vtool( elem );
3259 if ( faceIndex < vtool.NbFaces() )
3261 aResult->length( vtool.NbFaceNodes( faceIndex ));
3262 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3263 for ( int i = 0; i < aResult->length(); ++i )
3264 aResult[ i ] = nn[ i ]->GetID();
3268 return aResult._retn();
3271 //=======================================================================
3272 //function : FindElementByNodes
3273 //purpose : Returns an element based on all given nodes.
3274 //=======================================================================
3276 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3278 CORBA::Long elemID(0);
3279 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3281 vector< const SMDS_MeshNode * > nn( nodes.length() );
3282 for ( int i = 0; i < nodes.length(); ++i )
3283 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3286 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3287 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3288 _impl->NbFaces( ORDER_QUADRATIC ) ||
3289 _impl->NbVolumes( ORDER_QUADRATIC )))
3290 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3292 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3297 //=============================================================================
3299 * Returns true if given element is polygon
3301 //=============================================================================
3303 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3305 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3306 if ( aSMESHDS_Mesh == NULL ) return false;
3307 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3308 if(!elem) return false;
3309 return elem->IsPoly();
3313 //=============================================================================
3315 * Returns true if given element is quadratic
3317 //=============================================================================
3319 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3321 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3322 if ( aSMESHDS_Mesh == NULL ) return false;
3323 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3324 if(!elem) return false;
3325 return elem->IsQuadratic();
3329 //=============================================================================
3331 * Returns bary center for given element
3333 //=============================================================================
3335 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3337 SMESH::double_array_var aResult = new SMESH::double_array();
3338 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3339 if ( aSMESHDS_Mesh == NULL )
3340 return aResult._retn();
3342 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3344 return aResult._retn();
3346 if(elem->GetType()==SMDSAbs_Volume) {
3347 SMDS_VolumeTool aTool;
3348 if(aTool.Set(elem)) {
3350 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3355 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3357 double x=0., y=0., z=0.;
3358 for(; anIt->more(); ) {
3360 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3374 return aResult._retn();
3378 //=============================================================================
3380 * Create and publish group servants if any groups were imported or created anyhow
3382 //=============================================================================
3384 void SMESH_Mesh_i::CreateGroupServants()
3386 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3388 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3389 while ( groupIt->more() )
3391 ::SMESH_Group* group = groupIt->next();
3392 int anId = group->GetGroupDS()->GetID();
3394 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3395 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3398 SMESH_GroupBase_i* aGroupImpl;
3400 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3401 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3403 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3404 shape = groupOnGeom->GetShape();
3407 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3410 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3411 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3412 aGroupImpl->Register();
3414 SMESH::SMESH_GroupBase_var groupVar =
3415 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3416 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3418 // register CORBA object for persistence
3419 int nextId = _gen_i->RegisterObject( groupVar );
3420 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3422 // publishing of the groups in the study
3423 if ( !aStudy->_is_nil() ) {
3424 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3425 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3430 //=============================================================================
3432 * \brief Return groups cantained in _mapGroups by their IDs
3434 //=============================================================================
3436 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3438 int nbGroups = groupIDs.size();
3439 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3440 aList->length( nbGroups );
3442 list<int>::const_iterator ids = groupIDs.begin();
3443 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3445 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3446 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3447 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3449 aList->length( nbGroups );
3450 return aList._retn();
3453 //=============================================================================
3455 * \brief Return information about imported file
3457 //=============================================================================
3459 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3461 SALOME_MED::MedFileInfo_var res( myFileInfo );
3462 if ( !res.operator->() ) {
3463 res = new SALOME_MED::MedFileInfo;
3465 res->fileSize = res->major = res->minor = res->release = -1;
3470 //=============================================================================
3472 * \brief Check and correct names of mesh groups
3474 //=============================================================================
3476 void SMESH_Mesh_i::checkGroupNames()
3478 int nbGrp = NbGroups();
3482 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3483 if ( aStudy->_is_nil() )
3484 return; // nothing to do
3486 SMESH::ListOfGroups* grpList = 0;
3487 // avoid dump of "GetGroups"
3489 // store python dump into a local variable inside local scope
3490 SMESH::TPythonDump pDump; // do not delete this line of code
3491 grpList = GetGroups();
3494 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3495 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3498 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3499 if ( aGrpSO->_is_nil() )
3501 // correct name of the mesh group if necessary
3502 const char* guiName = aGrpSO->GetName();
3503 if ( strcmp(guiName, aGrp->GetName()) )
3504 aGrp->SetName( guiName );
3508 //=============================================================================
3510 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3512 //=============================================================================
3513 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3515 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3516 CORBA::string_dup(theParameters));
3519 //=============================================================================
3521 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3523 //=============================================================================
3524 char* SMESH_Mesh_i::GetParameters()
3526 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3527 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3530 //=============================================================================
3532 * \brief Returns list of notebook variables used for last Mesh operation
3534 //=============================================================================
3535 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3537 SMESH::string_array_var aResult = new SMESH::string_array();
3538 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3540 char *aParameters = GetParameters();
3541 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3542 if(!aStudy->_is_nil()) {
3543 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3544 if(aSections->length() > 0) {
3545 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3546 aResult->length(aVars.length());
3547 for(int i = 0;i < aVars.length();i++)
3548 aResult[i] = CORBA::string_dup( aVars[i]);
3552 return aResult._retn();
3555 //=======================================================================
3556 //function : GetTypes
3557 //purpose : Returns types of elements it contains
3558 //=======================================================================
3560 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3562 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3566 if (_impl->NbEdges())
3567 types[nbTypes++] = SMESH::EDGE;
3568 if (_impl->NbFaces())
3569 types[nbTypes++] = SMESH::FACE;
3570 if (_impl->NbVolumes())
3571 types[nbTypes++] = SMESH::VOLUME;
3572 if (_impl->Nb0DElements())
3573 types[nbTypes++] = SMESH::ELEM0D;
3574 types->length( nbTypes );
3576 return types._retn();
3579 //=============================================================================
3581 * \brief Returns statistic of mesh elements
3583 //=============================================================================
3584 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3586 SMESH::long_array_var aRes = new SMESH::long_array();
3587 aRes->length(SMESH::Entity_Last);
3588 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3590 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3592 return aRes._retn();
3593 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3594 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3595 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3596 return aRes._retn();
3599 //=============================================================================
3601 * \brief Collect statistic of mesh elements given by iterator
3603 //=============================================================================
3604 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3605 SMESH::long_array& theInfo)
3607 if (!theItr) return;
3608 while (theItr->more())
3609 theInfo[ theItr->next()->GetEntityType() ]++;
3612 //=============================================================================
3614 * \brief mapping of mesh dimension into shape type
3616 //=============================================================================
3617 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3619 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3621 case 0: aType = TopAbs_VERTEX; break;
3622 case 1: aType = TopAbs_EDGE; break;
3623 case 2: aType = TopAbs_FACE; break;
3625 default:aType = TopAbs_SOLID; break;
3630 //=============================================================================
3632 * \brief Internal structure used to find concurent submeshes
3634 * It represents a pair < submesh, concurent dimension >, where
3635 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3636 * with another submesh. In other words, it is dimension of a hypothesis assigned
3639 //=============================================================================
3645 int _dim; //!< a dimension the algo can build (concurrent dimension)
3646 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3647 TopTools_MapOfShape _shapeMap;
3648 SMESH_subMesh* _subMesh;
3649 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3652 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3654 const TopoDS_Shape& theShape)
3656 _subMesh = (SMESH_subMesh*)theSubMesh;
3657 SetShape( theDim, theShape );
3661 void SetShape(const int theDim,
3662 const TopoDS_Shape& theShape)
3665 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3666 if (_dim >= _ownDim)
3667 _shapeMap.Add( theShape );
3669 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3670 for( ; anExp.More(); anExp.Next() )
3671 _shapeMap.Add( anExp.Current() );
3675 //! Check sharing of sub shapes
3676 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3677 const TopTools_MapOfShape& theToFind,
3678 const TopAbs_ShapeEnum theType)
3680 bool isShared = false;
3681 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3682 for (; !isShared && anItr.More(); anItr.Next() ) {
3683 const TopoDS_Shape aSubSh = anItr.Key();
3684 // check for case when concurrent dimensions are same
3685 isShared = theToFind.Contains( aSubSh );
3686 // check for subshape with concurrent dimension
3687 TopExp_Explorer anExp( aSubSh, theType );
3688 for ( ; !isShared && anExp.More(); anExp.Next() )
3689 isShared = theToFind.Contains( anExp.Current() );
3694 //! check algorithms
3695 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3696 const SMESHDS_Hypothesis* theA2)
3698 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3699 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3700 return false; // one of the hypothesis is not algorithm
3701 // check algorithm names (should be equal)
3702 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3706 //! Check if subshape hypotheses are concurrent
3707 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3709 if ( _subMesh == theOther->_subMesh )
3710 return false; // same subshape - should not be
3712 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3713 // any of the two submeshes is not on COMPOUND shape )
3714 // -> no concurrency
3715 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3716 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3717 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3720 // bool checkSubShape = ( _dim >= theOther->_dim )
3721 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3722 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3723 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3724 if ( !checkSubShape )
3727 // check algorithms to be same
3728 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3729 return true; // different algorithms
3731 // check hypothesises for concurrence (skip first as algorithm)
3733 // pointers should be same, becase it is referenes from mesh hypothesis partition
3734 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3735 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3736 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3737 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3739 // the submeshes are concurrent if their algorithms has different parameters
3740 return nbSame != theOther->_hypothesises.size() - 1;
3743 }; // end of SMESH_DimHyp
3745 typedef list<SMESH_DimHyp*> TDimHypList;
3747 static void addDimHypInstance(const int theDim,
3748 const TopoDS_Shape& theShape,
3749 const SMESH_Algo* theAlgo,
3750 const SMESH_subMesh* theSubMesh,
3751 const list <const SMESHDS_Hypothesis*>& theHypList,
3752 TDimHypList* theDimHypListArr )
3754 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3755 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3756 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3757 listOfdimHyp.push_back( dimHyp );
3760 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3761 dimHyp->_hypothesises.push_front(theAlgo);
3762 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3763 for( ; hypIt != theHypList.end(); hypIt++ )
3764 dimHyp->_hypothesises.push_back( *hypIt );
3767 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3768 const TDimHypList& theListOfDimHyp,
3769 TListOfInt& theListOfConcurr )
3771 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3772 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3773 const SMESH_DimHyp* curDimHyp = *rIt;
3774 if ( curDimHyp == theDimHyp )
3775 break; // meet own dimHyp pointer in same dimension
3776 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3777 if ( find( theListOfConcurr.begin(),
3778 theListOfConcurr.end(),
3779 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3780 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3784 static void unionLists(TListOfInt& theListOfId,
3785 TListOfListOfInt& theListOfListOfId,
3788 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3789 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3791 continue; //skip already treated lists
3792 // check if other list has any same submesh object
3793 TListOfInt& otherListOfId = *it;
3794 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3795 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3798 // union two lists (from source into target)
3799 TListOfInt::iterator it2 = otherListOfId.begin();
3800 for ( ; it2 != otherListOfId.end(); it2++ ) {
3801 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3802 theListOfId.push_back(*it2);
3804 // clear source list
3805 otherListOfId.clear();
3809 //! free memory allocated for dimension-hypothesis objects
3810 static void removeDimHyps( TDimHypList* theArrOfList )
3812 for (int i = 0; i < 4; i++ ) {
3813 TDimHypList& listOfdimHyp = theArrOfList[i];
3814 TDimHypList::const_iterator it = listOfdimHyp.begin();
3815 for ( ; it != listOfdimHyp.end(); it++ )
3820 //=============================================================================
3822 * \brief Return submesh objects list in meshing order
3824 //=============================================================================
3826 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3828 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3830 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3832 return aResult._retn();
3834 ::SMESH_Mesh& mesh = GetImpl();
3835 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3836 if ( !anOrder.size() ) {
3838 // collect submeshes detecting concurrent algorithms and hypothesises
3839 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3841 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3842 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3843 ::SMESH_subMesh* sm = (*i_sm).second;
3845 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3847 // list of assigned hypothesises
3848 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3849 // Find out dimensions where the submesh can be concurrent.
3850 // We define the dimensions by algo of each of hypotheses in hypList
3851 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3852 for( ; hypIt != hypList.end(); hypIt++ ) {
3853 SMESH_Algo* anAlgo = 0;
3854 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3855 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3856 // hyp it-self is algo
3857 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3859 // try to find algorithm with help of subshapes
3860 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3861 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3862 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3865 continue; // no assigned algorithm to current submesh
3867 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3868 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3870 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3871 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3872 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3874 } // end iterations on submesh
3876 // iterate on created dimension-hypotheses and check for concurrents
3877 for ( int i = 0; i < 4; i++ ) {
3878 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3879 // check for concurrents in own and other dimensions (step-by-step)
3880 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3881 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3882 const SMESH_DimHyp* dimHyp = *dhIt;
3883 TListOfInt listOfConcurr;
3884 // looking for concurrents and collect into own list
3885 for ( int j = i; j < 4; j++ )
3886 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3887 // check if any concurrents found
3888 if ( listOfConcurr.size() > 0 ) {
3889 // add own submesh to list of concurrent
3890 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3891 anOrder.push_back( listOfConcurr );
3896 removeDimHyps(dimHypListArr);
3898 // now, minimise the number of concurrent groups
3899 // Here we assume that lists of submhes can has same submesh
3900 // in case of multi-dimension algorithms, as result
3901 // list with common submesh have to be union into one list
3903 TListOfListOfInt::iterator listIt = anOrder.begin();
3904 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3905 unionLists( *listIt, anOrder, listIndx + 1 );
3907 // convert submesh ids into interface instances
3908 // and dump command into python
3909 convertMeshOrder( anOrder, aResult, true );
3911 return aResult._retn();
3914 //=============================================================================
3916 * \brief find common submeshes with given submesh
3917 * \param theSubMeshList list of already collected submesh to check
3918 * \param theSubMesh given submesh to intersect with other
3919 * \param theCommonSubMeshes collected common submeshes
3921 //=============================================================================
3923 static void findCommonSubMesh
3924 (list<const SMESH_subMesh*>& theSubMeshList,
3925 const SMESH_subMesh* theSubMesh,
3926 set<const SMESH_subMesh*>& theCommon )
3930 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
3931 for ( ; it != theSubMeshList.end(); it++ )
3932 theSubMesh->FindIntersection( *it, theCommon );
3933 theSubMeshList.push_back( theSubMesh );
3934 //theCommon.insert( theSubMesh );
3937 //=============================================================================
3939 * \brief Set submesh object order
3940 * \param theSubMeshArray submesh array order
3942 //=============================================================================
3944 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
3947 ::SMESH_Mesh& mesh = GetImpl();
3949 TPythonDump aPythonDump; // prevent dump of called methods
3950 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
3952 TListOfListOfInt subMeshOrder;
3953 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
3955 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
3956 TListOfInt subMeshIds;
3957 aPythonDump << "[ ";
3958 // Collect subMeshes which should be clear
3959 // do it list-by-list, because modification of submesh order
3960 // take effect between concurrent submeshes only
3961 set<const SMESH_subMesh*> subMeshToClear;
3962 list<const SMESH_subMesh*> subMeshList;
3963 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
3965 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
3967 aPythonDump << ", ";
3968 aPythonDump << subMesh;
3969 subMeshIds.push_back( subMesh->GetId() );
3970 // detect common parts of submeshes
3971 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
3972 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
3974 aPythonDump << " ]";
3975 subMeshOrder.push_back( subMeshIds );
3977 // clear collected submeshes
3978 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
3979 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
3980 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
3982 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
3983 // ClearSubMesh( *clrIt );
3986 aPythonDump << " ])";
3988 mesh.SetMeshOrder( subMeshOrder );
3994 //=============================================================================
3996 * \brief Convert submesh ids into submesh interfaces
3998 //=============================================================================
4000 void SMESH_Mesh_i::convertMeshOrder
4001 (const TListOfListOfInt& theIdsOrder,
4002 SMESH::submesh_array_array& theResOrder,
4003 const bool theIsDump)
4005 int nbSet = theIdsOrder.size();
4006 TPythonDump aPythonDump; // prevent dump of called methods
4008 aPythonDump << "[ ";
4009 theResOrder.length(nbSet);
4010 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4012 for( ; it != theIdsOrder.end(); it++ ) {
4013 // translate submesh identificators into submesh objects
4014 // takeing into account real number of concurrent lists
4015 const TListOfInt& aSubOrder = (*it);
4016 if (!aSubOrder.size())
4019 aPythonDump << "[ ";
4020 // convert shape indeces into interfaces
4021 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4022 aResSubSet->length(aSubOrder.size());
4023 TListOfInt::const_iterator subIt = aSubOrder.begin();
4024 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4025 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4027 SMESH::SMESH_subMesh_var subMesh =
4028 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4031 aPythonDump << ", ";
4032 aPythonDump << subMesh;
4034 aResSubSet[ j++ ] = subMesh;
4037 aPythonDump << " ]";
4038 theResOrder[ listIndx++ ] = aResSubSet;
4040 // correct number of lists
4041 theResOrder.length( listIndx );
4044 // finilise python dump
4045 aPythonDump << " ]";
4046 aPythonDump << " = " << _this() << ".GetMeshOrder()";