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 subMesh = getSubMesh( subMeshId );
660 // create a new subMesh object servant if there is none for the shape
661 if ( subMesh->_is_nil() )
662 subMesh = createSubMesh( aSubShapeObject );
663 if ( _gen_i->CanPublishInStudy( subMesh )) {
664 SALOMEDS::SObject_var aSO =
665 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
666 subMesh, aSubShapeObject, theName );
667 if ( !aSO->_is_nil()) {
668 // Update Python script
669 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
670 << aSubShapeObject << ", '" << theName << "' )";
674 catch(SALOME_Exception & S_ex) {
675 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
677 return subMesh._retn();
680 //=============================================================================
684 //=============================================================================
686 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
687 throw (SALOME::SALOME_Exception)
689 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
690 if ( theSubMesh->_is_nil() )
693 GEOM::GEOM_Object_var aSubShapeObject;
694 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
695 if ( !aStudy->_is_nil() ) {
696 // Remove submesh's SObject
697 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
698 if ( !anSO->_is_nil() ) {
699 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
700 SALOMEDS::SObject_var anObj, aRef;
701 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
702 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
704 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
705 // aSubShapeObject = theSubMesh->GetSubShape();
707 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
709 // Update Python script
710 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
714 removeSubMesh( theSubMesh, aSubShapeObject.in() );
717 //=============================================================================
721 //=============================================================================
722 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
723 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
725 switch (theElemType) {
730 CASE2STRING( VOLUME );
736 //=============================================================================
740 //=============================================================================
742 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
743 const char* theName )
744 throw(SALOME::SALOME_Exception)
746 Unexpect aCatch(SALOME_SalomeException);
747 SMESH::SMESH_Group_var aNewGroup =
748 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
750 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
751 SALOMEDS::SObject_var aSO =
752 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
753 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
754 if ( !aSO->_is_nil()) {
755 // Update Python script
756 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
757 << ElementTypeString(theElemType) << ", '" << theName << "' )";
760 return aNewGroup._retn();
764 //=============================================================================
768 //=============================================================================
769 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
771 GEOM::GEOM_Object_ptr theGeomObj)
772 throw(SALOME::SALOME_Exception)
774 Unexpect aCatch(SALOME_SalomeException);
775 SMESH::SMESH_GroupOnGeom_var aNewGroup;
777 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
778 if ( !aShape.IsNull() )
780 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
781 ( createGroup( theElemType, theName, aShape ));
783 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
784 SALOMEDS::SObject_var aSO =
785 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
786 aNewGroup, theGeomObj, theName);
787 if ( !aSO->_is_nil()) {
788 // Update Python script
789 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
790 << ElementTypeString(theElemType) << ", '" << theName << "', "
791 << theGeomObj << " )";
796 return aNewGroup._retn();
799 //=============================================================================
803 //=============================================================================
805 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
806 throw (SALOME::SALOME_Exception)
808 if ( theGroup->_is_nil() )
811 SMESH_GroupBase_i* aGroup =
812 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
816 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
817 if ( !aStudy->_is_nil() ) {
818 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
820 if ( !aGroupSO->_is_nil() ) {
821 // Update Python script
822 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
824 // Remove group's SObject
825 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
829 // Remove the group from SMESH data structures
830 removeGroup( aGroup->GetLocalID() );
833 //=============================================================================
834 /*! RemoveGroupWithContents
835 * Remove group with its contents
837 //=============================================================================
838 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
839 throw (SALOME::SALOME_Exception)
841 if ( theGroup->_is_nil() )
844 SMESH_GroupBase_i* aGroup =
845 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
849 SMESH::long_array_var anIds = aGroup->GetListOfID();
850 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
852 // Update Python script
853 TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
856 if ( aGroup->GetType() == SMESH::NODE )
857 aMeshEditor->RemoveNodes( anIds );
859 aMeshEditor->RemoveElements( anIds );
862 RemoveGroup( theGroup );
864 // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
865 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
866 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
870 //================================================================================
872 * \brief Get the list of groups existing in the mesh
873 * \retval SMESH::ListOfGroups * - list of groups
875 //================================================================================
877 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
879 Unexpect aCatch(SALOME_SalomeException);
880 if (MYDEBUG) MESSAGE("GetGroups");
882 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
885 TPythonDump aPythonDump;
886 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
890 aList->length( _mapGroups.size() );
892 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
893 for ( ; it != _mapGroups.end(); it++ ) {
894 if ( CORBA::is_nil( it->second )) continue;
895 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
897 if (i > 1) aPythonDump << ", ";
898 aPythonDump << it->second;
902 catch(SALOME_Exception & S_ex) {
903 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
906 // Update Python script
907 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
908 aPythonDump << " ] = " << _this() << ".GetGroups()";
910 return aList._retn();
912 //=============================================================================
914 * Get number of groups existing in the mesh
916 //=============================================================================
918 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
920 Unexpect aCatch(SALOME_SalomeException);
921 return _mapGroups.size();
924 //=============================================================================
926 * New group is created. All mesh elements that are
927 * present in initial groups are added to the new one
929 //=============================================================================
930 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
931 SMESH::SMESH_GroupBase_ptr theGroup2,
932 const char* theName )
933 throw (SALOME::SALOME_Exception)
937 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
938 theGroup1->GetType() != theGroup2->GetType() )
939 return SMESH::SMESH_Group::_nil();
942 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
943 if ( aResGrp->_is_nil() )
944 return SMESH::SMESH_Group::_nil();
946 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
947 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
949 TColStd_MapOfInteger aResMap;
951 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
952 aResMap.Add( anIds1[ i1 ] );
954 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
955 aResMap.Add( anIds2[ i2 ] );
957 SMESH::long_array_var aResIds = new SMESH::long_array;
958 aResIds->length( aResMap.Extent() );
961 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
962 for( ; anIter.More(); anIter.Next() )
963 aResIds[ resI++ ] = anIter.Key();
965 aResGrp->Add( aResIds );
967 // Clear python lines, created by CreateGroup() and Add()
968 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
969 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
970 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
972 // Update Python script
973 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
974 << theGroup1 << ", " << theGroup2 << ", '"
977 return aResGrp._retn();
981 return SMESH::SMESH_Group::_nil();
985 //=============================================================================
987 \brief Union list of groups. New group is created. All mesh elements that are
988 present in initial groups are added to the new one.
989 \param theGroups list of groups
990 \param theName name of group to be created
991 \return pointer on the group
993 //=============================================================================
994 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
995 const char* theName )
996 throw (SALOME::SALOME_Exception)
999 return SMESH::SMESH_Group::_nil();
1003 NCollection_Map< int > anIds;
1004 SMESH::ElementType aType = SMESH::ALL;
1005 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1007 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1008 if ( CORBA::is_nil( aGrp ) )
1012 SMESH::ElementType aCurrType = aGrp->GetType();
1013 if ( aType == SMESH::ALL )
1017 if ( aType != aCurrType )
1018 return SMESH::SMESH_Group::_nil();
1022 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1023 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1025 int aCurrId = aCurrIds[ i ];
1026 anIds.Add( aCurrId );
1031 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1032 if ( aResGrp->_is_nil() )
1033 return SMESH::SMESH_Group::_nil();
1035 // Create array of identifiers
1036 SMESH::long_array_var aResIds = new SMESH::long_array;
1037 aResIds->length( anIds.Extent() );
1039 NCollection_Map< int >::Iterator anIter( anIds );
1040 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1042 aResIds[ i ] = anIter.Value();
1044 aResGrp->Add( aResIds );
1046 // Clear python lines, created by CreateGroup() and Add()
1047 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1048 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1049 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1051 // Update Python script
1053 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1054 << &theGroups << ", '" << theName << "' )";
1056 return aResGrp._retn();
1060 return SMESH::SMESH_Group::_nil();
1064 //=============================================================================
1066 * New group is created. All mesh elements that are
1067 * present in both initial groups are added to the new one.
1069 //=============================================================================
1070 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1071 SMESH::SMESH_GroupBase_ptr theGroup2,
1072 const char* theName )
1073 throw (SALOME::SALOME_Exception)
1075 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1076 theGroup1->GetType() != theGroup2->GetType() )
1077 return SMESH::SMESH_Group::_nil();
1079 // Create Intersection
1080 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1081 if ( aResGrp->_is_nil() )
1084 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1085 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1087 TColStd_MapOfInteger aMap1;
1089 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1090 aMap1.Add( anIds1[ i1 ] );
1092 TColStd_SequenceOfInteger aSeq;
1094 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1095 if ( aMap1.Contains( anIds2[ i2 ] ) )
1096 aSeq.Append( anIds2[ i2 ] );
1098 SMESH::long_array_var aResIds = new SMESH::long_array;
1099 aResIds->length( aSeq.Length() );
1101 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1102 aResIds[ resI ] = aSeq( resI + 1 );
1104 aResGrp->Add( aResIds );
1106 // Clear python lines, created by CreateGroup() and Add()
1107 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1108 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1109 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1111 // Update Python script
1112 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1113 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1115 return aResGrp._retn();
1118 //=============================================================================
1120 \brief Intersect list of groups. New group is created. All mesh elements that
1121 are present in all initial groups simultaneously are added to the new one.
1122 \param theGroups list of groups
1123 \param theName name of group to be created
1124 \return pointer on the group
1126 //=============================================================================
1127 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1128 const SMESH::ListOfGroups& theGroups, const char* theName )
1129 throw (SALOME::SALOME_Exception)
1132 return SMESH::SMESH_Group::_nil();
1136 NCollection_DataMap< int, int > anIdToCount;
1137 SMESH::ElementType aType = SMESH::ALL;
1138 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1140 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1141 if ( CORBA::is_nil( aGrp ) )
1145 SMESH::ElementType aCurrType = aGrp->GetType();
1146 if ( aType == SMESH::ALL )
1150 if ( aType != aCurrType )
1151 return SMESH::SMESH_Group::_nil();
1154 // calculates number of occurance ids in groups
1155 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1156 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1158 int aCurrId = aCurrIds[ i ];
1159 if ( !anIdToCount.IsBound( aCurrId ) )
1160 anIdToCount.Bind( aCurrId, 1 );
1162 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1166 // create map of ids
1167 int nbGrp = theGroups.length();
1168 NCollection_Map< int > anIds;
1169 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1170 for ( ; anIter.More(); anIter.Next() )
1172 int aCurrId = anIter.Key();
1173 int aCurrNb = anIter.Value();
1174 if ( aCurrNb == nbGrp )
1175 anIds.Add( aCurrId );
1179 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1180 if ( aResGrp->_is_nil() )
1181 return SMESH::SMESH_Group::_nil();
1183 // Create array of identifiers
1184 SMESH::long_array_var aResIds = new SMESH::long_array;
1185 aResIds->length( anIds.Extent() );
1187 NCollection_Map< int >::Iterator aListIter( anIds );
1188 for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1190 aResIds[ i ] = aListIter.Value();
1192 aResGrp->Add( aResIds );
1194 // Clear python lines, created by CreateGroup() and Add()
1195 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1196 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1197 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1199 // Update Python script
1201 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1202 << &theGroups << ", '" << theName << "' )";
1204 return aResGrp._retn();
1208 return SMESH::SMESH_Group::_nil();
1212 //=============================================================================
1214 * New group is created. All mesh elements that are present in
1215 * main group but do not present in tool group are added to the new one
1217 //=============================================================================
1218 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1219 SMESH::SMESH_GroupBase_ptr theGroup2,
1220 const char* theName )
1221 throw (SALOME::SALOME_Exception)
1223 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1224 theGroup1->GetType() != theGroup2->GetType() )
1225 return SMESH::SMESH_Group::_nil();
1228 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1229 if ( aResGrp->_is_nil() )
1232 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1233 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1235 TColStd_MapOfInteger aMap2;
1237 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1238 aMap2.Add( anIds2[ i2 ] );
1240 TColStd_SequenceOfInteger aSeq;
1241 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1242 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1243 aSeq.Append( anIds1[ i1 ] );
1245 SMESH::long_array_var aResIds = new SMESH::long_array;
1246 aResIds->length( aSeq.Length() );
1248 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1249 aResIds[ resI ] = aSeq( resI + 1 );
1251 aResGrp->Add( aResIds );
1253 // Clear python lines, created by CreateGroup() and Add()
1254 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1255 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1256 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1258 // Update Python script
1259 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1260 << theGroup1 << ", " << theGroup2 << ", '"
1261 << theName << "' )";
1263 return aResGrp._retn();
1266 //=============================================================================
1268 \brief Cut lists of groups. New group is created. All mesh elements that are
1269 present in main groups but do not present in tool groups are added to the new one
1270 \param theMainGroups list of main groups
1271 \param theToolGroups list of tool groups
1272 \param theName name of group to be created
1273 \return pointer on the group
1275 //=============================================================================
1276 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1277 const SMESH::ListOfGroups& theMainGroups,
1278 const SMESH::ListOfGroups& theToolGroups,
1279 const char* theName )
1280 throw (SALOME::SALOME_Exception)
1283 return SMESH::SMESH_Group::_nil();
1287 NCollection_Map< int > aToolIds;
1288 SMESH::ElementType aType = SMESH::ALL;
1290 // iterate through tool groups
1291 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1293 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1294 if ( CORBA::is_nil( aGrp ) )
1298 SMESH::ElementType aCurrType = aGrp->GetType();
1299 if ( aType == SMESH::ALL )
1303 if ( aType != aCurrType )
1304 return SMESH::SMESH_Group::_nil();
1308 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1309 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1311 int aCurrId = aCurrIds[ i ];
1312 aToolIds.Add( aCurrId );
1316 NCollection_Map< int > anIds; // result
1318 // Iterate through main group
1319 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1321 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1322 if ( CORBA::is_nil( aGrp ) )
1326 SMESH::ElementType aCurrType = aGrp->GetType();
1327 if ( aType == SMESH::ALL )
1331 if ( aType != aCurrType )
1332 return SMESH::SMESH_Group::_nil();
1336 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1337 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1339 int aCurrId = aCurrIds[ i ];
1340 if ( !aToolIds.Contains( aCurrId ) )
1341 anIds.Add( aCurrId );
1346 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1347 if ( aResGrp->_is_nil() )
1348 return SMESH::SMESH_Group::_nil();
1350 // Create array of identifiers
1351 SMESH::long_array_var aResIds = new SMESH::long_array;
1352 aResIds->length( anIds.Extent() );
1354 NCollection_Map< int >::Iterator anIter( anIds );
1355 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1357 aResIds[ i ] = anIter.Value();
1359 aResGrp->Add( aResIds );
1361 // Clear python lines, created by CreateGroup() and Add()
1362 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1363 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1364 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1366 // Update Python script
1368 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1369 << &theMainGroups << ", " << &theToolGroups << ", '"
1370 << theName << "' )";
1372 return aResGrp._retn();
1376 return SMESH::SMESH_Group::_nil();
1380 //=============================================================================
1382 \brief Create groups of entities from existing groups of superior dimensions
1384 1) extract all nodes from each group,
1385 2) combine all elements of specified dimension laying on these nodes.
1386 \param theGroups list of source groups
1387 \param theElemType dimension of elements
1388 \param theName name of new group
1389 \return pointer on new group
1391 //=============================================================================
1392 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1393 const SMESH::ListOfGroups& theGroups,
1394 SMESH::ElementType theElemType,
1395 const char* theName )
1396 throw (SALOME::SALOME_Exception)
1398 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1400 if ( !theName || !aMeshDS )
1401 return SMESH::SMESH_Group::_nil();
1403 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1407 // Create map of nodes from all groups
1409 NCollection_Map< int > aNodeMap;
1411 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1413 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1414 if ( CORBA::is_nil( aGrp ) )
1417 SMESH::ElementType aType = aGrp->GetType();
1418 if ( aType == SMESH::ALL )
1420 else if ( aType == SMESH::NODE )
1422 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1423 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1425 int aCurrId = aCurrIds[ i ];
1426 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1428 aNodeMap.Add( aNode->GetID() );
1433 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1434 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1436 int aCurrId = aCurrIds[ i ];
1437 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1440 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1441 while( aNodeIter->more() )
1443 const SMDS_MeshNode* aNode =
1444 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1446 aNodeMap.Add( aNode->GetID() );
1452 // Get result identifiers
1454 NCollection_Map< int > aResultIds;
1455 if ( theElemType == SMESH::NODE )
1457 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1458 for ( ; aNodeIter.More(); aNodeIter.Next() )
1459 aResultIds.Add( aNodeIter.Value() );
1463 // Create list of elements of given dimension constructed on the nodes
1464 NCollection_Map< int > anElemList;
1465 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1466 for ( ; aNodeIter.More(); aNodeIter.Next() )
1468 const SMDS_MeshElement* aNode =
1469 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1473 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1474 while( anElemIter->more() )
1476 const SMDS_MeshElement* anElem =
1477 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1478 if ( anElem && anElem->GetType() == anElemType )
1479 anElemList.Add( anElem->GetID() );
1483 // check whether all nodes of elements are present in nodes map
1484 NCollection_Map< int >::Iterator anIter( anElemList );
1485 for ( ; anIter.More(); anIter.Next() )
1487 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1492 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1493 while( aNodeIter->more() )
1495 const SMDS_MeshNode* aNode =
1496 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1497 if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1504 aResultIds.Add( anElem->GetID() );
1510 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1511 if ( aResGrp->_is_nil() )
1512 return SMESH::SMESH_Group::_nil();
1514 // Create array of identifiers
1515 SMESH::long_array_var aResIds = new SMESH::long_array;
1516 aResIds->length( aResultIds.Extent() );
1518 NCollection_Map< int >::Iterator aResIter( aResultIds );
1519 for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1520 aResIds[ i ] = aResIter.Value();
1521 aResGrp->Add( aResIds );
1523 // Remove strings corresponding to group creation
1524 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1525 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1526 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1528 // Update Python script
1530 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1531 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1533 return aResGrp._retn();
1537 return SMESH::SMESH_Group::_nil();
1541 //================================================================================
1543 * \brief Remember GEOM group data
1545 //================================================================================
1547 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1548 CORBA::Object_ptr theSmeshObj)
1550 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1553 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1554 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1555 if ( groupSO->_is_nil() )
1558 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1559 GEOM::GEOM_IGroupOperations_var groupOp =
1560 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1561 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1564 _geomGroupData.push_back( TGeomGroupData() );
1565 TGeomGroupData & groupData = _geomGroupData.back();
1567 CORBA::String_var entry = groupSO->GetID();
1568 groupData._groupEntry = entry.in();
1570 for ( int i = 0; i < ids->length(); ++i )
1571 groupData._indices.insert( ids[i] );
1573 groupData._smeshObject = theSmeshObj;
1576 //================================================================================
1578 * Remove GEOM group data relating to removed smesh object
1580 //================================================================================
1582 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1584 list<TGeomGroupData>::iterator
1585 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1586 for ( ; data != dataEnd; ++data ) {
1587 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1588 _geomGroupData.erase( data );
1594 //================================================================================
1596 * \brief Return new group contents if it has been changed and update group data
1598 //================================================================================
1600 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1602 TopoDS_Shape newShape;
1605 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1606 if ( study->_is_nil() ) return newShape; // means "not changed"
1607 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1608 if ( !groupSO->_is_nil() )
1610 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1611 if ( CORBA::is_nil( groupObj )) return newShape;
1612 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1614 // get indices of group items
1615 set<int> curIndices;
1616 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1617 GEOM::GEOM_IGroupOperations_var groupOp =
1618 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1619 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1620 for ( int i = 0; i < ids->length(); ++i )
1621 curIndices.insert( ids[i] );
1623 if ( groupData._indices == curIndices )
1624 return newShape; // group not changed
1627 groupData._indices = curIndices;
1629 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1630 if ( !geomClient ) return newShape;
1631 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1632 geomClient->RemoveShapeFromBuffer( groupIOR );
1633 newShape = _gen_i->GeomObjectToShape( geomGroup );
1636 if ( newShape.IsNull() ) {
1637 // geom group becomes empty - return empty compound
1638 TopoDS_Compound compound;
1639 BRep_Builder().MakeCompound(compound);
1640 newShape = compound;
1646 //=============================================================================
1648 * \brief Storage of shape and index used in CheckGeomGroupModif()
1650 //=============================================================================
1651 struct TIndexedShape {
1653 TopoDS_Shape _shape;
1654 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1657 //=============================================================================
1659 * \brief Update objects depending on changed geom groups
1661 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1662 * issue 0020210: Update of a smesh group after modification of the associated geom group
1664 //=============================================================================
1666 void SMESH_Mesh_i::CheckGeomGroupModif()
1668 if ( !_impl->HasShapeToMesh() ) return;
1670 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1671 if ( study->_is_nil() ) return;
1673 CORBA::Long nbEntities = NbNodes() + NbElements();
1675 // Check if group contents changed
1677 typedef map< string, TopoDS_Shape > TEntry2Geom;
1678 TEntry2Geom newGroupContents;
1680 list<TGeomGroupData>::iterator
1681 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1682 for ( ; data != dataEnd; ++data )
1684 pair< TEntry2Geom::iterator, bool > it_new =
1685 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1686 bool processedGroup = !it_new.second;
1687 TopoDS_Shape& newShape = it_new.first->second;
1688 if ( !processedGroup )
1689 newShape = newGroupShape( *data );
1690 if ( newShape.IsNull() )
1691 continue; // no changes
1693 if ( processedGroup ) { // update group indices
1694 list<TGeomGroupData>::iterator data2 = data;
1695 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1696 data->_indices = data2->_indices;
1699 // Update SMESH objects according to new GEOM group contents
1701 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1702 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1704 int oldID = submesh->GetId();
1705 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1707 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1709 // update hypotheses
1710 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1711 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1712 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1714 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1715 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1717 // care of submeshes
1718 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1719 int newID = newSubmesh->GetId();
1720 if ( newID != oldID ) {
1721 _mapSubMesh [ newID ] = newSubmesh;
1722 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1723 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1724 _mapSubMesh. erase(oldID);
1725 _mapSubMesh_i. erase(oldID);
1726 _mapSubMeshIor.erase(oldID);
1727 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1732 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1733 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1734 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1736 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1738 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1739 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1740 ds->SetShape( newShape );
1745 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1746 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1748 // Remove groups and submeshes basing on removed sub-shapes
1750 TopTools_MapOfShape newShapeMap;
1751 TopoDS_Iterator shapeIt( newShape );
1752 for ( ; shapeIt.More(); shapeIt.Next() )
1753 newShapeMap.Add( shapeIt.Value() );
1755 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1756 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1758 if ( newShapeMap.Contains( shapeIt.Value() ))
1760 TopTools_IndexedMapOfShape oldShapeMap;
1761 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1762 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1764 const TopoDS_Shape& oldShape = oldShapeMap(i);
1765 int oldInd = meshDS->ShapeToIndex( oldShape );
1767 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1768 if ( i_smIor != _mapSubMeshIor.end() ) {
1769 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1772 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1773 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1775 // check if a group bases on oldInd shape
1776 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1777 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1778 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1779 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1781 RemoveGroup( i_grp->second ); // several groups can base on same shape
1782 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1787 // Reassign hypotheses and update groups after setting the new shape to mesh
1789 // collect anassigned hypotheses
1790 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1791 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1792 TShapeHypList assignedHyps;
1793 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1795 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1796 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1797 if ( !hyps.empty() ) {
1798 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1799 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1800 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1803 // collect shapes supporting groups
1804 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1805 TShapeTypeList groupData;
1806 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1807 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1808 for ( ; grIt != groups.end(); ++grIt )
1810 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1812 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1814 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1815 _impl->ShapeToMesh( newShape );
1817 // reassign hypotheses
1818 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1819 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1821 TIndexedShape& geom = indS_hyps->first;
1822 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1823 int oldID = geom._index;
1824 int newID = meshDS->ShapeToIndex( geom._shape );
1827 if ( oldID == 1 ) { // main shape
1829 geom._shape = newShape;
1831 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1832 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1833 // care of submeshes
1834 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1835 if ( newID != oldID ) {
1836 _mapSubMesh [ newID ] = newSubmesh;
1837 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1838 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1839 _mapSubMesh. erase(oldID);
1840 _mapSubMesh_i. erase(oldID);
1841 _mapSubMeshIor.erase(oldID);
1842 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1846 TShapeTypeList::iterator geomType = groupData.begin();
1847 for ( ; geomType != groupData.end(); ++geomType )
1849 const TIndexedShape& geom = geomType->first;
1850 int oldID = geom._index;
1851 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1854 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1855 CORBA::String_var name = groupSO->GetName();
1857 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1859 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1860 group_i->changeLocalId( newID );
1863 break; // everything has been updated
1866 } // loop on group data
1870 CORBA::Long newNbEntities = NbNodes() + NbElements();
1871 list< SALOMEDS::SObject_var > soToUpdateIcons;
1872 if ( newNbEntities != nbEntities )
1874 // Add all SObjects with icons
1875 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1877 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1878 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1879 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1881 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1882 i_gr != _mapGroups.end(); ++i_gr ) // groups
1883 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1886 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1887 for ( ; so != soToUpdateIcons.end(); ++so )
1888 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1891 //=============================================================================
1893 * \brief Create standalone group instead if group on geometry
1895 //=============================================================================
1897 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1899 SMESH::SMESH_Group_var aGroup;
1900 if ( theGroup->_is_nil() )
1901 return aGroup._retn();
1903 Unexpect aCatch(SALOME_SalomeException);
1905 SMESH_GroupBase_i* aGroupToRem =
1906 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1908 return aGroup._retn();
1910 int anId = aGroupToRem->GetLocalID();
1911 if ( !_impl->ConvertToStandalone( anId ) )
1912 return aGroup._retn();
1913 removeGeomGroupData( theGroup );
1915 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1917 // remove old instance of group from own map
1918 _mapGroups.erase( anId );
1920 SALOMEDS::StudyBuilder_var builder;
1921 SALOMEDS::SObject_var aGroupSO;
1922 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1923 if ( !aStudy->_is_nil() ) {
1924 builder = aStudy->NewBuilder();
1925 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1926 if ( !aGroupSO->_is_nil() ) {
1928 // remove reference to geometry
1929 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1930 for ( ; chItr->More(); chItr->Next() )
1931 // Remove group's child SObject
1932 builder->RemoveObject( chItr->Value() );
1934 // Update Python script
1935 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1936 << aGroupSO << " )";
1940 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1941 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1942 aGroupImpl->Register();
1943 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1945 // remember new group in own map
1946 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1947 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1949 // register CORBA object for persistence
1950 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1952 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1954 return aGroup._retn();
1957 //=============================================================================
1961 //=============================================================================
1963 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1965 if(MYDEBUG) MESSAGE( "createSubMesh" );
1966 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1968 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1969 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1970 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1971 SMESH::SMESH_subMesh_var subMesh
1972 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1974 _mapSubMesh[subMeshId] = mySubMesh;
1975 _mapSubMesh_i[subMeshId] = subMeshServant;
1976 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1978 // register CORBA object for persistence
1979 int nextId = _gen_i->RegisterObject( subMesh );
1980 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1982 // to track changes of GEOM groups
1983 addGeomGroupData( theSubShapeObject, subMesh );
1985 return subMesh._retn();
1988 //=======================================================================
1989 //function : getSubMesh
1991 //=======================================================================
1993 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1995 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1996 if ( it == _mapSubMeshIor.end() )
1997 return SMESH::SMESH_subMesh::_nil();
1999 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2003 //=============================================================================
2007 //=============================================================================
2009 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2010 GEOM::GEOM_Object_ptr theSubShapeObject )
2012 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2013 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2016 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2018 CORBA::Long shapeId = theSubMesh->GetId();
2019 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2021 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2024 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2025 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2026 for ( ; hyp != hyps.end(); ++hyp )
2027 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2034 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2035 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2036 removeHypothesis( theSubShapeObject, aHypList[i] );
2039 catch( const SALOME::SALOME_Exception& ) {
2040 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2042 removeGeomGroupData( theSubShapeObject );
2044 int subMeshId = theSubMesh->GetId();
2046 _mapSubMesh.erase(subMeshId);
2047 _mapSubMesh_i.erase(subMeshId);
2048 _mapSubMeshIor.erase(subMeshId);
2049 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2052 //=============================================================================
2056 //=============================================================================
2058 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2059 const char* theName,
2060 const TopoDS_Shape& theShape )
2063 SMESH::SMESH_GroupBase_var aGroup;
2064 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2065 SMESH_GroupBase_i* aGroupImpl;
2066 if ( !theShape.IsNull() )
2067 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2069 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2071 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2072 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2073 aGroupImpl->Register();
2074 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2076 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2077 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2079 // register CORBA object for persistence
2080 int nextId = _gen_i->RegisterObject( aGroup );
2081 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2083 // to track changes of GEOM groups
2084 if ( !theShape.IsNull() ) {
2085 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2086 addGeomGroupData( geom, aGroup );
2089 return aGroup._retn();
2092 //=============================================================================
2094 * SMESH_Mesh_i::removeGroup
2096 * Should be called by ~SMESH_Group_i()
2098 //=============================================================================
2100 void SMESH_Mesh_i::removeGroup( const int theId )
2102 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2103 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2104 removeGeomGroupData( _mapGroups[theId] );
2105 _mapGroups.erase( theId );
2106 _impl->RemoveGroup( theId );
2111 //=============================================================================
2115 //=============================================================================
2117 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2118 throw(SALOME::SALOME_Exception)
2120 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2122 SMESH::log_array_var aLog;
2124 list < SMESHDS_Command * >logDS = _impl->GetLog();
2125 aLog = new SMESH::log_array;
2127 int lg = logDS.size();
2130 list < SMESHDS_Command * >::iterator its = logDS.begin();
2131 while(its != logDS.end()){
2132 SMESHDS_Command *com = *its;
2133 int comType = com->GetType();
2135 int lgcom = com->GetNumber();
2137 const list < int >&intList = com->GetIndexes();
2138 int inum = intList.size();
2140 list < int >::const_iterator ii = intList.begin();
2141 const list < double >&coordList = com->GetCoords();
2142 int rnum = coordList.size();
2144 list < double >::const_iterator ir = coordList.begin();
2145 aLog[indexLog].commandType = comType;
2146 aLog[indexLog].number = lgcom;
2147 aLog[indexLog].coords.length(rnum);
2148 aLog[indexLog].indexes.length(inum);
2149 for(int i = 0; i < rnum; i++){
2150 aLog[indexLog].coords[i] = *ir;
2151 //MESSAGE(" "<<i<<" "<<ir.Value());
2154 for(int i = 0; i < inum; i++){
2155 aLog[indexLog].indexes[i] = *ii;
2156 //MESSAGE(" "<<i<<" "<<ii.Value());
2165 catch(SALOME_Exception & S_ex){
2166 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2168 return aLog._retn();
2172 //=============================================================================
2176 //=============================================================================
2178 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2180 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2184 //=============================================================================
2188 //=============================================================================
2190 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2192 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2196 //=============================================================================
2200 //=============================================================================
2202 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2207 //=============================================================================
2211 //=============================================================================
2213 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2215 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2219 //=============================================================================
2223 //=============================================================================
2225 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2227 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2231 //=============================================================================
2233 * Return mesh editor
2235 //=============================================================================
2237 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2239 // Create MeshEditor
2240 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2241 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2243 // Update Python script
2244 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2246 return aMesh._retn();
2249 //=============================================================================
2251 * Return mesh edition previewer
2253 //=============================================================================
2255 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2257 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2258 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2259 return aMesh._retn();
2262 //================================================================================
2264 * \brief Return true if the mesh has been edited since a last total re-compute
2265 * and those modifications may prevent successful partial re-compute
2267 //================================================================================
2269 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2271 Unexpect aCatch(SALOME_SalomeException);
2272 return _impl->HasModificationsToDiscard();
2275 //=============================================================================
2279 //=============================================================================
2280 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2282 Unexpect aCatch(SALOME_SalomeException);
2283 _impl->SetAutoColor(theAutoColor);
2286 //=============================================================================
2290 //=============================================================================
2291 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2293 Unexpect aCatch(SALOME_SalomeException);
2294 return _impl->GetAutoColor();
2298 //=============================================================================
2300 * Export in different formats
2302 //=============================================================================
2304 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2306 return _impl->HasDuplicatedGroupNamesMED();
2309 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2311 TCollection_AsciiString aFullName ((char*)file);
2312 OSD_Path aPath (aFullName);
2313 OSD_File aFile (aPath);
2314 if (aFile.Exists()) {
2315 // existing filesystem node
2316 if (aFile.KindOfFile() == OSD_FILE) {
2317 if (aFile.IsWriteable()) {
2322 if (aFile.Failed()) {
2323 TCollection_AsciiString msg ("File ");
2324 msg += aFullName + " cannot be replaced.";
2325 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2328 TCollection_AsciiString msg ("File ");
2329 msg += aFullName + " cannot be overwritten.";
2330 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2333 TCollection_AsciiString msg ("Location ");
2334 msg += aFullName + " is not a file.";
2335 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2338 // nonexisting file; check if it can be created
2340 aFile.Build(OSD_WriteOnly, OSD_Protection());
2341 if (aFile.Failed()) {
2342 TCollection_AsciiString msg ("You cannot create the file ");
2343 msg += aFullName + ". Check the directory existance and access rights.";
2344 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2352 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2353 CORBA::Boolean auto_groups,
2354 SMESH::MED_VERSION theVersion,
2355 CORBA::Boolean overwrite)
2356 throw(SALOME::SALOME_Exception)
2358 Unexpect aCatch(SALOME_SalomeException);
2361 PrepareForWriting(file, overwrite);
2362 const char* aMeshName = "Mesh";
2363 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2364 if ( !aStudy->_is_nil() ) {
2365 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2366 if ( !aMeshSO->_is_nil() ) {
2367 aMeshName = aMeshSO->GetName();
2368 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2369 if ( !aStudy->GetProperties()->IsLocked() )
2371 SALOMEDS::GenericAttribute_var anAttr;
2372 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2373 SALOMEDS::AttributeExternalFileDef_var aFileName;
2374 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2375 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2376 ASSERT(!aFileName->_is_nil());
2377 aFileName->SetValue(file);
2378 SALOMEDS::AttributeFileType_var aFileType;
2379 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2380 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2381 ASSERT(!aFileType->_is_nil());
2382 aFileType->SetValue("FICHIERMED");
2386 // Update Python script
2387 // set name of mesh before export
2388 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2390 // check names of groups
2393 TPythonDump() << _this() << ".ExportToMEDX( r'"
2394 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2396 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2399 void SMESH_Mesh_i::ExportToMED (const char* file,
2400 CORBA::Boolean auto_groups,
2401 SMESH::MED_VERSION theVersion)
2402 throw(SALOME::SALOME_Exception)
2404 ExportToMEDX(file,auto_groups,theVersion,true);
2407 void SMESH_Mesh_i::ExportMED (const char* file,
2408 CORBA::Boolean auto_groups)
2409 throw(SALOME::SALOME_Exception)
2411 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2414 void SMESH_Mesh_i::ExportDAT (const char *file)
2415 throw(SALOME::SALOME_Exception)
2417 Unexpect aCatch(SALOME_SalomeException);
2419 // Update Python script
2420 // check names of groups
2422 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2425 PrepareForWriting(file);
2426 _impl->ExportDAT(file);
2429 void SMESH_Mesh_i::ExportUNV (const char *file)
2430 throw(SALOME::SALOME_Exception)
2432 Unexpect aCatch(SALOME_SalomeException);
2434 // Update Python script
2435 // check names of groups
2437 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2440 PrepareForWriting(file);
2441 _impl->ExportUNV(file);
2444 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2445 throw(SALOME::SALOME_Exception)
2447 Unexpect aCatch(SALOME_SalomeException);
2449 // Update Python script
2450 // check names of groups
2452 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2455 PrepareForWriting(file);
2456 _impl->ExportSTL(file, isascii);
2459 //=============================================================================
2463 //=============================================================================
2465 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2467 Unexpect aCatch(SALOME_SalomeException);
2468 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2469 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2470 return aMesh._retn();
2473 //=============================================================================
2477 //=============================================================================
2478 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2480 Unexpect aCatch(SALOME_SalomeException);
2481 return _impl->NbNodes();
2484 //=============================================================================
2488 //=============================================================================
2489 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2491 Unexpect aCatch(SALOME_SalomeException);
2492 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2495 //=============================================================================
2499 //=============================================================================
2500 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2502 Unexpect aCatch(SALOME_SalomeException);
2503 return _impl->Nb0DElements();
2506 //=============================================================================
2510 //=============================================================================
2511 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2513 Unexpect aCatch(SALOME_SalomeException);
2514 return _impl->NbEdges();
2517 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2518 throw(SALOME::SALOME_Exception)
2520 Unexpect aCatch(SALOME_SalomeException);
2521 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2524 //=============================================================================
2528 //=============================================================================
2529 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2531 Unexpect aCatch(SALOME_SalomeException);
2532 return _impl->NbFaces();
2535 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2537 Unexpect aCatch(SALOME_SalomeException);
2538 return _impl->NbTriangles();
2541 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2543 Unexpect aCatch(SALOME_SalomeException);
2544 return _impl->NbQuadrangles();
2547 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2549 Unexpect aCatch(SALOME_SalomeException);
2550 return _impl->NbPolygons();
2553 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2554 throw(SALOME::SALOME_Exception)
2556 Unexpect aCatch(SALOME_SalomeException);
2557 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2560 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2561 throw(SALOME::SALOME_Exception)
2563 Unexpect aCatch(SALOME_SalomeException);
2564 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2567 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2568 throw(SALOME::SALOME_Exception)
2570 Unexpect aCatch(SALOME_SalomeException);
2571 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2574 //=============================================================================
2578 //=============================================================================
2579 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2581 Unexpect aCatch(SALOME_SalomeException);
2582 return _impl->NbVolumes();
2585 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2587 Unexpect aCatch(SALOME_SalomeException);
2588 return _impl->NbTetras();
2591 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2593 Unexpect aCatch(SALOME_SalomeException);
2594 return _impl->NbHexas();
2597 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2599 Unexpect aCatch(SALOME_SalomeException);
2600 return _impl->NbPyramids();
2603 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2605 Unexpect aCatch(SALOME_SalomeException);
2606 return _impl->NbPrisms();
2609 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2611 Unexpect aCatch(SALOME_SalomeException);
2612 return _impl->NbPolyhedrons();
2615 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2616 throw(SALOME::SALOME_Exception)
2618 Unexpect aCatch(SALOME_SalomeException);
2619 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2622 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2623 throw(SALOME::SALOME_Exception)
2625 Unexpect aCatch(SALOME_SalomeException);
2626 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2629 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2630 throw(SALOME::SALOME_Exception)
2632 Unexpect aCatch(SALOME_SalomeException);
2633 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2636 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2637 throw(SALOME::SALOME_Exception)
2639 Unexpect aCatch(SALOME_SalomeException);
2640 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2643 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2644 throw(SALOME::SALOME_Exception)
2646 Unexpect aCatch(SALOME_SalomeException);
2647 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2650 //=============================================================================
2654 //=============================================================================
2655 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2657 Unexpect aCatch(SALOME_SalomeException);
2658 return _mapSubMesh_i.size();
2661 //=============================================================================
2665 //=============================================================================
2666 char* SMESH_Mesh_i::Dump()
2670 return CORBA::string_dup( os.str().c_str() );
2673 //=============================================================================
2677 //=============================================================================
2678 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2680 // SMESH::long_array_var aResult = new SMESH::long_array();
2681 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2682 // int aMinId = aSMESHDS_Mesh->MinElementID();
2683 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2685 // aResult->length(aMaxId - aMinId + 1);
2687 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2688 // aResult[i++] = id;
2690 // return aResult._retn();
2692 return GetElementsId();
2695 //=============================================================================
2699 //=============================================================================
2701 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2702 throw (SALOME::SALOME_Exception)
2704 Unexpect aCatch(SALOME_SalomeException);
2705 MESSAGE("SMESH_Mesh_i::GetElementsId");
2706 SMESH::long_array_var aResult = new SMESH::long_array();
2707 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2709 if ( aSMESHDS_Mesh == NULL )
2710 return aResult._retn();
2712 long nbElements = NbElements();
2713 aResult->length( nbElements );
2714 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2715 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2716 aResult[i] = anIt->next()->GetID();
2718 return aResult._retn();
2722 //=============================================================================
2726 //=============================================================================
2728 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2729 throw (SALOME::SALOME_Exception)
2731 Unexpect aCatch(SALOME_SalomeException);
2732 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2733 SMESH::long_array_var aResult = new SMESH::long_array();
2734 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2736 if ( aSMESHDS_Mesh == NULL )
2737 return aResult._retn();
2739 long nbElements = NbElements();
2741 // No sense in returning ids of elements along with ids of nodes:
2742 // when theElemType == SMESH::ALL, return node ids only if
2743 // there are no elements
2744 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2745 return GetNodesId();
2747 aResult->length( nbElements );
2751 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2752 while ( i < nbElements && anIt->more() ) {
2753 const SMDS_MeshElement* anElem = anIt->next();
2754 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2755 aResult[i++] = anElem->GetID();
2758 aResult->length( i );
2760 return aResult._retn();
2763 //=============================================================================
2767 //=============================================================================
2769 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2770 throw (SALOME::SALOME_Exception)
2772 Unexpect aCatch(SALOME_SalomeException);
2773 MESSAGE("SMESH_subMesh_i::GetNodesId");
2774 SMESH::long_array_var aResult = new SMESH::long_array();
2775 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2777 if ( aSMESHDS_Mesh == NULL )
2778 return aResult._retn();
2780 long nbNodes = NbNodes();
2781 aResult->length( nbNodes );
2782 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2783 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2784 aResult[i] = anIt->next()->GetID();
2786 return aResult._retn();
2789 //=============================================================================
2793 //=============================================================================
2795 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2796 throw (SALOME::SALOME_Exception)
2798 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2801 //=============================================================================
2805 //=============================================================================
2807 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2808 throw (SALOME::SALOME_Exception)
2810 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2812 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2814 return ( SMESH::EntityType ) e->GetEntityType();
2817 //=============================================================================
2819 * Returns ID of elements for given submesh
2821 //=============================================================================
2822 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2823 throw (SALOME::SALOME_Exception)
2825 SMESH::long_array_var aResult = new SMESH::long_array();
2827 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2828 if(!SM) return aResult._retn();
2830 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2831 if(!SDSM) return aResult._retn();
2833 aResult->length(SDSM->NbElements());
2835 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2837 while ( eIt->more() ) {
2838 aResult[i++] = eIt->next()->GetID();
2841 return aResult._retn();
2845 //=============================================================================
2847 * Returns ID of nodes for given submesh
2848 * If param all==true - returns all nodes, else -
2849 * returns only nodes on shapes.
2851 //=============================================================================
2852 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2853 throw (SALOME::SALOME_Exception)
2855 SMESH::long_array_var aResult = new SMESH::long_array();
2857 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2858 if(!SM) return aResult._retn();
2860 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2861 if(!SDSM) return aResult._retn();
2864 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2865 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2866 while ( nIt->more() ) {
2867 const SMDS_MeshNode* elem = nIt->next();
2868 theElems.insert( elem->GetID() );
2871 else { // all nodes of submesh elements
2872 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2873 while ( eIt->more() ) {
2874 const SMDS_MeshElement* anElem = eIt->next();
2875 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2876 while ( nIt->more() ) {
2877 const SMDS_MeshElement* elem = nIt->next();
2878 theElems.insert( elem->GetID() );
2883 aResult->length(theElems.size());
2884 set<int>::iterator itElem;
2886 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2887 aResult[i++] = *itElem;
2889 return aResult._retn();
2893 //=============================================================================
2895 * Returns type of elements for given submesh
2897 //=============================================================================
2898 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2899 throw (SALOME::SALOME_Exception)
2901 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2902 if(!SM) return SMESH::ALL;
2904 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2905 if(!SDSM) return SMESH::ALL;
2907 if(SDSM->NbElements()==0)
2908 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2910 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2911 const SMDS_MeshElement* anElem = eIt->next();
2912 return ( SMESH::ElementType ) anElem->GetType();
2916 //=============================================================================
2920 //=============================================================================
2922 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2924 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2926 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2931 //=============================================================================
2933 * Get XYZ coordinates of node as list of double
2934 * If there is not node for given ID - returns empty list
2936 //=============================================================================
2938 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2940 SMESH::double_array_var aResult = new SMESH::double_array();
2941 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2942 if ( aSMESHDS_Mesh == NULL )
2943 return aResult._retn();
2946 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2948 return aResult._retn();
2952 aResult[0] = aNode->X();
2953 aResult[1] = aNode->Y();
2954 aResult[2] = aNode->Z();
2955 return aResult._retn();
2959 //=============================================================================
2961 * For given node returns list of IDs of inverse elements
2962 * If there is not node for given ID - returns empty list
2964 //=============================================================================
2966 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2968 SMESH::long_array_var aResult = new SMESH::long_array();
2969 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2970 if ( aSMESHDS_Mesh == NULL )
2971 return aResult._retn();
2974 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2976 return aResult._retn();
2978 // find inverse elements
2979 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2980 TColStd_SequenceOfInteger IDs;
2981 while(eIt->more()) {
2982 const SMDS_MeshElement* elem = eIt->next();
2983 IDs.Append(elem->GetID());
2985 if(IDs.Length()>0) {
2986 aResult->length(IDs.Length());
2988 for(; i<=IDs.Length(); i++) {
2989 aResult[i-1] = IDs.Value(i);
2992 return aResult._retn();
2995 //=============================================================================
2997 * \brief Return position of a node on shape
2999 //=============================================================================
3001 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3003 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3004 aNodePosition->shapeID = 0;
3005 aNodePosition->shapeType = GEOM::SHAPE;
3007 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3008 if ( !mesh ) return aNodePosition;
3010 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3012 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3014 aNodePosition->shapeID = pos->GetShapeId();
3015 switch ( pos->GetTypeOfPosition() ) {
3017 aNodePosition->shapeType = GEOM::EDGE;
3018 aNodePosition->params.length(1);
3019 aNodePosition->params[0] =
3020 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
3023 aNodePosition->shapeType = GEOM::FACE;
3024 aNodePosition->params.length(2);
3025 aNodePosition->params[0] =
3026 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
3027 aNodePosition->params[1] =
3028 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
3030 case SMDS_TOP_VERTEX:
3031 aNodePosition->shapeType = GEOM::VERTEX;
3033 case SMDS_TOP_3DSPACE:
3034 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3035 aNodePosition->shapeType = GEOM::SOLID;
3036 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3037 aNodePosition->shapeType = GEOM::SHELL;
3043 return aNodePosition;
3046 //=============================================================================
3048 * If given element is node returns IDs of shape from position
3049 * If there is not node for given ID - returns -1
3051 //=============================================================================
3053 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3055 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3056 if ( aSMESHDS_Mesh == NULL )
3060 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3062 SMDS_PositionPtr pos = aNode->GetPosition();
3066 return pos->GetShapeId();
3073 //=============================================================================
3075 * For given element returns ID of result shape after
3076 * ::FindShape() from SMESH_MeshEditor
3077 * If there is not element for given ID - returns -1
3079 //=============================================================================
3081 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3083 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3084 if ( aSMESHDS_Mesh == NULL )
3087 // try to find element
3088 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3092 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3093 ::SMESH_MeshEditor aMeshEditor(_impl);
3094 int index = aMeshEditor.FindShape( elem );
3102 //=============================================================================
3104 * Returns number of nodes for given element
3105 * If there is not element for given ID - returns -1
3107 //=============================================================================
3109 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3111 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3112 if ( aSMESHDS_Mesh == NULL ) return -1;
3113 // try to find element
3114 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3115 if(!elem) return -1;
3116 return elem->NbNodes();
3120 //=============================================================================
3122 * Returns ID of node by given index for given element
3123 * If there is not element for given ID - returns -1
3124 * If there is not node for given index - returns -2
3126 //=============================================================================
3128 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3130 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3131 if ( aSMESHDS_Mesh == NULL ) return -1;
3132 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3133 if(!elem) return -1;
3134 if( index>=elem->NbNodes() || index<0 ) return -1;
3135 return elem->GetNode(index)->GetID();
3138 //=============================================================================
3140 * Returns IDs of nodes of given element
3142 //=============================================================================
3144 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3146 SMESH::long_array_var aResult = new SMESH::long_array();
3147 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3149 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3151 aResult->length( elem->NbNodes() );
3152 for ( int i = 0; i < elem->NbNodes(); ++i )
3153 aResult[ i ] = elem->GetNode( i )->GetID();
3156 return aResult._retn();
3159 //=============================================================================
3161 * Returns true if given node is medium node
3162 * in given quadratic element
3164 //=============================================================================
3166 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3168 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3169 if ( aSMESHDS_Mesh == NULL ) return false;
3171 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3172 if(!aNode) return false;
3173 // try to find element
3174 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3175 if(!elem) return false;
3177 return elem->IsMediumNode(aNode);
3181 //=============================================================================
3183 * Returns true if given node is medium node
3184 * in one of quadratic elements
3186 //=============================================================================
3188 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3189 SMESH::ElementType theElemType)
3191 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3192 if ( aSMESHDS_Mesh == NULL ) return false;
3195 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3196 if(!aNode) return false;
3198 SMESH_MesherHelper aHelper( *(_impl) );
3200 SMDSAbs_ElementType aType;
3201 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3202 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3203 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3204 else aType = SMDSAbs_All;
3206 return aHelper.IsMedium(aNode,aType);
3210 //=============================================================================
3212 * Returns number of edges for given element
3214 //=============================================================================
3216 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3218 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3219 if ( aSMESHDS_Mesh == NULL ) return -1;
3220 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3221 if(!elem) return -1;
3222 return elem->NbEdges();
3226 //=============================================================================
3228 * Returns number of faces for given element
3230 //=============================================================================
3232 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3234 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3235 if ( aSMESHDS_Mesh == NULL ) return -1;
3236 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3237 if(!elem) return -1;
3238 return elem->NbFaces();
3241 //=======================================================================
3242 //function : GetElemFaceNodes
3243 //purpose : Returns nodes of given face (counted from zero) for given element.
3244 //=======================================================================
3246 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3247 CORBA::Short faceIndex)
3249 SMESH::long_array_var aResult = new SMESH::long_array();
3250 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3252 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3254 SMDS_VolumeTool vtool( elem );
3255 if ( faceIndex < vtool.NbFaces() )
3257 aResult->length( vtool.NbFaceNodes( faceIndex ));
3258 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3259 for ( int i = 0; i < aResult->length(); ++i )
3260 aResult[ i ] = nn[ i ]->GetID();
3264 return aResult._retn();
3267 //=======================================================================
3268 //function : FindElementByNodes
3269 //purpose : Returns an element based on all given nodes.
3270 //=======================================================================
3272 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3274 CORBA::Long elemID(0);
3275 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3277 vector< const SMDS_MeshNode * > nn( nodes.length() );
3278 for ( int i = 0; i < nodes.length(); ++i )
3279 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3282 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3283 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3284 _impl->NbFaces( ORDER_QUADRATIC ) ||
3285 _impl->NbVolumes( ORDER_QUADRATIC )))
3286 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3288 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3293 //=============================================================================
3295 * Returns true if given element is polygon
3297 //=============================================================================
3299 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3301 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3302 if ( aSMESHDS_Mesh == NULL ) return false;
3303 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3304 if(!elem) return false;
3305 return elem->IsPoly();
3309 //=============================================================================
3311 * Returns true if given element is quadratic
3313 //=============================================================================
3315 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3317 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3318 if ( aSMESHDS_Mesh == NULL ) return false;
3319 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3320 if(!elem) return false;
3321 return elem->IsQuadratic();
3325 //=============================================================================
3327 * Returns bary center for given element
3329 //=============================================================================
3331 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3333 SMESH::double_array_var aResult = new SMESH::double_array();
3334 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3335 if ( aSMESHDS_Mesh == NULL )
3336 return aResult._retn();
3338 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3340 return aResult._retn();
3342 if(elem->GetType()==SMDSAbs_Volume) {
3343 SMDS_VolumeTool aTool;
3344 if(aTool.Set(elem)) {
3346 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3351 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3353 double x=0., y=0., z=0.;
3354 for(; anIt->more(); ) {
3356 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3370 return aResult._retn();
3374 //=============================================================================
3376 * Create and publish group servants if any groups were imported or created anyhow
3378 //=============================================================================
3380 void SMESH_Mesh_i::CreateGroupServants()
3382 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3384 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3385 while ( groupIt->more() )
3387 ::SMESH_Group* group = groupIt->next();
3388 int anId = group->GetGroupDS()->GetID();
3390 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3391 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3394 SMESH_GroupBase_i* aGroupImpl;
3396 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3397 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3399 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3400 shape = groupOnGeom->GetShape();
3403 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3406 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3407 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3408 aGroupImpl->Register();
3410 SMESH::SMESH_GroupBase_var groupVar =
3411 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3412 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3414 // register CORBA object for persistence
3415 int nextId = _gen_i->RegisterObject( groupVar );
3416 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3418 // publishing of the groups in the study
3419 if ( !aStudy->_is_nil() ) {
3420 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3421 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3426 //=============================================================================
3428 * \brief Return groups cantained in _mapGroups by their IDs
3430 //=============================================================================
3432 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3434 int nbGroups = groupIDs.size();
3435 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3436 aList->length( nbGroups );
3438 list<int>::const_iterator ids = groupIDs.begin();
3439 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3441 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3442 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3443 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3445 aList->length( nbGroups );
3446 return aList._retn();
3449 //=============================================================================
3451 * \brief Return information about imported file
3453 //=============================================================================
3455 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3457 SALOME_MED::MedFileInfo_var res( myFileInfo );
3458 if ( !res.operator->() ) {
3459 res = new SALOME_MED::MedFileInfo;
3461 res->fileSize = res->major = res->minor = res->release = -1;
3466 //=============================================================================
3468 * \brief Check and correct names of mesh groups
3470 //=============================================================================
3472 void SMESH_Mesh_i::checkGroupNames()
3474 int nbGrp = NbGroups();
3478 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3479 if ( aStudy->_is_nil() )
3480 return; // nothing to do
3482 SMESH::ListOfGroups* grpList = 0;
3483 // avoid dump of "GetGroups"
3485 // store python dump into a local variable inside local scope
3486 SMESH::TPythonDump pDump; // do not delete this line of code
3487 grpList = GetGroups();
3490 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3491 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3494 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3495 if ( aGrpSO->_is_nil() )
3497 // correct name of the mesh group if necessary
3498 const char* guiName = aGrpSO->GetName();
3499 if ( strcmp(guiName, aGrp->GetName()) )
3500 aGrp->SetName( guiName );
3504 //=============================================================================
3506 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3508 //=============================================================================
3509 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3511 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3512 CORBA::string_dup(theParameters));
3515 //=============================================================================
3517 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3519 //=============================================================================
3520 char* SMESH_Mesh_i::GetParameters()
3522 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3523 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3526 //=============================================================================
3528 * \brief Returns list of notebook variables used for last Mesh operation
3530 //=============================================================================
3531 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3533 SMESH::string_array_var aResult = new SMESH::string_array();
3534 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3536 char *aParameters = GetParameters();
3537 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3538 if(!aStudy->_is_nil()) {
3539 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3540 if(aSections->length() > 0) {
3541 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3542 aResult->length(aVars.length());
3543 for(int i = 0;i < aVars.length();i++)
3544 aResult[i] = CORBA::string_dup( aVars[i]);
3548 return aResult._retn();
3551 //=============================================================================
3553 * \brief Returns statistic of mesh elements
3555 //=============================================================================
3556 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3558 SMESH::long_array_var aRes = new SMESH::long_array();
3559 aRes->length(SMESH::Entity_Last);
3560 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3562 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3564 return aRes._retn();
3565 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3566 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3567 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3568 return aRes._retn();
3571 //=============================================================================
3573 * \brief Collect statistic of mesh elements given by iterator
3575 //=============================================================================
3576 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3577 SMESH::long_array& theInfo)
3579 if (!theItr) return;
3580 while (theItr->more())
3581 theInfo[ theItr->next()->GetEntityType() ]++;
3584 //=============================================================================
3586 * \brief mapping of mesh dimension into shape type
3588 //=============================================================================
3589 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3591 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3593 case 0: aType = TopAbs_VERTEX; break;
3594 case 1: aType = TopAbs_EDGE; break;
3595 case 2: aType = TopAbs_FACE; break;
3597 default:aType = TopAbs_SOLID; break;
3602 //=============================================================================
3604 * \brief Internal structure used to find concurent submeshes
3606 * It represents a pair < submesh, concurent dimension >, where
3607 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3608 * with another submesh. In other words, it is dimension of a hypothesis assigned
3611 //=============================================================================
3617 int _dim; //!< a dimension the algo can build (concurrent dimension)
3618 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3619 TopTools_MapOfShape _shapeMap;
3620 SMESH_subMesh* _subMesh;
3621 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3624 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3626 const TopoDS_Shape& theShape)
3628 _subMesh = (SMESH_subMesh*)theSubMesh;
3629 SetShape( theDim, theShape );
3633 void SetShape(const int theDim,
3634 const TopoDS_Shape& theShape)
3637 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3638 if (_dim >= _ownDim)
3639 _shapeMap.Add( theShape );
3641 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3642 for( ; anExp.More(); anExp.Next() )
3643 _shapeMap.Add( anExp.Current() );
3647 //! Check sharing of sub shapes
3648 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3649 const TopTools_MapOfShape& theToFind,
3650 const TopAbs_ShapeEnum theType)
3652 bool isShared = false;
3653 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3654 for (; !isShared && anItr.More(); anItr.Next() ) {
3655 const TopoDS_Shape aSubSh = anItr.Key();
3656 // check for case when concurrent dimensions are same
3657 isShared = theToFind.Contains( aSubSh );
3658 // check for subshape with concurrent dimension
3659 TopExp_Explorer anExp( aSubSh, theType );
3660 for ( ; !isShared && anExp.More(); anExp.Next() )
3661 isShared = theToFind.Contains( anExp.Current() );
3666 //! check algorithms
3667 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3668 const SMESHDS_Hypothesis* theA2)
3670 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3671 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3672 return false; // one of the hypothesis is not algorithm
3673 // check algorithm names (should be equal)
3674 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3678 //! Check if subshape hypotheses are concurrent
3679 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3681 if ( _subMesh == theOther->_subMesh )
3682 return false; // same subshape - should not be
3684 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3685 // any of the two submeshes is not on COMPOUND shape )
3686 // -> no concurrency
3687 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3688 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3689 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3692 // bool checkSubShape = ( _dim >= theOther->_dim )
3693 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3694 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3695 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3696 if ( !checkSubShape )
3699 // check algorithms to be same
3700 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3701 return true; // different algorithms
3703 // check hypothesises for concurrence (skip first as algorithm)
3705 // pointers should be same, becase it is referenes from mesh hypothesis partition
3706 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3707 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3708 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3709 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3711 // the submeshes are concurrent if their algorithms has different parameters
3712 return nbSame != theOther->_hypothesises.size() - 1;
3715 }; // end of SMESH_DimHyp
3717 typedef list<SMESH_DimHyp*> TDimHypList;
3719 static void addDimHypInstance(const int theDim,
3720 const TopoDS_Shape& theShape,
3721 const SMESH_Algo* theAlgo,
3722 const SMESH_subMesh* theSubMesh,
3723 const list <const SMESHDS_Hypothesis*>& theHypList,
3724 TDimHypList* theDimHypListArr )
3726 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3727 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3728 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3729 listOfdimHyp.push_back( dimHyp );
3732 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3733 dimHyp->_hypothesises.push_front(theAlgo);
3734 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3735 for( ; hypIt != theHypList.end(); hypIt++ )
3736 dimHyp->_hypothesises.push_back( *hypIt );
3739 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3740 const TDimHypList& theListOfDimHyp,
3741 TListOfInt& theListOfConcurr )
3743 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3744 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3745 const SMESH_DimHyp* curDimHyp = *rIt;
3746 if ( curDimHyp == theDimHyp )
3747 break; // meet own dimHyp pointer in same dimension
3748 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3749 if ( find( theListOfConcurr.begin(),
3750 theListOfConcurr.end(),
3751 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3752 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3756 static void unionLists(TListOfInt& theListOfId,
3757 TListOfListOfInt& theListOfListOfId,
3760 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3761 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3763 continue; //skip already treated lists
3764 // check if other list has any same submesh object
3765 TListOfInt& otherListOfId = *it;
3766 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3767 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3770 // union two lists (from source into target)
3771 TListOfInt::iterator it2 = otherListOfId.begin();
3772 for ( ; it2 != otherListOfId.end(); it2++ ) {
3773 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3774 theListOfId.push_back(*it2);
3776 // clear source list
3777 otherListOfId.clear();
3781 //! free memory allocated for dimension-hypothesis objects
3782 static void removeDimHyps( TDimHypList* theArrOfList )
3784 for (int i = 0; i < 4; i++ ) {
3785 TDimHypList& listOfdimHyp = theArrOfList[i];
3786 TDimHypList::const_iterator it = listOfdimHyp.begin();
3787 for ( ; it != listOfdimHyp.end(); it++ )
3792 //=============================================================================
3794 * \brief Return submesh objects list in meshing order
3796 //=============================================================================
3798 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3800 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3802 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3804 return aResult._retn();
3806 ::SMESH_Mesh& mesh = GetImpl();
3807 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3808 if ( !anOrder.size() ) {
3810 // collect submeshes detecting concurrent algorithms and hypothesises
3811 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3813 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3814 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3815 ::SMESH_subMesh* sm = (*i_sm).second;
3817 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3819 // list of assigned hypothesises
3820 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3821 // Find out dimensions where the submesh can be concurrent.
3822 // We define the dimensions by algo of each of hypotheses in hypList
3823 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3824 for( ; hypIt != hypList.end(); hypIt++ ) {
3825 SMESH_Algo* anAlgo = 0;
3826 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3827 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3828 // hyp it-self is algo
3829 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3831 // try to find algorithm with help of subshapes
3832 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3833 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3834 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3837 continue; // no assigned algorithm to current submesh
3839 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3840 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3842 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3843 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3844 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3846 } // end iterations on submesh
3848 // iterate on created dimension-hypotheses and check for concurrents
3849 for ( int i = 0; i < 4; i++ ) {
3850 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3851 // check for concurrents in own and other dimensions (step-by-step)
3852 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3853 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3854 const SMESH_DimHyp* dimHyp = *dhIt;
3855 TListOfInt listOfConcurr;
3856 // looking for concurrents and collect into own list
3857 for ( int j = i; j < 4; j++ )
3858 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3859 // check if any concurrents found
3860 if ( listOfConcurr.size() > 0 ) {
3861 // add own submesh to list of concurrent
3862 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3863 anOrder.push_back( listOfConcurr );
3868 removeDimHyps(dimHypListArr);
3870 // now, minimise the number of concurrent groups
3871 // Here we assume that lists of submhes can has same submesh
3872 // in case of multi-dimension algorithms, as result
3873 // list with common submesh have to be union into one list
3875 TListOfListOfInt::iterator listIt = anOrder.begin();
3876 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3877 unionLists( *listIt, anOrder, listIndx + 1 );
3879 // convert submesh ids into interface instances
3880 // and dump command into python
3881 convertMeshOrder( anOrder, aResult, true );
3883 return aResult._retn();
3886 //=============================================================================
3888 * \brief find common submeshes with given submesh
3889 * \param theSubMeshList list of already collected submesh to check
3890 * \param theSubMesh given submesh to intersect with other
3891 * \param theCommonSubMeshes collected common submeshes
3893 //=============================================================================
3895 static void findCommonSubMesh
3896 (list<const SMESH_subMesh*>& theSubMeshList,
3897 const SMESH_subMesh* theSubMesh,
3898 set<const SMESH_subMesh*>& theCommon )
3902 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
3903 for ( ; it != theSubMeshList.end(); it++ )
3904 theSubMesh->FindIntersection( *it, theCommon );
3905 theSubMeshList.push_back( theSubMesh );
3906 //theCommon.insert( theSubMesh );
3909 //=============================================================================
3911 * \brief Set submesh object order
3912 * \param theSubMeshArray submesh array order
3914 //=============================================================================
3916 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
3919 ::SMESH_Mesh& mesh = GetImpl();
3921 TPythonDump aPythonDump; // prevent dump of called methods
3922 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
3924 TListOfListOfInt subMeshOrder;
3925 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
3927 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
3928 TListOfInt subMeshIds;
3929 aPythonDump << "[ ";
3930 // Collect subMeshes which should be clear
3931 // do it list-by-list, because modification of submesh order
3932 // take effect between concurrent submeshes only
3933 set<const SMESH_subMesh*> subMeshToClear;
3934 list<const SMESH_subMesh*> subMeshList;
3935 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
3937 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
3939 aPythonDump << ", ";
3940 aPythonDump << subMesh;
3941 subMeshIds.push_back( subMesh->GetId() );
3942 // detect common parts of submeshes
3943 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
3944 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
3946 aPythonDump << " ]";
3947 subMeshOrder.push_back( subMeshIds );
3949 // clear collected submeshes
3950 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
3951 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
3952 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
3954 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
3955 // ClearSubMesh( *clrIt );
3958 aPythonDump << " ])";
3960 mesh.SetMeshOrder( subMeshOrder );
3966 //=============================================================================
3968 * \brief Convert submesh ids into submesh interfaces
3970 //=============================================================================
3972 void SMESH_Mesh_i::convertMeshOrder
3973 (const TListOfListOfInt& theIdsOrder,
3974 SMESH::submesh_array_array& theResOrder,
3975 const bool theIsDump)
3977 int nbSet = theIdsOrder.size();
3978 TPythonDump aPythonDump; // prevent dump of called methods
3980 aPythonDump << "[ ";
3981 theResOrder.length(nbSet);
3982 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
3984 for( ; it != theIdsOrder.end(); it++ ) {
3985 // translate submesh identificators into submesh objects
3986 // takeing into account real number of concurrent lists
3987 const TListOfInt& aSubOrder = (*it);
3988 if (!aSubOrder.size())
3991 aPythonDump << "[ ";
3992 // convert shape indeces into interfaces
3993 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
3994 aResSubSet->length(aSubOrder.size());
3995 TListOfInt::const_iterator subIt = aSubOrder.begin();
3996 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
3997 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
3999 SMESH::SMESH_subMesh_var subMesh =
4000 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4003 aPythonDump << ", ";
4004 aPythonDump << subMesh;
4006 aResSubSet[ j++ ] = subMesh;
4009 aPythonDump << " ]";
4010 theResOrder[ listIndx++ ] = aResSubSet;
4012 // correct number of lists
4013 theResOrder.length( listIndx );
4016 // finilise python dump
4017 aPythonDump << " ]";
4018 aPythonDump << " = " << _this() << ".GetMeshOrder()";