1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
23 // File : SMESH_Mesh_i.cxx
24 // Author : Paul RASCLE, EDF
27 #include "SMESH_Mesh_i.hxx"
29 #include "SMESH_Filter_i.hxx"
30 #include "SMESH_Gen_i.hxx"
31 #include "SMESH_Group_i.hxx"
32 #include "SMESH_MEDMesh_i.hxx"
33 #include "SMESH_MeshEditor_i.hxx"
34 #include "SMESH_PythonDump.hxx"
35 #include "SMESH_subMesh_i.hxx"
37 #include "DriverMED_R_SMESHDS_Mesh.h"
38 #include "DriverMED_W_SMESHDS_Mesh.h"
39 #include "SMDS_VolumeTool.hxx"
40 #include "SMDS_ElemIterator.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_GroupOnGeom.hxx"
44 #include "SMESH_Group.hxx"
45 #include "SMESH_MeshEditor.hxx"
46 #include "SMESH_MesherHelper.hxx"
47 #include "SMDS_EdgePosition.hxx"
48 #include "SMDS_FacePosition.hxx"
51 #include "SALOME_NamingService.hxx"
52 #include "Utils_CorbaException.hxx"
53 #include "Utils_ExceptHandlers.hxx"
54 #include "Utils_SINGLETON.hxx"
55 #include "utilities.h"
56 #include "GEOMImpl_Types.hxx"
59 #include <BRep_Builder.hxx>
60 #include <OSD_Directory.hxx>
61 #include <OSD_File.hxx>
62 #include <OSD_Path.hxx>
63 #include <OSD_Protection.hxx>
64 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
65 #include <TColStd_MapOfInteger.hxx>
66 #include <TColStd_SequenceOfInteger.hxx>
67 #include <TCollection_AsciiString.hxx>
69 #include <TopExp_Explorer.hxx>
70 #include <TopoDS_Compound.hxx>
71 #include <TopTools_MapOfShape.hxx>
72 #include <TopTools_MapIteratorOfMapOfShape.hxx>
82 static int MYDEBUG = 0;
84 static int MYDEBUG = 0;
88 using SMESH::TPythonDump;
90 int SMESH_Mesh_i::myIdGenerator = 0;
92 //To disable automatic genericobj management, the following line should be commented.
93 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
94 #define WITHGENERICOBJ
96 //=============================================================================
100 //=============================================================================
102 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
104 CORBA::Long studyId )
105 : SALOME::GenericObj_i( thePOA )
107 MESSAGE("SMESH_Mesh_i");
110 _id = myIdGenerator++;
114 //=============================================================================
118 //=============================================================================
120 SMESH_Mesh_i::~SMESH_Mesh_i()
122 INFOS("~SMESH_Mesh_i");
125 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
126 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
127 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
129 // this method is called from destructor of group (PAL6331)
130 //_impl->RemoveGroup( aGroup->GetLocalID() );
131 #ifdef WITHGENERICOBJ
138 #ifdef WITHGENERICOBJ
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
142 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
147 _mapSubMeshIor.clear();
149 // destroy hypotheses
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
163 //=============================================================================
167 * Associates <this> mesh with <theShape> and puts a reference
168 * to <theShape> into the current study;
169 * the previous shape is substituted by the new one.
171 //=============================================================================
173 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
174 throw (SALOME::SALOME_Exception)
176 Unexpect aCatch(SALOME_SalomeException);
178 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
180 catch(SALOME_Exception & S_ex) {
181 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
183 // to track changes of GEOM groups
184 addGeomGroupData( theShapeObject, _this() );
187 //================================================================================
189 * \brief return true if mesh has a shape to build a shape on
191 //================================================================================
193 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
194 throw (SALOME::SALOME_Exception)
196 Unexpect aCatch(SALOME_SalomeException);
199 res = _impl->HasShapeToMesh();
201 catch(SALOME_Exception & S_ex) {
202 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
207 //=======================================================================
208 //function : GetShapeToMesh
210 //=======================================================================
212 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
213 throw (SALOME::SALOME_Exception)
215 Unexpect aCatch(SALOME_SalomeException);
216 GEOM::GEOM_Object_var aShapeObj;
218 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
220 aShapeObj = _gen_i->ShapeToGeomObject( S );
222 catch(SALOME_Exception & S_ex) {
223 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
225 return aShapeObj._retn();
228 //================================================================================
230 * \brief Remove all nodes and elements
232 //================================================================================
234 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
236 Unexpect aCatch(SALOME_SalomeException);
239 CheckGeomGroupModif(); // issue 20145
241 catch(SALOME_Exception & S_ex) {
242 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
244 TPythonDump() << _this() << ".Clear()";
247 //================================================================================
249 * \brief Remove all nodes and elements for indicated shape
251 //================================================================================
253 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
254 throw (SALOME::SALOME_Exception)
256 Unexpect aCatch(SALOME_SalomeException);
258 _impl->ClearSubMesh( ShapeID );
260 catch(SALOME_Exception & S_ex) {
261 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
265 //=============================================================================
269 //=============================================================================
271 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
273 SMESH::DriverMED_ReadStatus res;
276 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
277 res = SMESH::DRS_OK; break;
278 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
279 res = SMESH::DRS_EMPTY; break;
280 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
281 res = SMESH::DRS_WARN_RENUMBER; break;
282 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
283 res = SMESH::DRS_WARN_SKIP_ELEM; break;
284 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
286 res = SMESH::DRS_FAIL; break;
291 //=============================================================================
295 * Imports mesh data from MED file
297 //=============================================================================
299 SMESH::DriverMED_ReadStatus
300 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
301 throw ( SALOME::SALOME_Exception )
303 Unexpect aCatch(SALOME_SalomeException);
306 status = _impl->MEDToMesh( theFileName, theMeshName );
308 catch( SALOME_Exception& S_ex ) {
309 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
312 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
315 CreateGroupServants();
317 int major, minor, release;
318 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
319 major = minor = release = -1;
320 myFileInfo = new SALOME_MED::MedFileInfo();
321 myFileInfo->fileName = theFileName;
322 myFileInfo->fileSize = 0;
325 if ( ::_stati64( theFileName, &d ) != -1 )
328 if ( ::stat64( theFileName, &d ) != -1 )
330 myFileInfo->fileSize = d.st_size;
331 myFileInfo->major = major;
332 myFileInfo->minor = minor;
333 myFileInfo->release = release;
335 return ConvertDriverMEDReadStatus(status);
338 //================================================================================
340 * \brief Return string representation of a MED file version comprising nbDigits
342 //================================================================================
344 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
346 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
348 return CORBA::string_dup( ver.c_str() );
351 //=============================================================================
355 * Imports mesh data from MED file
357 //=============================================================================
359 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
360 throw ( SALOME::SALOME_Exception )
362 // Read mesh with name = <theMeshName> into SMESH_Mesh
363 _impl->UNVToMesh( theFileName );
365 CreateGroupServants();
370 //=============================================================================
374 * Imports mesh data from STL file
376 //=============================================================================
377 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
378 throw ( SALOME::SALOME_Exception )
380 // Read mesh with name = <theMeshName> into SMESH_Mesh
381 _impl->STLToMesh( theFileName );
386 //=============================================================================
390 * Imports mesh data from MED file
392 //=============================================================================
394 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
396 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
397 // int status = _impl->MEDToMesh( theFileName, theMeshName );
398 // CreateGroupServants();
403 //=============================================================================
407 //=============================================================================
409 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
411 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
412 (SMESH_Hypothesis::Hypothesis_Status theStatus)
415 RETURNCASE( HYP_OK );
416 RETURNCASE( HYP_MISSING );
417 RETURNCASE( HYP_CONCURENT );
418 RETURNCASE( HYP_BAD_PARAMETER );
419 RETURNCASE( HYP_HIDDEN_ALGO );
420 RETURNCASE( HYP_HIDING_ALGO );
421 RETURNCASE( HYP_UNKNOWN_FATAL );
422 RETURNCASE( HYP_INCOMPATIBLE );
423 RETURNCASE( HYP_NOTCONFORM );
424 RETURNCASE( HYP_ALREADY_EXIST );
425 RETURNCASE( HYP_BAD_DIM );
426 RETURNCASE( HYP_BAD_SUBSHAPE );
427 RETURNCASE( HYP_BAD_GEOMETRY );
428 RETURNCASE( HYP_NEED_SHAPE );
431 return SMESH::HYP_UNKNOWN_FATAL;
434 //=============================================================================
438 * calls internal addHypothesis() and then adds a reference to <anHyp> under
439 * the SObject actually having a reference to <aSubShape>.
440 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
442 //=============================================================================
444 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
445 SMESH::SMESH_Hypothesis_ptr anHyp)
446 throw(SALOME::SALOME_Exception)
448 Unexpect aCatch(SALOME_SalomeException);
449 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
451 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
452 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
453 aSubShapeObject, anHyp );
455 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
457 // Update Python script
458 if(_impl->HasShapeToMesh()) {
459 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
460 << aSubShapeObject << ", " << anHyp << " )";
463 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
466 return ConvertHypothesisStatus(status);
469 //=============================================================================
473 //=============================================================================
475 SMESH_Hypothesis::Hypothesis_Status
476 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
477 SMESH::SMESH_Hypothesis_ptr anHyp)
479 if(MYDEBUG) MESSAGE("addHypothesis");
481 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
482 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
485 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
486 if (CORBA::is_nil(myHyp))
487 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
490 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
493 TopoDS_Shape myLocSubShape;
494 //use PseudoShape in case if mesh has no shape
496 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
498 myLocSubShape = _impl->GetShapeToMesh();
500 int hypId = myHyp->GetId();
501 status = _impl->AddHypothesis(myLocSubShape, hypId);
502 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
503 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
504 #ifdef WITHGENERICOBJ
505 _mapHypo[hypId]->Register();
507 // assure there is a corresponding submesh
508 if ( !_impl->IsMainShape( myLocSubShape )) {
509 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
510 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
511 createSubMesh( aSubShapeObject );
515 catch(SALOME_Exception & S_ex)
517 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
522 //=============================================================================
526 //=============================================================================
528 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
529 SMESH::SMESH_Hypothesis_ptr anHyp)
530 throw(SALOME::SALOME_Exception)
532 Unexpect aCatch(SALOME_SalomeException);
533 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
535 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
536 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
537 aSubShapeObject, anHyp );
539 // Update Python script
540 // Update Python script
541 if(_impl->HasShapeToMesh()) {
542 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
543 << aSubShapeObject << ", " << anHyp << " )";
546 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
550 return ConvertHypothesisStatus(status);
553 //=============================================================================
557 //=============================================================================
559 SMESH_Hypothesis::Hypothesis_Status
560 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
561 SMESH::SMESH_Hypothesis_ptr anHyp)
563 if(MYDEBUG) MESSAGE("removeHypothesis()");
564 // **** proposer liste de subShape (selection multiple)
566 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
567 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
569 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
570 if (CORBA::is_nil(myHyp))
571 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
573 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
576 TopoDS_Shape myLocSubShape;
577 //use PseudoShape in case if mesh has no shape
579 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
581 myLocSubShape = _impl->GetShapeToMesh();
583 int hypId = myHyp->GetId();
584 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
585 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
586 // _mapHypo.erase( hypId );
588 catch(SALOME_Exception & S_ex)
590 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
595 //=============================================================================
599 //=============================================================================
601 SMESH::ListOfHypothesis *
602 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
603 throw(SALOME::SALOME_Exception)
605 Unexpect aCatch(SALOME_SalomeException);
606 if (MYDEBUG) MESSAGE("GetHypothesisList");
607 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
608 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
610 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
613 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
614 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
615 myLocSubShape = _impl->GetShapeToMesh();
616 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
617 int i = 0, n = aLocalList.size();
620 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
621 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
622 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
623 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
628 catch(SALOME_Exception & S_ex) {
629 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
632 return aList._retn();
635 //=============================================================================
639 //=============================================================================
640 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
641 const char* theName )
642 throw(SALOME::SALOME_Exception)
644 Unexpect aCatch(SALOME_SalomeException);
645 MESSAGE("SMESH_Mesh_i::GetSubMesh");
646 if (CORBA::is_nil(aSubShapeObject))
647 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
650 SMESH::SMESH_subMesh_var subMesh;
651 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
653 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
655 //Get or Create the SMESH_subMesh object implementation
657 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
658 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
659 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
661 subMesh = getSubMesh( subMeshId );
663 // create a new subMesh object servant if there is none for the shape
664 if ( subMesh->_is_nil() )
665 subMesh = createSubMesh( aSubShapeObject );
666 if ( _gen_i->CanPublishInStudy( subMesh )) {
667 SALOMEDS::SObject_var aSO =
668 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
669 subMesh, aSubShapeObject, theName );
670 if ( !aSO->_is_nil()) {
671 // Update Python script
672 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
673 << aSubShapeObject << ", '" << theName << "' )";
677 catch(SALOME_Exception & S_ex) {
678 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
680 return subMesh._retn();
683 //=============================================================================
687 //=============================================================================
689 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
690 throw (SALOME::SALOME_Exception)
692 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
693 if ( theSubMesh->_is_nil() )
696 GEOM::GEOM_Object_var aSubShapeObject;
697 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
698 if ( !aStudy->_is_nil() ) {
699 // Remove submesh's SObject
700 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
701 if ( !anSO->_is_nil() ) {
702 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
703 SALOMEDS::SObject_var anObj, aRef;
704 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
705 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
707 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
708 // aSubShapeObject = theSubMesh->GetSubShape();
710 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
712 // Update Python script
713 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
717 removeSubMesh( theSubMesh, aSubShapeObject.in() );
720 //=============================================================================
724 //=============================================================================
725 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
726 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
728 switch (theElemType) {
733 CASE2STRING( VOLUME );
739 //=============================================================================
743 //=============================================================================
745 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
746 const char* theName )
747 throw(SALOME::SALOME_Exception)
749 Unexpect aCatch(SALOME_SalomeException);
750 SMESH::SMESH_Group_var aNewGroup =
751 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
753 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
754 SALOMEDS::SObject_var aSO =
755 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
756 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
757 if ( !aSO->_is_nil()) {
758 // Update Python script
759 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
760 << ElementTypeString(theElemType) << ", '" << theName << "' )";
763 return aNewGroup._retn();
767 //=============================================================================
771 //=============================================================================
772 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
774 GEOM::GEOM_Object_ptr theGeomObj)
775 throw(SALOME::SALOME_Exception)
777 Unexpect aCatch(SALOME_SalomeException);
778 SMESH::SMESH_GroupOnGeom_var aNewGroup;
780 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
781 if ( !aShape.IsNull() )
783 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
784 ( createGroup( theElemType, theName, aShape ));
786 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
787 SALOMEDS::SObject_var aSO =
788 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
789 aNewGroup, theGeomObj, theName);
790 if ( !aSO->_is_nil()) {
791 // Update Python script
792 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
793 << ElementTypeString(theElemType) << ", '" << theName << "', "
794 << theGeomObj << " )";
799 return aNewGroup._retn();
802 //=============================================================================
806 //=============================================================================
808 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
809 throw (SALOME::SALOME_Exception)
811 if ( theGroup->_is_nil() )
814 SMESH_GroupBase_i* aGroup =
815 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
819 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
820 if ( !aStudy->_is_nil() ) {
821 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
823 if ( !aGroupSO->_is_nil() ) {
824 // Update Python script
825 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
827 // Remove group's SObject
828 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
832 // Remove the group from SMESH data structures
833 removeGroup( aGroup->GetLocalID() );
836 //=============================================================================
837 /*! RemoveGroupWithContents
838 * Remove group with its contents
840 //=============================================================================
841 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
842 throw (SALOME::SALOME_Exception)
844 if ( theGroup->_is_nil() )
847 SMESH_GroupBase_i* aGroup =
848 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
852 SMESH::long_array_var anIds = aGroup->GetListOfID();
853 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
855 // Update Python script
856 TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
859 if ( aGroup->GetType() == SMESH::NODE )
860 aMeshEditor->RemoveNodes( anIds );
862 aMeshEditor->RemoveElements( anIds );
865 RemoveGroup( theGroup );
867 // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
868 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
869 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
873 //================================================================================
875 * \brief Get the list of groups existing in the mesh
876 * \retval SMESH::ListOfGroups * - list of groups
878 //================================================================================
880 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
882 Unexpect aCatch(SALOME_SalomeException);
883 if (MYDEBUG) MESSAGE("GetGroups");
885 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
888 TPythonDump aPythonDump;
889 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
893 aList->length( _mapGroups.size() );
895 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
896 for ( ; it != _mapGroups.end(); it++ ) {
897 if ( CORBA::is_nil( it->second )) continue;
898 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
900 if (i > 1) aPythonDump << ", ";
901 aPythonDump << it->second;
905 catch(SALOME_Exception & S_ex) {
906 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
909 // Update Python script
910 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
911 aPythonDump << " ] = " << _this() << ".GetGroups()";
913 return aList._retn();
915 //=============================================================================
917 * Get number of groups existing in the mesh
919 //=============================================================================
921 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
923 Unexpect aCatch(SALOME_SalomeException);
924 return _mapGroups.size();
927 //=============================================================================
929 * New group is created. All mesh elements that are
930 * present in initial groups are added to the new one
932 //=============================================================================
933 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
934 SMESH::SMESH_GroupBase_ptr theGroup2,
935 const char* theName )
936 throw (SALOME::SALOME_Exception)
940 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
941 theGroup1->GetType() != theGroup2->GetType() )
942 return SMESH::SMESH_Group::_nil();
945 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
946 if ( aResGrp->_is_nil() )
947 return SMESH::SMESH_Group::_nil();
949 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
950 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
952 TColStd_MapOfInteger aResMap;
954 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
955 aResMap.Add( anIds1[ i1 ] );
957 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
958 aResMap.Add( anIds2[ i2 ] );
960 SMESH::long_array_var aResIds = new SMESH::long_array;
961 aResIds->length( aResMap.Extent() );
964 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
965 for( ; anIter.More(); anIter.Next() )
966 aResIds[ resI++ ] = anIter.Key();
968 aResGrp->Add( aResIds );
970 // Clear python lines, created by CreateGroup() and Add()
971 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
972 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
973 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
975 // Update Python script
976 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
977 << theGroup1 << ", " << theGroup2 << ", '"
980 return aResGrp._retn();
984 return SMESH::SMESH_Group::_nil();
988 //=============================================================================
990 \brief Union list of groups. New group is created. All mesh elements that are
991 present in initial groups are added to the new one.
992 \param theGroups list of groups
993 \param theName name of group to be created
994 \return pointer on the group
996 //=============================================================================
997 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
998 const char* theName )
999 throw (SALOME::SALOME_Exception)
1002 return SMESH::SMESH_Group::_nil();
1006 NCollection_Map< int > anIds;
1007 SMESH::ElementType aType = SMESH::ALL;
1008 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1010 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1011 if ( CORBA::is_nil( aGrp ) )
1015 SMESH::ElementType aCurrType = aGrp->GetType();
1016 if ( aType == SMESH::ALL )
1020 if ( aType != aCurrType )
1021 return SMESH::SMESH_Group::_nil();
1025 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1026 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1028 int aCurrId = aCurrIds[ i ];
1029 anIds.Add( aCurrId );
1034 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1035 if ( aResGrp->_is_nil() )
1036 return SMESH::SMESH_Group::_nil();
1038 // Create array of identifiers
1039 SMESH::long_array_var aResIds = new SMESH::long_array;
1040 aResIds->length( anIds.Extent() );
1042 NCollection_Map< int >::Iterator anIter( anIds );
1043 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1045 aResIds[ i ] = anIter.Value();
1047 aResGrp->Add( aResIds );
1049 // Clear python lines, created by CreateGroup() and Add()
1050 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1051 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1052 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1054 // Update Python script
1056 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1057 << &theGroups << ", '" << theName << "' )";
1059 return aResGrp._retn();
1063 return SMESH::SMESH_Group::_nil();
1067 //=============================================================================
1069 * New group is created. All mesh elements that are
1070 * present in both initial groups are added to the new one.
1072 //=============================================================================
1073 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1074 SMESH::SMESH_GroupBase_ptr theGroup2,
1075 const char* theName )
1076 throw (SALOME::SALOME_Exception)
1078 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1079 theGroup1->GetType() != theGroup2->GetType() )
1080 return SMESH::SMESH_Group::_nil();
1082 // Create Intersection
1083 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1084 if ( aResGrp->_is_nil() )
1087 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1088 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1090 TColStd_MapOfInteger aMap1;
1092 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1093 aMap1.Add( anIds1[ i1 ] );
1095 TColStd_SequenceOfInteger aSeq;
1097 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1098 if ( aMap1.Contains( anIds2[ i2 ] ) )
1099 aSeq.Append( anIds2[ i2 ] );
1101 SMESH::long_array_var aResIds = new SMESH::long_array;
1102 aResIds->length( aSeq.Length() );
1104 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1105 aResIds[ resI ] = aSeq( resI + 1 );
1107 aResGrp->Add( aResIds );
1109 // Clear python lines, created by CreateGroup() and Add()
1110 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1111 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1112 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1114 // Update Python script
1115 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1116 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1118 return aResGrp._retn();
1121 //=============================================================================
1123 \brief Intersect list of groups. New group is created. All mesh elements that
1124 are present in all initial groups simultaneously are added to the new one.
1125 \param theGroups list of groups
1126 \param theName name of group to be created
1127 \return pointer on the group
1129 //=============================================================================
1130 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1131 const SMESH::ListOfGroups& theGroups, const char* theName )
1132 throw (SALOME::SALOME_Exception)
1135 return SMESH::SMESH_Group::_nil();
1139 NCollection_DataMap< int, int > anIdToCount;
1140 SMESH::ElementType aType = SMESH::ALL;
1141 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1143 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1144 if ( CORBA::is_nil( aGrp ) )
1148 SMESH::ElementType aCurrType = aGrp->GetType();
1149 if ( aType == SMESH::ALL )
1153 if ( aType != aCurrType )
1154 return SMESH::SMESH_Group::_nil();
1157 // calculates number of occurance ids in groups
1158 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1159 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1161 int aCurrId = aCurrIds[ i ];
1162 if ( !anIdToCount.IsBound( aCurrId ) )
1163 anIdToCount.Bind( aCurrId, 1 );
1165 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1169 // create map of ids
1170 int nbGrp = theGroups.length();
1171 NCollection_Map< int > anIds;
1172 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1173 for ( ; anIter.More(); anIter.Next() )
1175 int aCurrId = anIter.Key();
1176 int aCurrNb = anIter.Value();
1177 if ( aCurrNb == nbGrp )
1178 anIds.Add( aCurrId );
1182 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1183 if ( aResGrp->_is_nil() )
1184 return SMESH::SMESH_Group::_nil();
1186 // Create array of identifiers
1187 SMESH::long_array_var aResIds = new SMESH::long_array;
1188 aResIds->length( anIds.Extent() );
1190 NCollection_Map< int >::Iterator aListIter( anIds );
1191 for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1193 aResIds[ i ] = aListIter.Value();
1195 aResGrp->Add( aResIds );
1197 // Clear python lines, created by CreateGroup() and Add()
1198 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1199 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1200 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1202 // Update Python script
1204 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1205 << &theGroups << ", '" << theName << "' )";
1207 return aResGrp._retn();
1211 return SMESH::SMESH_Group::_nil();
1215 //=============================================================================
1217 * New group is created. All mesh elements that are present in
1218 * main group but do not present in tool group are added to the new one
1220 //=============================================================================
1221 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1222 SMESH::SMESH_GroupBase_ptr theGroup2,
1223 const char* theName )
1224 throw (SALOME::SALOME_Exception)
1226 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1227 theGroup1->GetType() != theGroup2->GetType() )
1228 return SMESH::SMESH_Group::_nil();
1231 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1232 if ( aResGrp->_is_nil() )
1235 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1236 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1238 TColStd_MapOfInteger aMap2;
1240 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1241 aMap2.Add( anIds2[ i2 ] );
1243 TColStd_SequenceOfInteger aSeq;
1244 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1245 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1246 aSeq.Append( anIds1[ i1 ] );
1248 SMESH::long_array_var aResIds = new SMESH::long_array;
1249 aResIds->length( aSeq.Length() );
1251 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1252 aResIds[ resI ] = aSeq( resI + 1 );
1254 aResGrp->Add( aResIds );
1256 // Clear python lines, created by CreateGroup() and Add()
1257 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1258 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1259 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1261 // Update Python script
1262 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1263 << theGroup1 << ", " << theGroup2 << ", '"
1264 << theName << "' )";
1266 return aResGrp._retn();
1269 //=============================================================================
1271 \brief Cut lists of groups. New group is created. All mesh elements that are
1272 present in main groups but do not present in tool groups are added to the new one
1273 \param theMainGroups list of main groups
1274 \param theToolGroups list of tool groups
1275 \param theName name of group to be created
1276 \return pointer on the group
1278 //=============================================================================
1279 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1280 const SMESH::ListOfGroups& theMainGroups,
1281 const SMESH::ListOfGroups& theToolGroups,
1282 const char* theName )
1283 throw (SALOME::SALOME_Exception)
1286 return SMESH::SMESH_Group::_nil();
1290 NCollection_Map< int > aToolIds;
1291 SMESH::ElementType aType = SMESH::ALL;
1293 // iterate through tool groups
1294 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1296 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1297 if ( CORBA::is_nil( aGrp ) )
1301 SMESH::ElementType aCurrType = aGrp->GetType();
1302 if ( aType == SMESH::ALL )
1306 if ( aType != aCurrType )
1307 return SMESH::SMESH_Group::_nil();
1311 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1312 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1314 int aCurrId = aCurrIds[ i ];
1315 aToolIds.Add( aCurrId );
1319 NCollection_Map< int > anIds; // result
1321 // Iterate through main group
1322 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1324 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1325 if ( CORBA::is_nil( aGrp ) )
1329 SMESH::ElementType aCurrType = aGrp->GetType();
1330 if ( aType == SMESH::ALL )
1334 if ( aType != aCurrType )
1335 return SMESH::SMESH_Group::_nil();
1339 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1340 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1342 int aCurrId = aCurrIds[ i ];
1343 if ( !aToolIds.Contains( aCurrId ) )
1344 anIds.Add( aCurrId );
1349 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1350 if ( aResGrp->_is_nil() )
1351 return SMESH::SMESH_Group::_nil();
1353 // Create array of identifiers
1354 SMESH::long_array_var aResIds = new SMESH::long_array;
1355 aResIds->length( anIds.Extent() );
1357 NCollection_Map< int >::Iterator anIter( anIds );
1358 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1360 aResIds[ i ] = anIter.Value();
1362 aResGrp->Add( aResIds );
1364 // Clear python lines, created by CreateGroup() and Add()
1365 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1366 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1367 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1369 // Update Python script
1371 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1372 << &theMainGroups << ", " << &theToolGroups << ", '"
1373 << theName << "' )";
1375 return aResGrp._retn();
1379 return SMESH::SMESH_Group::_nil();
1383 //=============================================================================
1385 \brief Create groups of entities from existing groups of superior dimensions
1387 1) extract all nodes from each group,
1388 2) combine all elements of specified dimension laying on these nodes.
1389 \param theGroups list of source groups
1390 \param theElemType dimension of elements
1391 \param theName name of new group
1392 \return pointer on new group
1394 //=============================================================================
1395 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1396 const SMESH::ListOfGroups& theGroups,
1397 SMESH::ElementType theElemType,
1398 const char* theName )
1399 throw (SALOME::SALOME_Exception)
1401 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1403 if ( !theName || !aMeshDS )
1404 return SMESH::SMESH_Group::_nil();
1406 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1410 // Create map of nodes from all groups
1412 NCollection_Map< int > aNodeMap;
1414 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1416 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1417 if ( CORBA::is_nil( aGrp ) )
1420 SMESH::ElementType aType = aGrp->GetType();
1421 if ( aType == SMESH::ALL )
1423 else if ( aType == SMESH::NODE )
1425 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1426 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1428 int aCurrId = aCurrIds[ i ];
1429 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1431 aNodeMap.Add( aNode->GetID() );
1436 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1437 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1439 int aCurrId = aCurrIds[ i ];
1440 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1443 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1444 while( aNodeIter->more() )
1446 const SMDS_MeshNode* aNode =
1447 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1449 aNodeMap.Add( aNode->GetID() );
1455 // Get result identifiers
1457 NCollection_Map< int > aResultIds;
1458 if ( theElemType == SMESH::NODE )
1460 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1461 for ( ; aNodeIter.More(); aNodeIter.Next() )
1462 aResultIds.Add( aNodeIter.Value() );
1466 // Create list of elements of given dimension constructed on the nodes
1467 NCollection_Map< int > anElemList;
1468 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1469 for ( ; aNodeIter.More(); aNodeIter.Next() )
1471 const SMDS_MeshElement* aNode =
1472 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1476 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1477 while( anElemIter->more() )
1479 const SMDS_MeshElement* anElem =
1480 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1481 if ( anElem && anElem->GetType() == anElemType )
1482 anElemList.Add( anElem->GetID() );
1486 // check whether all nodes of elements are present in nodes map
1487 NCollection_Map< int >::Iterator anIter( anElemList );
1488 for ( ; anIter.More(); anIter.Next() )
1490 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1495 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1496 while( aNodeIter->more() )
1498 const SMDS_MeshNode* aNode =
1499 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1500 if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1507 aResultIds.Add( anElem->GetID() );
1513 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1514 if ( aResGrp->_is_nil() )
1515 return SMESH::SMESH_Group::_nil();
1517 // Create array of identifiers
1518 SMESH::long_array_var aResIds = new SMESH::long_array;
1519 aResIds->length( aResultIds.Extent() );
1521 NCollection_Map< int >::Iterator aResIter( aResultIds );
1522 for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1523 aResIds[ i ] = aResIter.Value();
1524 aResGrp->Add( aResIds );
1526 // Remove strings corresponding to group creation
1527 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1528 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1529 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1531 // Update Python script
1533 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1534 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1536 return aResGrp._retn();
1540 return SMESH::SMESH_Group::_nil();
1544 //================================================================================
1546 * \brief Remember GEOM group data
1548 //================================================================================
1550 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1551 CORBA::Object_ptr theSmeshObj)
1553 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1556 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1557 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1558 if ( groupSO->_is_nil() )
1561 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1562 GEOM::GEOM_IGroupOperations_var groupOp =
1563 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1564 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1567 _geomGroupData.push_back( TGeomGroupData() );
1568 TGeomGroupData & groupData = _geomGroupData.back();
1570 CORBA::String_var entry = groupSO->GetID();
1571 groupData._groupEntry = entry.in();
1573 for ( int i = 0; i < ids->length(); ++i )
1574 groupData._indices.insert( ids[i] );
1576 groupData._smeshObject = theSmeshObj;
1579 //================================================================================
1581 * Remove GEOM group data relating to removed smesh object
1583 //================================================================================
1585 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1587 list<TGeomGroupData>::iterator
1588 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1589 for ( ; data != dataEnd; ++data ) {
1590 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1591 _geomGroupData.erase( data );
1597 //================================================================================
1599 * \brief Return new group contents if it has been changed and update group data
1601 //================================================================================
1603 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1605 TopoDS_Shape newShape;
1608 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1609 if ( study->_is_nil() ) return newShape; // means "not changed"
1610 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1611 if ( !groupSO->_is_nil() )
1613 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1614 if ( CORBA::is_nil( groupObj )) return newShape;
1615 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1617 // get indices of group items
1618 set<int> curIndices;
1619 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1620 GEOM::GEOM_IGroupOperations_var groupOp =
1621 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1622 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1623 for ( int i = 0; i < ids->length(); ++i )
1624 curIndices.insert( ids[i] );
1626 if ( groupData._indices == curIndices )
1627 return newShape; // group not changed
1630 groupData._indices = curIndices;
1632 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1633 if ( !geomClient ) return newShape;
1634 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1635 geomClient->RemoveShapeFromBuffer( groupIOR );
1636 newShape = _gen_i->GeomObjectToShape( geomGroup );
1639 if ( newShape.IsNull() ) {
1640 // geom group becomes empty - return empty compound
1641 TopoDS_Compound compound;
1642 BRep_Builder().MakeCompound(compound);
1643 newShape = compound;
1649 //=============================================================================
1651 * \brief Storage of shape and index used in CheckGeomGroupModif()
1653 //=============================================================================
1654 struct TIndexedShape {
1656 TopoDS_Shape _shape;
1657 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1660 //=============================================================================
1662 * \brief Update objects depending on changed geom groups
1664 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1665 * issue 0020210: Update of a smesh group after modification of the associated geom group
1667 //=============================================================================
1669 void SMESH_Mesh_i::CheckGeomGroupModif()
1671 if ( !_impl->HasShapeToMesh() ) return;
1673 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1674 if ( study->_is_nil() ) return;
1676 CORBA::Long nbEntities = NbNodes() + NbElements();
1678 // Check if group contents changed
1680 typedef map< string, TopoDS_Shape > TEntry2Geom;
1681 TEntry2Geom newGroupContents;
1683 list<TGeomGroupData>::iterator
1684 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1685 for ( ; data != dataEnd; ++data )
1687 pair< TEntry2Geom::iterator, bool > it_new =
1688 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1689 bool processedGroup = !it_new.second;
1690 TopoDS_Shape& newShape = it_new.first->second;
1691 if ( !processedGroup )
1692 newShape = newGroupShape( *data );
1693 if ( newShape.IsNull() )
1694 continue; // no changes
1696 if ( processedGroup ) { // update group indices
1697 list<TGeomGroupData>::iterator data2 = data;
1698 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1699 data->_indices = data2->_indices;
1702 // Update SMESH objects according to new GEOM group contents
1704 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1705 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1707 int oldID = submesh->GetId();
1708 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1710 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1712 // update hypotheses
1713 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1714 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1715 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1717 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1718 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1720 // care of submeshes
1721 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1722 int newID = newSubmesh->GetId();
1723 if ( newID != oldID ) {
1724 _mapSubMesh [ newID ] = newSubmesh;
1725 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1726 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1727 _mapSubMesh. erase(oldID);
1728 _mapSubMesh_i. erase(oldID);
1729 _mapSubMeshIor.erase(oldID);
1730 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1735 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1736 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1737 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1739 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1741 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1742 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1743 ds->SetShape( newShape );
1748 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1749 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1751 // Remove groups and submeshes basing on removed sub-shapes
1753 TopTools_MapOfShape newShapeMap;
1754 TopoDS_Iterator shapeIt( newShape );
1755 for ( ; shapeIt.More(); shapeIt.Next() )
1756 newShapeMap.Add( shapeIt.Value() );
1758 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1759 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1761 if ( newShapeMap.Contains( shapeIt.Value() ))
1763 TopTools_IndexedMapOfShape oldShapeMap;
1764 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1765 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1767 const TopoDS_Shape& oldShape = oldShapeMap(i);
1768 int oldInd = meshDS->ShapeToIndex( oldShape );
1770 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1771 if ( i_smIor != _mapSubMeshIor.end() ) {
1772 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1775 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1776 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1778 // check if a group bases on oldInd shape
1779 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1780 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1781 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1782 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1784 RemoveGroup( i_grp->second ); // several groups can base on same shape
1785 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1790 // Reassign hypotheses and update groups after setting the new shape to mesh
1792 // collect anassigned hypotheses
1793 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1794 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1795 TShapeHypList assignedHyps;
1796 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1798 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1799 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1800 if ( !hyps.empty() ) {
1801 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1802 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1803 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1806 // collect shapes supporting groups
1807 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1808 TShapeTypeList groupData;
1809 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1810 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1811 for ( ; grIt != groups.end(); ++grIt )
1813 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1815 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1817 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1818 _impl->ShapeToMesh( newShape );
1820 // reassign hypotheses
1821 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1822 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1824 TIndexedShape& geom = indS_hyps->first;
1825 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1826 int oldID = geom._index;
1827 int newID = meshDS->ShapeToIndex( geom._shape );
1830 if ( oldID == 1 ) { // main shape
1832 geom._shape = newShape;
1834 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1835 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1836 // care of submeshes
1837 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1838 if ( newID != oldID ) {
1839 _mapSubMesh [ newID ] = newSubmesh;
1840 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1841 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1842 _mapSubMesh. erase(oldID);
1843 _mapSubMesh_i. erase(oldID);
1844 _mapSubMeshIor.erase(oldID);
1845 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1849 TShapeTypeList::iterator geomType = groupData.begin();
1850 for ( ; geomType != groupData.end(); ++geomType )
1852 const TIndexedShape& geom = geomType->first;
1853 int oldID = geom._index;
1854 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1857 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1858 CORBA::String_var name = groupSO->GetName();
1860 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1862 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1863 group_i->changeLocalId( newID );
1866 break; // everything has been updated
1869 } // loop on group data
1873 CORBA::Long newNbEntities = NbNodes() + NbElements();
1874 list< SALOMEDS::SObject_var > soToUpdateIcons;
1875 if ( newNbEntities != nbEntities )
1877 // Add all SObjects with icons
1878 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1880 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1881 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1882 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1884 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1885 i_gr != _mapGroups.end(); ++i_gr ) // groups
1886 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1889 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1890 for ( ; so != soToUpdateIcons.end(); ++so )
1891 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1894 //=============================================================================
1896 * \brief Create standalone group instead if group on geometry
1898 //=============================================================================
1900 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1902 SMESH::SMESH_Group_var aGroup;
1903 if ( theGroup->_is_nil() )
1904 return aGroup._retn();
1906 Unexpect aCatch(SALOME_SalomeException);
1908 SMESH_GroupBase_i* aGroupToRem =
1909 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1911 return aGroup._retn();
1913 int anId = aGroupToRem->GetLocalID();
1914 if ( !_impl->ConvertToStandalone( anId ) )
1915 return aGroup._retn();
1916 removeGeomGroupData( theGroup );
1918 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1920 // remove old instance of group from own map
1921 _mapGroups.erase( anId );
1923 SALOMEDS::StudyBuilder_var builder;
1924 SALOMEDS::SObject_var aGroupSO;
1925 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1926 if ( !aStudy->_is_nil() ) {
1927 builder = aStudy->NewBuilder();
1928 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1929 if ( !aGroupSO->_is_nil() ) {
1931 // remove reference to geometry
1932 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1933 for ( ; chItr->More(); chItr->Next() )
1934 // Remove group's child SObject
1935 builder->RemoveObject( chItr->Value() );
1937 // Update Python script
1938 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1939 << aGroupSO << " )";
1943 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1944 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1945 aGroupImpl->Register();
1946 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1948 // remember new group in own map
1949 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1950 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1952 // register CORBA object for persistence
1953 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1955 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1957 return aGroup._retn();
1960 //=============================================================================
1964 //=============================================================================
1966 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1968 if(MYDEBUG) MESSAGE( "createSubMesh" );
1969 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1971 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1972 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1973 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1974 SMESH::SMESH_subMesh_var subMesh
1975 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1977 _mapSubMesh[subMeshId] = mySubMesh;
1978 _mapSubMesh_i[subMeshId] = subMeshServant;
1979 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1981 // register CORBA object for persistence
1982 int nextId = _gen_i->RegisterObject( subMesh );
1983 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1985 // to track changes of GEOM groups
1986 addGeomGroupData( theSubShapeObject, subMesh );
1988 return subMesh._retn();
1991 //=======================================================================
1992 //function : getSubMesh
1994 //=======================================================================
1996 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
1998 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
1999 if ( it == _mapSubMeshIor.end() )
2000 return SMESH::SMESH_subMesh::_nil();
2002 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2006 //=============================================================================
2010 //=============================================================================
2012 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2013 GEOM::GEOM_Object_ptr theSubShapeObject )
2015 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2016 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2019 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2021 CORBA::Long shapeId = theSubMesh->GetId();
2022 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2024 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2027 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2028 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2029 for ( ; hyp != hyps.end(); ++hyp )
2030 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2037 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2038 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2039 removeHypothesis( theSubShapeObject, aHypList[i] );
2042 catch( const SALOME::SALOME_Exception& ) {
2043 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2045 removeGeomGroupData( theSubShapeObject );
2047 int subMeshId = theSubMesh->GetId();
2049 _mapSubMesh.erase(subMeshId);
2050 _mapSubMesh_i.erase(subMeshId);
2051 _mapSubMeshIor.erase(subMeshId);
2052 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2055 //=============================================================================
2059 //=============================================================================
2061 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2062 const char* theName,
2063 const TopoDS_Shape& theShape )
2066 SMESH::SMESH_GroupBase_var aGroup;
2067 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2068 SMESH_GroupBase_i* aGroupImpl;
2069 if ( !theShape.IsNull() )
2070 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2072 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2074 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2075 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2076 aGroupImpl->Register();
2077 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2079 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2080 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2082 // register CORBA object for persistence
2083 int nextId = _gen_i->RegisterObject( aGroup );
2084 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2086 // to track changes of GEOM groups
2087 if ( !theShape.IsNull() ) {
2088 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2089 addGeomGroupData( geom, aGroup );
2092 return aGroup._retn();
2095 //=============================================================================
2097 * SMESH_Mesh_i::removeGroup
2099 * Should be called by ~SMESH_Group_i()
2101 //=============================================================================
2103 void SMESH_Mesh_i::removeGroup( const int theId )
2105 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2106 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2107 removeGeomGroupData( _mapGroups[theId] );
2108 _mapGroups.erase( theId );
2109 _impl->RemoveGroup( theId );
2114 //=============================================================================
2118 //=============================================================================
2120 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2121 throw(SALOME::SALOME_Exception)
2123 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2125 SMESH::log_array_var aLog;
2127 list < SMESHDS_Command * >logDS = _impl->GetLog();
2128 aLog = new SMESH::log_array;
2130 int lg = logDS.size();
2133 list < SMESHDS_Command * >::iterator its = logDS.begin();
2134 while(its != logDS.end()){
2135 SMESHDS_Command *com = *its;
2136 int comType = com->GetType();
2138 int lgcom = com->GetNumber();
2140 const list < int >&intList = com->GetIndexes();
2141 int inum = intList.size();
2143 list < int >::const_iterator ii = intList.begin();
2144 const list < double >&coordList = com->GetCoords();
2145 int rnum = coordList.size();
2147 list < double >::const_iterator ir = coordList.begin();
2148 aLog[indexLog].commandType = comType;
2149 aLog[indexLog].number = lgcom;
2150 aLog[indexLog].coords.length(rnum);
2151 aLog[indexLog].indexes.length(inum);
2152 for(int i = 0; i < rnum; i++){
2153 aLog[indexLog].coords[i] = *ir;
2154 //MESSAGE(" "<<i<<" "<<ir.Value());
2157 for(int i = 0; i < inum; i++){
2158 aLog[indexLog].indexes[i] = *ii;
2159 //MESSAGE(" "<<i<<" "<<ii.Value());
2168 catch(SALOME_Exception & S_ex){
2169 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2171 return aLog._retn();
2175 //=============================================================================
2179 //=============================================================================
2181 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2183 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2187 //=============================================================================
2191 //=============================================================================
2193 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2195 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2199 //=============================================================================
2203 //=============================================================================
2205 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2210 //=============================================================================
2214 //=============================================================================
2216 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2218 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2222 //=============================================================================
2226 //=============================================================================
2228 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2230 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2234 //=============================================================================
2236 * Return mesh editor
2238 //=============================================================================
2240 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2242 // Create MeshEditor
2243 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2244 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2246 // Update Python script
2247 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2249 return aMesh._retn();
2252 //=============================================================================
2254 * Return mesh edition previewer
2256 //=============================================================================
2258 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2260 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2261 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2262 return aMesh._retn();
2265 //================================================================================
2267 * \brief Return true if the mesh has been edited since a last total re-compute
2268 * and those modifications may prevent successful partial re-compute
2270 //================================================================================
2272 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2274 Unexpect aCatch(SALOME_SalomeException);
2275 return _impl->HasModificationsToDiscard();
2278 //=============================================================================
2282 //=============================================================================
2283 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2285 Unexpect aCatch(SALOME_SalomeException);
2286 _impl->SetAutoColor(theAutoColor);
2289 //=============================================================================
2293 //=============================================================================
2294 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2296 Unexpect aCatch(SALOME_SalomeException);
2297 return _impl->GetAutoColor();
2301 //=============================================================================
2303 * Export in different formats
2305 //=============================================================================
2307 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2309 return _impl->HasDuplicatedGroupNamesMED();
2312 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2314 TCollection_AsciiString aFullName ((char*)file);
2315 OSD_Path aPath (aFullName);
2316 OSD_File aFile (aPath);
2317 if (aFile.Exists()) {
2318 // existing filesystem node
2319 if (aFile.KindOfFile() == OSD_FILE) {
2320 if (aFile.IsWriteable()) {
2325 if (aFile.Failed()) {
2326 TCollection_AsciiString msg ("File ");
2327 msg += aFullName + " cannot be replaced.";
2328 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2331 TCollection_AsciiString msg ("File ");
2332 msg += aFullName + " cannot be overwritten.";
2333 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2336 TCollection_AsciiString msg ("Location ");
2337 msg += aFullName + " is not a file.";
2338 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2341 // nonexisting file; check if it can be created
2343 aFile.Build(OSD_WriteOnly, OSD_Protection());
2344 if (aFile.Failed()) {
2345 TCollection_AsciiString msg ("You cannot create the file ");
2346 msg += aFullName + ". Check the directory existance and access rights.";
2347 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2355 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2356 CORBA::Boolean auto_groups,
2357 SMESH::MED_VERSION theVersion,
2358 CORBA::Boolean overwrite)
2359 throw(SALOME::SALOME_Exception)
2361 Unexpect aCatch(SALOME_SalomeException);
2364 PrepareForWriting(file, overwrite);
2365 const char* aMeshName = "Mesh";
2366 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2367 if ( !aStudy->_is_nil() ) {
2368 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2369 if ( !aMeshSO->_is_nil() ) {
2370 aMeshName = aMeshSO->GetName();
2371 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2372 if ( !aStudy->GetProperties()->IsLocked() )
2374 SALOMEDS::GenericAttribute_var anAttr;
2375 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2376 SALOMEDS::AttributeExternalFileDef_var aFileName;
2377 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2378 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2379 ASSERT(!aFileName->_is_nil());
2380 aFileName->SetValue(file);
2381 SALOMEDS::AttributeFileType_var aFileType;
2382 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2383 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2384 ASSERT(!aFileType->_is_nil());
2385 aFileType->SetValue("FICHIERMED");
2389 // Update Python script
2390 // set name of mesh before export
2391 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2393 // check names of groups
2396 TPythonDump() << _this() << ".ExportToMEDX( r'"
2397 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2399 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2402 void SMESH_Mesh_i::ExportToMED (const char* file,
2403 CORBA::Boolean auto_groups,
2404 SMESH::MED_VERSION theVersion)
2405 throw(SALOME::SALOME_Exception)
2407 ExportToMEDX(file,auto_groups,theVersion,true);
2410 void SMESH_Mesh_i::ExportMED (const char* file,
2411 CORBA::Boolean auto_groups)
2412 throw(SALOME::SALOME_Exception)
2414 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2417 void SMESH_Mesh_i::ExportDAT (const char *file)
2418 throw(SALOME::SALOME_Exception)
2420 Unexpect aCatch(SALOME_SalomeException);
2422 // Update Python script
2423 // check names of groups
2425 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2428 PrepareForWriting(file);
2429 _impl->ExportDAT(file);
2432 void SMESH_Mesh_i::ExportUNV (const char *file)
2433 throw(SALOME::SALOME_Exception)
2435 Unexpect aCatch(SALOME_SalomeException);
2437 // Update Python script
2438 // check names of groups
2440 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2443 PrepareForWriting(file);
2444 _impl->ExportUNV(file);
2447 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2448 throw(SALOME::SALOME_Exception)
2450 Unexpect aCatch(SALOME_SalomeException);
2452 // Update Python script
2453 // check names of groups
2455 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2458 PrepareForWriting(file);
2459 _impl->ExportSTL(file, isascii);
2462 //=============================================================================
2466 //=============================================================================
2468 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2470 Unexpect aCatch(SALOME_SalomeException);
2471 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2472 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2473 return aMesh._retn();
2476 //=============================================================================
2480 //=============================================================================
2481 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2483 Unexpect aCatch(SALOME_SalomeException);
2484 return _impl->NbNodes();
2487 //=============================================================================
2491 //=============================================================================
2492 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2494 Unexpect aCatch(SALOME_SalomeException);
2495 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2498 //=============================================================================
2502 //=============================================================================
2503 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2505 Unexpect aCatch(SALOME_SalomeException);
2506 return _impl->Nb0DElements();
2509 //=============================================================================
2513 //=============================================================================
2514 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2516 Unexpect aCatch(SALOME_SalomeException);
2517 return _impl->NbEdges();
2520 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2521 throw(SALOME::SALOME_Exception)
2523 Unexpect aCatch(SALOME_SalomeException);
2524 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2527 //=============================================================================
2531 //=============================================================================
2532 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2534 Unexpect aCatch(SALOME_SalomeException);
2535 return _impl->NbFaces();
2538 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2540 Unexpect aCatch(SALOME_SalomeException);
2541 return _impl->NbTriangles();
2544 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2546 Unexpect aCatch(SALOME_SalomeException);
2547 return _impl->NbQuadrangles();
2550 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2552 Unexpect aCatch(SALOME_SalomeException);
2553 return _impl->NbPolygons();
2556 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2557 throw(SALOME::SALOME_Exception)
2559 Unexpect aCatch(SALOME_SalomeException);
2560 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2563 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2564 throw(SALOME::SALOME_Exception)
2566 Unexpect aCatch(SALOME_SalomeException);
2567 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2570 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2571 throw(SALOME::SALOME_Exception)
2573 Unexpect aCatch(SALOME_SalomeException);
2574 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2577 //=============================================================================
2581 //=============================================================================
2582 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2584 Unexpect aCatch(SALOME_SalomeException);
2585 return _impl->NbVolumes();
2588 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2590 Unexpect aCatch(SALOME_SalomeException);
2591 return _impl->NbTetras();
2594 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2596 Unexpect aCatch(SALOME_SalomeException);
2597 return _impl->NbHexas();
2600 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2602 Unexpect aCatch(SALOME_SalomeException);
2603 return _impl->NbPyramids();
2606 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2608 Unexpect aCatch(SALOME_SalomeException);
2609 return _impl->NbPrisms();
2612 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2614 Unexpect aCatch(SALOME_SalomeException);
2615 return _impl->NbPolyhedrons();
2618 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2619 throw(SALOME::SALOME_Exception)
2621 Unexpect aCatch(SALOME_SalomeException);
2622 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2625 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2626 throw(SALOME::SALOME_Exception)
2628 Unexpect aCatch(SALOME_SalomeException);
2629 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2632 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2633 throw(SALOME::SALOME_Exception)
2635 Unexpect aCatch(SALOME_SalomeException);
2636 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2639 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2640 throw(SALOME::SALOME_Exception)
2642 Unexpect aCatch(SALOME_SalomeException);
2643 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2646 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2647 throw(SALOME::SALOME_Exception)
2649 Unexpect aCatch(SALOME_SalomeException);
2650 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2653 //=============================================================================
2657 //=============================================================================
2658 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2660 Unexpect aCatch(SALOME_SalomeException);
2661 return _mapSubMesh_i.size();
2664 //=============================================================================
2668 //=============================================================================
2669 char* SMESH_Mesh_i::Dump()
2673 return CORBA::string_dup( os.str().c_str() );
2676 //=============================================================================
2680 //=============================================================================
2681 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2683 // SMESH::long_array_var aResult = new SMESH::long_array();
2684 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2685 // int aMinId = aSMESHDS_Mesh->MinElementID();
2686 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2688 // aResult->length(aMaxId - aMinId + 1);
2690 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2691 // aResult[i++] = id;
2693 // return aResult._retn();
2695 return GetElementsId();
2698 //=============================================================================
2702 //=============================================================================
2704 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2705 throw (SALOME::SALOME_Exception)
2707 Unexpect aCatch(SALOME_SalomeException);
2708 MESSAGE("SMESH_Mesh_i::GetElementsId");
2709 SMESH::long_array_var aResult = new SMESH::long_array();
2710 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2712 if ( aSMESHDS_Mesh == NULL )
2713 return aResult._retn();
2715 long nbElements = NbElements();
2716 aResult->length( nbElements );
2717 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2718 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2719 aResult[i] = anIt->next()->GetID();
2721 return aResult._retn();
2725 //=============================================================================
2729 //=============================================================================
2731 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2732 throw (SALOME::SALOME_Exception)
2734 Unexpect aCatch(SALOME_SalomeException);
2735 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2736 SMESH::long_array_var aResult = new SMESH::long_array();
2737 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2739 if ( aSMESHDS_Mesh == NULL )
2740 return aResult._retn();
2742 long nbElements = NbElements();
2744 // No sense in returning ids of elements along with ids of nodes:
2745 // when theElemType == SMESH::ALL, return node ids only if
2746 // there are no elements
2747 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2748 return GetNodesId();
2750 aResult->length( nbElements );
2754 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2755 while ( i < nbElements && anIt->more() ) {
2756 const SMDS_MeshElement* anElem = anIt->next();
2757 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2758 aResult[i++] = anElem->GetID();
2761 aResult->length( i );
2763 return aResult._retn();
2766 //=============================================================================
2770 //=============================================================================
2772 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2773 throw (SALOME::SALOME_Exception)
2775 Unexpect aCatch(SALOME_SalomeException);
2776 MESSAGE("SMESH_subMesh_i::GetNodesId");
2777 SMESH::long_array_var aResult = new SMESH::long_array();
2778 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2780 if ( aSMESHDS_Mesh == NULL )
2781 return aResult._retn();
2783 long nbNodes = NbNodes();
2784 aResult->length( nbNodes );
2785 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2786 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2787 aResult[i] = anIt->next()->GetID();
2789 return aResult._retn();
2792 //=============================================================================
2796 //=============================================================================
2798 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2799 throw (SALOME::SALOME_Exception)
2801 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2804 //=============================================================================
2808 //=============================================================================
2810 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2811 throw (SALOME::SALOME_Exception)
2813 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2815 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2817 return ( SMESH::EntityType ) e->GetEntityType();
2820 //=============================================================================
2822 * Returns ID of elements for given submesh
2824 //=============================================================================
2825 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2826 throw (SALOME::SALOME_Exception)
2828 SMESH::long_array_var aResult = new SMESH::long_array();
2830 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2831 if(!SM) return aResult._retn();
2833 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2834 if(!SDSM) return aResult._retn();
2836 aResult->length(SDSM->NbElements());
2838 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2840 while ( eIt->more() ) {
2841 aResult[i++] = eIt->next()->GetID();
2844 return aResult._retn();
2848 //=============================================================================
2850 * Returns ID of nodes for given submesh
2851 * If param all==true - returns all nodes, else -
2852 * returns only nodes on shapes.
2854 //=============================================================================
2855 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2856 throw (SALOME::SALOME_Exception)
2858 SMESH::long_array_var aResult = new SMESH::long_array();
2860 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2861 if(!SM) return aResult._retn();
2863 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2864 if(!SDSM) return aResult._retn();
2867 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2868 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2869 while ( nIt->more() ) {
2870 const SMDS_MeshNode* elem = nIt->next();
2871 theElems.insert( elem->GetID() );
2874 else { // all nodes of submesh elements
2875 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2876 while ( eIt->more() ) {
2877 const SMDS_MeshElement* anElem = eIt->next();
2878 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2879 while ( nIt->more() ) {
2880 const SMDS_MeshElement* elem = nIt->next();
2881 theElems.insert( elem->GetID() );
2886 aResult->length(theElems.size());
2887 set<int>::iterator itElem;
2889 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2890 aResult[i++] = *itElem;
2892 return aResult._retn();
2896 //=============================================================================
2898 * Returns type of elements for given submesh
2900 //=============================================================================
2901 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2902 throw (SALOME::SALOME_Exception)
2904 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2905 if(!SM) return SMESH::ALL;
2907 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2908 if(!SDSM) return SMESH::ALL;
2910 if(SDSM->NbElements()==0)
2911 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2913 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2914 const SMDS_MeshElement* anElem = eIt->next();
2915 return ( SMESH::ElementType ) anElem->GetType();
2919 //=============================================================================
2923 //=============================================================================
2925 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2927 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2929 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2934 //=============================================================================
2936 * Get XYZ coordinates of node as list of double
2937 * If there is not node for given ID - returns empty list
2939 //=============================================================================
2941 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2943 SMESH::double_array_var aResult = new SMESH::double_array();
2944 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2945 if ( aSMESHDS_Mesh == NULL )
2946 return aResult._retn();
2949 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2951 return aResult._retn();
2955 aResult[0] = aNode->X();
2956 aResult[1] = aNode->Y();
2957 aResult[2] = aNode->Z();
2958 return aResult._retn();
2962 //=============================================================================
2964 * For given node returns list of IDs of inverse elements
2965 * If there is not node for given ID - returns empty list
2967 //=============================================================================
2969 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2971 SMESH::long_array_var aResult = new SMESH::long_array();
2972 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2973 if ( aSMESHDS_Mesh == NULL )
2974 return aResult._retn();
2977 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2979 return aResult._retn();
2981 // find inverse elements
2982 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2983 TColStd_SequenceOfInteger IDs;
2984 while(eIt->more()) {
2985 const SMDS_MeshElement* elem = eIt->next();
2986 IDs.Append(elem->GetID());
2988 if(IDs.Length()>0) {
2989 aResult->length(IDs.Length());
2991 for(; i<=IDs.Length(); i++) {
2992 aResult[i-1] = IDs.Value(i);
2995 return aResult._retn();
2998 //=============================================================================
3000 * \brief Return position of a node on shape
3002 //=============================================================================
3004 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3006 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3007 aNodePosition->shapeID = 0;
3008 aNodePosition->shapeType = GEOM::SHAPE;
3010 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3011 if ( !mesh ) return aNodePosition;
3013 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3015 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3017 aNodePosition->shapeID = pos->GetShapeId();
3018 switch ( pos->GetTypeOfPosition() ) {
3020 aNodePosition->shapeType = GEOM::EDGE;
3021 aNodePosition->params.length(1);
3022 aNodePosition->params[0] =
3023 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
3026 aNodePosition->shapeType = GEOM::FACE;
3027 aNodePosition->params.length(2);
3028 aNodePosition->params[0] =
3029 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
3030 aNodePosition->params[1] =
3031 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
3033 case SMDS_TOP_VERTEX:
3034 aNodePosition->shapeType = GEOM::VERTEX;
3036 case SMDS_TOP_3DSPACE:
3037 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3038 aNodePosition->shapeType = GEOM::SOLID;
3039 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3040 aNodePosition->shapeType = GEOM::SHELL;
3046 return aNodePosition;
3049 //=============================================================================
3051 * If given element is node returns IDs of shape from position
3052 * If there is not node for given ID - returns -1
3054 //=============================================================================
3056 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3058 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3059 if ( aSMESHDS_Mesh == NULL )
3063 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3065 SMDS_PositionPtr pos = aNode->GetPosition();
3069 return pos->GetShapeId();
3076 //=============================================================================
3078 * For given element returns ID of result shape after
3079 * ::FindShape() from SMESH_MeshEditor
3080 * If there is not element for given ID - returns -1
3082 //=============================================================================
3084 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3086 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3087 if ( aSMESHDS_Mesh == NULL )
3090 // try to find element
3091 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3095 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3096 ::SMESH_MeshEditor aMeshEditor(_impl);
3097 int index = aMeshEditor.FindShape( elem );
3105 //=============================================================================
3107 * Returns number of nodes for given element
3108 * If there is not element for given ID - returns -1
3110 //=============================================================================
3112 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3114 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3115 if ( aSMESHDS_Mesh == NULL ) return -1;
3116 // try to find element
3117 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3118 if(!elem) return -1;
3119 return elem->NbNodes();
3123 //=============================================================================
3125 * Returns ID of node by given index for given element
3126 * If there is not element for given ID - returns -1
3127 * If there is not node for given index - returns -2
3129 //=============================================================================
3131 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3133 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3134 if ( aSMESHDS_Mesh == NULL ) return -1;
3135 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3136 if(!elem) return -1;
3137 if( index>=elem->NbNodes() || index<0 ) return -1;
3138 return elem->GetNode(index)->GetID();
3141 //=============================================================================
3143 * Returns IDs of nodes of given element
3145 //=============================================================================
3147 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3149 SMESH::long_array_var aResult = new SMESH::long_array();
3150 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3152 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3154 aResult->length( elem->NbNodes() );
3155 for ( int i = 0; i < elem->NbNodes(); ++i )
3156 aResult[ i ] = elem->GetNode( i )->GetID();
3159 return aResult._retn();
3162 //=============================================================================
3164 * Returns true if given node is medium node
3165 * in given quadratic element
3167 //=============================================================================
3169 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3171 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3172 if ( aSMESHDS_Mesh == NULL ) return false;
3174 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3175 if(!aNode) return false;
3176 // try to find element
3177 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3178 if(!elem) return false;
3180 return elem->IsMediumNode(aNode);
3184 //=============================================================================
3186 * Returns true if given node is medium node
3187 * in one of quadratic elements
3189 //=============================================================================
3191 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3192 SMESH::ElementType theElemType)
3194 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3195 if ( aSMESHDS_Mesh == NULL ) return false;
3198 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3199 if(!aNode) return false;
3201 SMESH_MesherHelper aHelper( *(_impl) );
3203 SMDSAbs_ElementType aType;
3204 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3205 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3206 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3207 else aType = SMDSAbs_All;
3209 return aHelper.IsMedium(aNode,aType);
3213 //=============================================================================
3215 * Returns number of edges for given element
3217 //=============================================================================
3219 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3221 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3222 if ( aSMESHDS_Mesh == NULL ) return -1;
3223 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3224 if(!elem) return -1;
3225 return elem->NbEdges();
3229 //=============================================================================
3231 * Returns number of faces for given element
3233 //=============================================================================
3235 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3237 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3238 if ( aSMESHDS_Mesh == NULL ) return -1;
3239 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3240 if(!elem) return -1;
3241 return elem->NbFaces();
3244 //=======================================================================
3245 //function : GetElemFaceNodes
3246 //purpose : Returns nodes of given face (counted from zero) for given element.
3247 //=======================================================================
3249 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3250 CORBA::Short faceIndex)
3252 SMESH::long_array_var aResult = new SMESH::long_array();
3253 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3255 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3257 SMDS_VolumeTool vtool( elem );
3258 if ( faceIndex < vtool.NbFaces() )
3260 aResult->length( vtool.NbFaceNodes( faceIndex ));
3261 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3262 for ( int i = 0; i < aResult->length(); ++i )
3263 aResult[ i ] = nn[ i ]->GetID();
3267 return aResult._retn();
3270 //=======================================================================
3271 //function : FindElementByNodes
3272 //purpose : Returns an element based on all given nodes.
3273 //=======================================================================
3275 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3277 CORBA::Long elemID(0);
3278 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3280 vector< const SMDS_MeshNode * > nn( nodes.length() );
3281 for ( int i = 0; i < nodes.length(); ++i )
3282 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3285 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3286 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3287 _impl->NbFaces( ORDER_QUADRATIC ) ||
3288 _impl->NbVolumes( ORDER_QUADRATIC )))
3289 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3291 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3296 //=============================================================================
3298 * Returns true if given element is polygon
3300 //=============================================================================
3302 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3304 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3305 if ( aSMESHDS_Mesh == NULL ) return false;
3306 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3307 if(!elem) return false;
3308 return elem->IsPoly();
3312 //=============================================================================
3314 * Returns true if given element is quadratic
3316 //=============================================================================
3318 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3320 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3321 if ( aSMESHDS_Mesh == NULL ) return false;
3322 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3323 if(!elem) return false;
3324 return elem->IsQuadratic();
3328 //=============================================================================
3330 * Returns bary center for given element
3332 //=============================================================================
3334 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3336 SMESH::double_array_var aResult = new SMESH::double_array();
3337 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3338 if ( aSMESHDS_Mesh == NULL )
3339 return aResult._retn();
3341 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3343 return aResult._retn();
3345 if(elem->GetType()==SMDSAbs_Volume) {
3346 SMDS_VolumeTool aTool;
3347 if(aTool.Set(elem)) {
3349 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3354 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3356 double x=0., y=0., z=0.;
3357 for(; anIt->more(); ) {
3359 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3373 return aResult._retn();
3377 //=============================================================================
3379 * Create and publish group servants if any groups were imported or created anyhow
3381 //=============================================================================
3383 void SMESH_Mesh_i::CreateGroupServants()
3385 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3387 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3388 while ( groupIt->more() )
3390 ::SMESH_Group* group = groupIt->next();
3391 int anId = group->GetGroupDS()->GetID();
3393 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3394 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3397 SMESH_GroupBase_i* aGroupImpl;
3399 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3400 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3402 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3403 shape = groupOnGeom->GetShape();
3406 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3409 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3410 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3411 aGroupImpl->Register();
3413 SMESH::SMESH_GroupBase_var groupVar =
3414 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3415 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3417 // register CORBA object for persistence
3418 int nextId = _gen_i->RegisterObject( groupVar );
3419 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3421 // publishing of the groups in the study
3422 if ( !aStudy->_is_nil() ) {
3423 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3424 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3429 //=============================================================================
3431 * \brief Return groups cantained in _mapGroups by their IDs
3433 //=============================================================================
3435 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3437 int nbGroups = groupIDs.size();
3438 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3439 aList->length( nbGroups );
3441 list<int>::const_iterator ids = groupIDs.begin();
3442 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3444 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3445 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3446 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3448 aList->length( nbGroups );
3449 return aList._retn();
3452 //=============================================================================
3454 * \brief Return information about imported file
3456 //=============================================================================
3458 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3460 SALOME_MED::MedFileInfo_var res( myFileInfo );
3461 if ( !res.operator->() ) {
3462 res = new SALOME_MED::MedFileInfo;
3464 res->fileSize = res->major = res->minor = res->release = -1;
3469 //=============================================================================
3471 * \brief Check and correct names of mesh groups
3473 //=============================================================================
3475 void SMESH_Mesh_i::checkGroupNames()
3477 int nbGrp = NbGroups();
3481 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3482 if ( aStudy->_is_nil() )
3483 return; // nothing to do
3485 SMESH::ListOfGroups* grpList = 0;
3486 // avoid dump of "GetGroups"
3488 // store python dump into a local variable inside local scope
3489 SMESH::TPythonDump pDump; // do not delete this line of code
3490 grpList = GetGroups();
3493 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3494 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3497 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3498 if ( aGrpSO->_is_nil() )
3500 // correct name of the mesh group if necessary
3501 const char* guiName = aGrpSO->GetName();
3502 if ( strcmp(guiName, aGrp->GetName()) )
3503 aGrp->SetName( guiName );
3507 //=============================================================================
3509 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3511 //=============================================================================
3512 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3514 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3515 CORBA::string_dup(theParameters));
3518 //=============================================================================
3520 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3522 //=============================================================================
3523 char* SMESH_Mesh_i::GetParameters()
3525 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3526 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3529 //=============================================================================
3531 * \brief Returns list of notebook variables used for last Mesh operation
3533 //=============================================================================
3534 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3536 SMESH::string_array_var aResult = new SMESH::string_array();
3537 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3539 char *aParameters = GetParameters();
3540 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3541 if(!aStudy->_is_nil()) {
3542 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3543 if(aSections->length() > 0) {
3544 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3545 aResult->length(aVars.length());
3546 for(int i = 0;i < aVars.length();i++)
3547 aResult[i] = CORBA::string_dup( aVars[i]);
3551 return aResult._retn();
3554 //=======================================================================
3555 //function : GetTypes
3556 //purpose : Returns types of elements it contains
3557 //=======================================================================
3559 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3561 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3565 if (_impl->NbEdges())
3566 types[nbTypes++] = SMESH::EDGE;
3567 if (_impl->NbFaces())
3568 types[nbTypes++] = SMESH::FACE;
3569 if (_impl->NbVolumes())
3570 types[nbTypes++] = SMESH::VOLUME;
3571 if (_impl->Nb0DElements())
3572 types[nbTypes++] = SMESH::ELEM0D;
3573 types->length( nbTypes );
3575 return types._retn();
3578 //=============================================================================
3580 * \brief Returns statistic of mesh elements
3582 //=============================================================================
3583 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3585 SMESH::long_array_var aRes = new SMESH::long_array();
3586 aRes->length(SMESH::Entity_Last);
3587 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3589 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3591 return aRes._retn();
3592 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3593 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3594 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3595 return aRes._retn();
3598 //=============================================================================
3600 * \brief Collect statistic of mesh elements given by iterator
3602 //=============================================================================
3603 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3604 SMESH::long_array& theInfo)
3606 if (!theItr) return;
3607 while (theItr->more())
3608 theInfo[ theItr->next()->GetEntityType() ]++;
3611 //=============================================================================
3613 * \brief mapping of mesh dimension into shape type
3615 //=============================================================================
3616 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3618 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3620 case 0: aType = TopAbs_VERTEX; break;
3621 case 1: aType = TopAbs_EDGE; break;
3622 case 2: aType = TopAbs_FACE; break;
3624 default:aType = TopAbs_SOLID; break;
3629 //=============================================================================
3631 * \brief Internal structure used to find concurent submeshes
3633 * It represents a pair < submesh, concurent dimension >, where
3634 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3635 * with another submesh. In other words, it is dimension of a hypothesis assigned
3638 //=============================================================================
3644 int _dim; //!< a dimension the algo can build (concurrent dimension)
3645 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3646 TopTools_MapOfShape _shapeMap;
3647 SMESH_subMesh* _subMesh;
3648 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3651 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3653 const TopoDS_Shape& theShape)
3655 _subMesh = (SMESH_subMesh*)theSubMesh;
3656 SetShape( theDim, theShape );
3660 void SetShape(const int theDim,
3661 const TopoDS_Shape& theShape)
3664 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3665 if (_dim >= _ownDim)
3666 _shapeMap.Add( theShape );
3668 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3669 for( ; anExp.More(); anExp.Next() )
3670 _shapeMap.Add( anExp.Current() );
3674 //! Check sharing of sub shapes
3675 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3676 const TopTools_MapOfShape& theToFind,
3677 const TopAbs_ShapeEnum theType)
3679 bool isShared = false;
3680 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3681 for (; !isShared && anItr.More(); anItr.Next() ) {
3682 const TopoDS_Shape aSubSh = anItr.Key();
3683 // check for case when concurrent dimensions are same
3684 isShared = theToFind.Contains( aSubSh );
3685 // check for subshape with concurrent dimension
3686 TopExp_Explorer anExp( aSubSh, theType );
3687 for ( ; !isShared && anExp.More(); anExp.Next() )
3688 isShared = theToFind.Contains( anExp.Current() );
3693 //! check algorithms
3694 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3695 const SMESHDS_Hypothesis* theA2)
3697 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3698 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3699 return false; // one of the hypothesis is not algorithm
3700 // check algorithm names (should be equal)
3701 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3705 //! Check if subshape hypotheses are concurrent
3706 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3708 if ( _subMesh == theOther->_subMesh )
3709 return false; // same subshape - should not be
3711 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3712 // any of the two submeshes is not on COMPOUND shape )
3713 // -> no concurrency
3714 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3715 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3716 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3719 // bool checkSubShape = ( _dim >= theOther->_dim )
3720 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3721 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3722 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3723 if ( !checkSubShape )
3726 // check algorithms to be same
3727 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3728 return true; // different algorithms
3730 // check hypothesises for concurrence (skip first as algorithm)
3732 // pointers should be same, becase it is referenes from mesh hypothesis partition
3733 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3734 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3735 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3736 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3738 // the submeshes are concurrent if their algorithms has different parameters
3739 return nbSame != theOther->_hypothesises.size() - 1;
3742 }; // end of SMESH_DimHyp
3744 typedef list<SMESH_DimHyp*> TDimHypList;
3746 static void addDimHypInstance(const int theDim,
3747 const TopoDS_Shape& theShape,
3748 const SMESH_Algo* theAlgo,
3749 const SMESH_subMesh* theSubMesh,
3750 const list <const SMESHDS_Hypothesis*>& theHypList,
3751 TDimHypList* theDimHypListArr )
3753 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3754 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3755 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3756 listOfdimHyp.push_back( dimHyp );
3759 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3760 dimHyp->_hypothesises.push_front(theAlgo);
3761 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3762 for( ; hypIt != theHypList.end(); hypIt++ )
3763 dimHyp->_hypothesises.push_back( *hypIt );
3766 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3767 const TDimHypList& theListOfDimHyp,
3768 TListOfInt& theListOfConcurr )
3770 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3771 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3772 const SMESH_DimHyp* curDimHyp = *rIt;
3773 if ( curDimHyp == theDimHyp )
3774 break; // meet own dimHyp pointer in same dimension
3775 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3776 if ( find( theListOfConcurr.begin(),
3777 theListOfConcurr.end(),
3778 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3779 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3783 static void unionLists(TListOfInt& theListOfId,
3784 TListOfListOfInt& theListOfListOfId,
3787 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3788 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3790 continue; //skip already treated lists
3791 // check if other list has any same submesh object
3792 TListOfInt& otherListOfId = *it;
3793 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3794 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3797 // union two lists (from source into target)
3798 TListOfInt::iterator it2 = otherListOfId.begin();
3799 for ( ; it2 != otherListOfId.end(); it2++ ) {
3800 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3801 theListOfId.push_back(*it2);
3803 // clear source list
3804 otherListOfId.clear();
3808 //! free memory allocated for dimension-hypothesis objects
3809 static void removeDimHyps( TDimHypList* theArrOfList )
3811 for (int i = 0; i < 4; i++ ) {
3812 TDimHypList& listOfdimHyp = theArrOfList[i];
3813 TDimHypList::const_iterator it = listOfdimHyp.begin();
3814 for ( ; it != listOfdimHyp.end(); it++ )
3819 //=============================================================================
3821 * \brief Return submesh objects list in meshing order
3823 //=============================================================================
3825 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3827 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3829 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3831 return aResult._retn();
3833 ::SMESH_Mesh& mesh = GetImpl();
3834 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3835 if ( !anOrder.size() ) {
3837 // collect submeshes detecting concurrent algorithms and hypothesises
3838 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3840 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3841 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3842 ::SMESH_subMesh* sm = (*i_sm).second;
3844 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3846 // list of assigned hypothesises
3847 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3848 // Find out dimensions where the submesh can be concurrent.
3849 // We define the dimensions by algo of each of hypotheses in hypList
3850 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3851 for( ; hypIt != hypList.end(); hypIt++ ) {
3852 SMESH_Algo* anAlgo = 0;
3853 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3854 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3855 // hyp it-self is algo
3856 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3858 // try to find algorithm with help of subshapes
3859 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3860 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3861 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3864 continue; // no assigned algorithm to current submesh
3866 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3867 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3869 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3870 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3871 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3873 } // end iterations on submesh
3875 // iterate on created dimension-hypotheses and check for concurrents
3876 for ( int i = 0; i < 4; i++ ) {
3877 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3878 // check for concurrents in own and other dimensions (step-by-step)
3879 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3880 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3881 const SMESH_DimHyp* dimHyp = *dhIt;
3882 TListOfInt listOfConcurr;
3883 // looking for concurrents and collect into own list
3884 for ( int j = i; j < 4; j++ )
3885 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3886 // check if any concurrents found
3887 if ( listOfConcurr.size() > 0 ) {
3888 // add own submesh to list of concurrent
3889 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3890 anOrder.push_back( listOfConcurr );
3895 removeDimHyps(dimHypListArr);
3897 // now, minimise the number of concurrent groups
3898 // Here we assume that lists of submhes can has same submesh
3899 // in case of multi-dimension algorithms, as result
3900 // list with common submesh have to be union into one list
3902 TListOfListOfInt::iterator listIt = anOrder.begin();
3903 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3904 unionLists( *listIt, anOrder, listIndx + 1 );
3906 // convert submesh ids into interface instances
3907 // and dump command into python
3908 convertMeshOrder( anOrder, aResult, true );
3910 return aResult._retn();
3913 //=============================================================================
3915 * \brief find common submeshes with given submesh
3916 * \param theSubMeshList list of already collected submesh to check
3917 * \param theSubMesh given submesh to intersect with other
3918 * \param theCommonSubMeshes collected common submeshes
3920 //=============================================================================
3922 static void findCommonSubMesh
3923 (list<const SMESH_subMesh*>& theSubMeshList,
3924 const SMESH_subMesh* theSubMesh,
3925 set<const SMESH_subMesh*>& theCommon )
3929 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
3930 for ( ; it != theSubMeshList.end(); it++ )
3931 theSubMesh->FindIntersection( *it, theCommon );
3932 theSubMeshList.push_back( theSubMesh );
3933 //theCommon.insert( theSubMesh );
3936 //=============================================================================
3938 * \brief Set submesh object order
3939 * \param theSubMeshArray submesh array order
3941 //=============================================================================
3943 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
3946 ::SMESH_Mesh& mesh = GetImpl();
3948 TPythonDump aPythonDump; // prevent dump of called methods
3949 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
3951 TListOfListOfInt subMeshOrder;
3952 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
3954 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
3955 TListOfInt subMeshIds;
3956 aPythonDump << "[ ";
3957 // Collect subMeshes which should be clear
3958 // do it list-by-list, because modification of submesh order
3959 // take effect between concurrent submeshes only
3960 set<const SMESH_subMesh*> subMeshToClear;
3961 list<const SMESH_subMesh*> subMeshList;
3962 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
3964 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
3966 aPythonDump << ", ";
3967 aPythonDump << subMesh;
3968 subMeshIds.push_back( subMesh->GetId() );
3969 // detect common parts of submeshes
3970 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
3971 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
3973 aPythonDump << " ]";
3974 subMeshOrder.push_back( subMeshIds );
3976 // clear collected submeshes
3977 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
3978 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
3979 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
3981 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
3982 // ClearSubMesh( *clrIt );
3985 aPythonDump << " ])";
3987 mesh.SetMeshOrder( subMeshOrder );
3993 //=============================================================================
3995 * \brief Convert submesh ids into submesh interfaces
3997 //=============================================================================
3999 void SMESH_Mesh_i::convertMeshOrder
4000 (const TListOfListOfInt& theIdsOrder,
4001 SMESH::submesh_array_array& theResOrder,
4002 const bool theIsDump)
4004 int nbSet = theIdsOrder.size();
4005 TPythonDump aPythonDump; // prevent dump of called methods
4007 aPythonDump << "[ ";
4008 theResOrder.length(nbSet);
4009 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4011 for( ; it != theIdsOrder.end(); it++ ) {
4012 // translate submesh identificators into submesh objects
4013 // takeing into account real number of concurrent lists
4014 const TListOfInt& aSubOrder = (*it);
4015 if (!aSubOrder.size())
4018 aPythonDump << "[ ";
4019 // convert shape indeces into interfaces
4020 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4021 aResSubSet->length(aSubOrder.size());
4022 TListOfInt::const_iterator subIt = aSubOrder.begin();
4023 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4024 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4026 SMESH::SMESH_subMesh_var subMesh =
4027 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4030 aPythonDump << ", ";
4031 aPythonDump << subMesh;
4033 aResSubSet[ j++ ] = subMesh;
4036 aPythonDump << " ]";
4037 theResOrder[ listIndx++ ] = aResSubSet;
4039 // correct number of lists
4040 theResOrder.length( listIndx );
4043 // finilise python dump
4044 aPythonDump << " ]";
4045 aPythonDump << " = " << _this() << ".GetMeshOrder()";