1 // Copyright (C) 2007-2013 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 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_SMESHDS_Mesh.h"
30 #include "SMDS_EdgePosition.hxx"
31 #include "SMDS_ElemIterator.hxx"
32 #include "SMDS_FacePosition.hxx"
33 #include "SMDS_IteratorOnIterators.hxx"
34 #include "SMDS_MeshGroup.hxx"
35 #include "SMDS_SetIterator.hxx"
36 #include "SMDS_VolumeTool.hxx"
37 #include "SMESHDS_Command.hxx"
38 #include "SMESHDS_CommandType.hxx"
39 #include "SMESHDS_Group.hxx"
40 #include "SMESHDS_GroupOnGeom.hxx"
41 #include "SMESH_Filter_i.hxx"
42 #include "SMESH_Gen_i.hxx"
43 #include "SMESH_Group.hxx"
44 #include "SMESH_Group_i.hxx"
45 #include "SMESH_MEDMesh_i.hxx"
46 #include "SMESH_MeshEditor.hxx"
47 #include "SMESH_MeshEditor_i.hxx"
48 #include "SMESH_MeshPartDS.hxx"
49 #include "SMESH_MesherHelper.hxx"
50 #include "SMESH_PreMeshInfo.hxx"
51 #include "SMESH_PythonDump.hxx"
52 #include "SMESH_subMesh_i.hxx"
55 #include <SALOMEDS_Attributes_wrap.hxx>
56 #include <SALOMEDS_wrap.hxx>
57 #include <SALOME_NamingService.hxx>
58 #include <Utils_ExceptHandlers.hxx>
59 #include <Utils_SINGLETON.hxx>
60 #include <utilities.h>
62 #include <GEOMImpl_Types.hxx>
63 #include <GEOM_wrap.hxx>
66 #include <BRep_Builder.hxx>
67 #include <OSD_Directory.hxx>
68 #include <OSD_File.hxx>
69 #include <OSD_Path.hxx>
70 #include <OSD_Protection.hxx>
71 #include <Standard_OutOfMemory.hxx>
72 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
73 #include <TColStd_MapOfInteger.hxx>
74 #include <TColStd_SequenceOfInteger.hxx>
75 #include <TCollection_AsciiString.hxx>
77 #include <TopExp_Explorer.hxx>
78 #include <TopTools_MapIteratorOfMapOfShape.hxx>
79 #include <TopTools_MapOfShape.hxx>
80 #include <TopoDS_Compound.hxx>
82 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 static int MYDEBUG = 0;
95 static int MYDEBUG = 0;
99 using SMESH::TPythonDump;
101 int SMESH_Mesh_i::_idGenerator = 0;
103 //=============================================================================
107 //=============================================================================
109 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
111 CORBA::Long studyId )
112 : SALOME::GenericObj_i( thePOA )
114 MESSAGE("SMESH_Mesh_i");
117 _id = _idGenerator++;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
130 MESSAGE("~SMESH_Mesh_i");
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 // _impl->RemoveGroup() is called by ~SMESH_GroupBase_i() (PAL6331)
138 //_impl->RemoveGroup( aGroup->GetLocalID() );
139 aGroup->myMeshServant = 0;
140 aGroup->UnRegister();
145 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
146 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
147 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
149 aSubMesh->UnRegister();
151 _mapSubMeshIor.clear();
153 // destroy hypotheses
154 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
155 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ )
156 if ( SMESH_Hypothesis_i* aHypo = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
162 delete _impl; _impl = NULL;
163 delete _preMeshInfo; _preMeshInfo = NULL;
166 //=============================================================================
170 * Associates <this> mesh with <theShape> and puts a reference
171 * to <theShape> into the current study;
172 * the previous shape is substituted by the new one.
174 //=============================================================================
176 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
177 throw (SALOME::SALOME_Exception)
179 Unexpect aCatch(SALOME_SalomeException);
181 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
183 catch(SALOME_Exception & S_ex) {
184 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
186 // to track changes of GEOM groups
187 addGeomGroupData( theShapeObject, _this() );
190 //================================================================================
192 * \brief return true if mesh has a shape to build a shape on
194 //================================================================================
196 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
197 throw (SALOME::SALOME_Exception)
199 Unexpect aCatch(SALOME_SalomeException);
202 res = _impl->HasShapeToMesh();
204 catch(SALOME_Exception & S_ex) {
205 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
210 //=======================================================================
211 //function : GetShapeToMesh
213 //=======================================================================
215 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
216 throw (SALOME::SALOME_Exception)
218 Unexpect aCatch(SALOME_SalomeException);
219 GEOM::GEOM_Object_var aShapeObj;
221 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
223 aShapeObj = _gen_i->ShapeToGeomObject( S );
225 catch(SALOME_Exception & S_ex) {
226 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
228 return aShapeObj._retn();
231 //================================================================================
233 * \brief Return false if the mesh is not yet fully loaded from the study file
235 //================================================================================
237 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
239 Unexpect aCatch(SALOME_SalomeException);
240 return !_preMeshInfo;
243 //================================================================================
245 * \brief Load full mesh data from the study file
247 //================================================================================
249 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
251 Unexpect aCatch(SALOME_SalomeException);
253 _preMeshInfo->FullLoadFromFile();
256 //================================================================================
258 * \brief Remove all nodes and elements
260 //================================================================================
262 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
264 Unexpect aCatch(SALOME_SalomeException);
266 _preMeshInfo->ForgetAllData();
270 CheckGeomGroupModif(); // issue 20145
272 catch(SALOME_Exception & S_ex) {
273 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
275 _impl->GetMeshDS()->Modified();
277 TPythonDump() << _this() << ".Clear()";
280 //================================================================================
282 * \brief Remove all nodes and elements for indicated shape
284 //================================================================================
286 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
287 throw (SALOME::SALOME_Exception)
289 Unexpect aCatch(SALOME_SalomeException);
291 _preMeshInfo->FullLoadFromFile();
294 _impl->ClearSubMesh( ShapeID );
296 catch(SALOME_Exception & S_ex) {
297 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
299 _impl->GetMeshDS()->Modified();
301 TPythonDump() << _this() << ".ClearSubMesh( " << ShapeID << " )";
304 //=============================================================================
306 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
308 //=============================================================================
310 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
312 SMESH::DriverMED_ReadStatus res;
315 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
316 res = SMESH::DRS_OK; break;
317 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
318 res = SMESH::DRS_EMPTY; break;
319 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
320 res = SMESH::DRS_WARN_RENUMBER; break;
321 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
322 res = SMESH::DRS_WARN_SKIP_ELEM; break;
323 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
324 res = SMESH::DRS_WARN_DESCENDING; break;
325 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
327 res = SMESH::DRS_FAIL; break;
332 //=============================================================================
334 * Convert ::SMESH_ComputeError to SMESH::ComputeError
336 //=============================================================================
338 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
340 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
341 errVar->subShapeID = -1;
342 errVar->hasBadMesh = false;
344 if ( !errorPtr || errorPtr->IsOK() )
346 errVar->code = SMESH::COMPERR_OK;
350 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
351 errVar->comment = errorPtr->myComment.c_str();
353 return errVar._retn();
356 //=============================================================================
360 * Imports mesh data from MED file
362 //=============================================================================
364 SMESH::DriverMED_ReadStatus
365 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
366 throw ( SALOME::SALOME_Exception )
368 Unexpect aCatch(SALOME_SalomeException);
371 status = _impl->MEDToMesh( theFileName, theMeshName );
373 catch( SALOME_Exception& S_ex ) {
374 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
377 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
380 CreateGroupServants();
382 int major, minor, release;
383 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
384 major = minor = release = -1;
385 _medFileInfo = new SALOME_MED::MedFileInfo();
386 _medFileInfo->fileName = theFileName;
387 _medFileInfo->fileSize = 0;
390 if ( ::_stati64( theFileName, &d ) != -1 )
393 if ( ::stat64( theFileName, &d ) != -1 )
395 _medFileInfo->fileSize = d.st_size;
396 _medFileInfo->major = major;
397 _medFileInfo->minor = minor;
398 _medFileInfo->release = release;
400 return ConvertDriverMEDReadStatus(status);
403 //================================================================================
405 * \brief Imports mesh data from the CGNS file
407 //================================================================================
409 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
410 const int theMeshIndex,
411 std::string& theMeshName )
412 throw ( SALOME::SALOME_Exception )
414 Unexpect aCatch(SALOME_SalomeException);
417 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
419 catch( SALOME_Exception& S_ex ) {
420 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
423 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
426 CreateGroupServants();
428 return ConvertDriverMEDReadStatus(status);
431 //================================================================================
433 * \brief Return string representation of a MED file version comprising nbDigits
435 //================================================================================
437 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
439 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
441 return CORBA::string_dup( ver.c_str() );
444 //=============================================================================
448 * Imports mesh data from MED file
450 //=============================================================================
452 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
453 throw ( SALOME::SALOME_Exception )
457 // Read mesh with name = <theMeshName> into SMESH_Mesh
458 _impl->UNVToMesh( theFileName );
460 CreateGroupServants();
462 SMESH_CATCH( SMESH::throwCorbaException );
467 //=============================================================================
471 * Imports mesh data from STL file
473 //=============================================================================
474 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
475 throw ( SALOME::SALOME_Exception )
479 // Read mesh with name = <theMeshName> into SMESH_Mesh
480 _impl->STLToMesh( theFileName );
482 SMESH_CATCH( SMESH::throwCorbaException );
487 //================================================================================
489 * \brief Function used in SMESH_CATCH by ImportGMFFile()
491 //================================================================================
495 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
497 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
501 //================================================================================
503 * \brief Imports data from a GMF file and returns an error description
505 //================================================================================
507 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
508 bool theMakeRequiredGroups )
509 throw (SALOME::SALOME_Exception)
511 SMESH_ComputeErrorPtr error;
514 #define SMESH_CAUGHT error =
517 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
519 SMESH_CATCH( exceptionToComputeError );
523 CreateGroupServants();
525 return ConvertComputeError( error );
528 //=============================================================================
532 //=============================================================================
534 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
536 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
537 (SMESH_Hypothesis::Hypothesis_Status theStatus)
540 RETURNCASE( HYP_OK );
541 RETURNCASE( HYP_MISSING );
542 RETURNCASE( HYP_CONCURENT );
543 RETURNCASE( HYP_BAD_PARAMETER );
544 RETURNCASE( HYP_HIDDEN_ALGO );
545 RETURNCASE( HYP_HIDING_ALGO );
546 RETURNCASE( HYP_UNKNOWN_FATAL );
547 RETURNCASE( HYP_INCOMPATIBLE );
548 RETURNCASE( HYP_NOTCONFORM );
549 RETURNCASE( HYP_ALREADY_EXIST );
550 RETURNCASE( HYP_BAD_DIM );
551 RETURNCASE( HYP_BAD_SUBSHAPE );
552 RETURNCASE( HYP_BAD_GEOMETRY );
553 RETURNCASE( HYP_NEED_SHAPE );
556 return SMESH::HYP_UNKNOWN_FATAL;
559 //=============================================================================
563 * calls internal addHypothesis() and then adds a reference to <anHyp> under
564 * the SObject actually having a reference to <aSubShape>.
565 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
567 //=============================================================================
569 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
570 SMESH::SMESH_Hypothesis_ptr anHyp)
571 throw(SALOME::SALOME_Exception)
573 Unexpect aCatch(SALOME_SalomeException);
575 _preMeshInfo->ForgetOrLoad();
577 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
579 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
580 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
581 aSubShapeObject, anHyp );
583 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
585 // Update Python script
586 //if(_impl->HasShapeToMesh()) {
587 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
588 << aSubShapeObject << ", " << anHyp << " )";
591 // TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
594 return ConvertHypothesisStatus(status);
597 //=============================================================================
601 //=============================================================================
603 SMESH_Hypothesis::Hypothesis_Status
604 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
605 SMESH::SMESH_Hypothesis_ptr anHyp)
607 if(MYDEBUG) MESSAGE("addHypothesis");
609 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
610 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
613 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
614 if (CORBA::is_nil(myHyp))
615 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
618 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
621 TopoDS_Shape myLocSubShape;
622 //use PseudoShape in case if mesh has no shape
624 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
626 myLocSubShape = _impl->GetShapeToMesh();
628 int hypId = myHyp->GetId();
629 status = _impl->AddHypothesis(myLocSubShape, hypId);
630 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
631 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
632 _mapHypo[hypId]->Register();
633 // assure there is a corresponding submesh
634 if ( !_impl->IsMainShape( myLocSubShape )) {
635 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
636 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
637 createSubMesh( aSubShapeObject );
641 catch(SALOME_Exception & S_ex)
643 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
648 //=============================================================================
652 //=============================================================================
654 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
655 SMESH::SMESH_Hypothesis_ptr anHyp)
656 throw(SALOME::SALOME_Exception)
658 Unexpect aCatch(SALOME_SalomeException);
660 _preMeshInfo->ForgetOrLoad();
662 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
664 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
665 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
666 aSubShapeObject, anHyp );
668 // Update Python script
669 // Update Python script
670 if(_impl->HasShapeToMesh()) {
671 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
672 << aSubShapeObject << ", " << anHyp << " )";
675 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
679 return ConvertHypothesisStatus(status);
682 //=============================================================================
686 //=============================================================================
688 SMESH_Hypothesis::Hypothesis_Status
689 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
690 SMESH::SMESH_Hypothesis_ptr anHyp)
692 if(MYDEBUG) MESSAGE("removeHypothesis()");
693 // **** proposer liste de sub-shape (selection multiple)
695 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
696 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
698 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
699 if (CORBA::is_nil(myHyp))
700 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
702 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
705 TopoDS_Shape myLocSubShape;
706 //use PseudoShape in case if mesh has no shape
708 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
710 myLocSubShape = _impl->GetShapeToMesh();
712 int hypId = myHyp->GetId();
713 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
714 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
715 // _mapHypo.erase( hypId );
717 catch(SALOME_Exception & S_ex)
719 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
724 //=============================================================================
728 //=============================================================================
730 SMESH::ListOfHypothesis *
731 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
732 throw(SALOME::SALOME_Exception)
734 Unexpect aCatch(SALOME_SalomeException);
735 if (MYDEBUG) MESSAGE("GetHypothesisList");
736 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
737 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
739 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
742 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
743 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
744 myLocSubShape = _impl->GetShapeToMesh();
745 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
746 int i = 0, n = aLocalList.size();
749 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
750 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
751 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
752 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
757 catch(SALOME_Exception & S_ex) {
758 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
761 return aList._retn();
764 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
766 Unexpect aCatch(SALOME_SalomeException);
767 if (MYDEBUG) MESSAGE("GetSubMeshes");
769 SMESH::submesh_array_var aList = new SMESH::submesh_array();
772 TPythonDump aPythonDump;
773 if ( !_mapSubMeshIor.empty() )
777 aList->length( _mapSubMeshIor.size() );
779 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
780 for ( ; it != _mapSubMeshIor.end(); it++ ) {
781 if ( CORBA::is_nil( it->second )) continue;
782 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
784 if (i > 1) aPythonDump << ", ";
785 aPythonDump << it->second;
789 catch(SALOME_Exception & S_ex) {
790 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
793 // Update Python script
794 if ( !_mapSubMeshIor.empty() )
795 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
797 return aList._retn();
800 //=============================================================================
804 //=============================================================================
805 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
806 const char* theName )
807 throw(SALOME::SALOME_Exception)
809 Unexpect aCatch(SALOME_SalomeException);
810 MESSAGE("SMESH_Mesh_i::GetSubMesh");
811 if (CORBA::is_nil(aSubShapeObject))
812 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
815 SMESH::SMESH_subMesh_var subMesh;
816 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
818 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
820 //Get or Create the SMESH_subMesh object implementation
822 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
824 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
826 TopoDS_Iterator it( myLocSubShape );
828 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
830 subMesh = getSubMesh( subMeshId );
832 // create a new subMesh object servant if there is none for the shape
833 if ( subMesh->_is_nil() )
834 subMesh = createSubMesh( aSubShapeObject );
835 if ( _gen_i->CanPublishInStudy( subMesh )) {
836 SALOMEDS::SObject_wrap aSO =
837 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
838 subMesh, aSubShapeObject, theName );
839 if ( !aSO->_is_nil()) {
840 // Update Python script
841 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
842 << aSubShapeObject << ", '" << theName << "' )";
846 catch(SALOME_Exception & S_ex) {
847 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
849 return subMesh._retn();
852 //=============================================================================
856 //=============================================================================
858 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
859 throw (SALOME::SALOME_Exception)
863 if ( theSubMesh->_is_nil() )
866 GEOM::GEOM_Object_var aSubShapeObject;
867 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
868 if ( !aStudy->_is_nil() ) {
869 // Remove submesh's SObject
870 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
871 if ( !anSO->_is_nil() ) {
872 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
873 SALOMEDS::SObject_wrap anObj, aRef;
874 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
875 anObj->ReferencedObject( aRef.inout() ))
877 CORBA::Object_var obj = aRef->GetObject();
878 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
880 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
881 // aSubShapeObject = theSubMesh->GetSubShape();
883 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
884 builder->RemoveObjectWithChildren( anSO );
886 // Update Python script
887 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
891 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
893 _preMeshInfo->ForgetOrLoad();
895 SMESH_CATCH( SMESH::throwCorbaException );
898 //=============================================================================
902 //=============================================================================
904 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
905 const char* theName )
906 throw(SALOME::SALOME_Exception)
908 Unexpect aCatch(SALOME_SalomeException);
910 _preMeshInfo->FullLoadFromFile();
912 SMESH::SMESH_Group_var aNewGroup =
913 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
915 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
916 SALOMEDS::SObject_wrap aSO =
917 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
918 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
919 if ( !aSO->_is_nil()) {
920 // Update Python script
921 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
922 << theElemType << ", '" << theName << "' )";
925 return aNewGroup._retn();
929 //=============================================================================
933 //=============================================================================
934 SMESH::SMESH_GroupOnGeom_ptr
935 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
937 GEOM::GEOM_Object_ptr theGeomObj)
938 throw(SALOME::SALOME_Exception)
940 Unexpect aCatch(SALOME_SalomeException);
942 _preMeshInfo->FullLoadFromFile();
944 SMESH::SMESH_GroupOnGeom_var aNewGroup;
946 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
947 if ( !aShape.IsNull() )
949 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
950 ( createGroup( theElemType, theName, aShape ));
952 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
953 SALOMEDS::SObject_wrap aSO =
954 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
955 aNewGroup, theGeomObj, theName);
956 if ( !aSO->_is_nil()) {
957 // Update Python script
958 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
959 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
964 return aNewGroup._retn();
967 //================================================================================
969 * \brief Creates a group whose contents is defined by filter
970 * \param theElemType - group type
971 * \param theName - group name
972 * \param theFilter - the filter
973 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
975 //================================================================================
977 SMESH::SMESH_GroupOnFilter_ptr
978 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
980 SMESH::Filter_ptr theFilter )
981 throw (SALOME::SALOME_Exception)
983 Unexpect aCatch(SALOME_SalomeException);
985 _preMeshInfo->FullLoadFromFile();
987 if ( CORBA::is_nil( theFilter ))
988 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
990 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
992 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
994 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
995 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
998 if ( !aNewGroup->_is_nil() )
999 aNewGroup->SetFilter( theFilter );
1001 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1003 SALOMEDS::SObject_wrap aSO =
1004 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
1005 GEOM::GEOM_Object::_nil(), theName);
1006 if ( !aSO->_is_nil()) {
1007 // Update Python script
1008 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
1009 << theElemType << ", '" << theName << "', " << theFilter << " )";
1013 return aNewGroup._retn();
1016 //=============================================================================
1020 //=============================================================================
1022 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1023 throw (SALOME::SALOME_Exception)
1025 if ( theGroup->_is_nil() )
1030 SMESH_GroupBase_i* aGroup =
1031 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1035 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1036 if ( !aStudy->_is_nil() ) {
1037 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1039 if ( !aGroupSO->_is_nil() ) {
1040 // Update Python script
1041 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
1043 // Remove group's SObject
1044 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1045 builder->RemoveObjectWithChildren( aGroupSO );
1049 // Remove the group from SMESH data structures
1050 removeGroup( aGroup->GetLocalID() );
1052 SMESH_CATCH( SMESH::throwCorbaException );
1055 //=============================================================================
1057 * Remove group with its contents
1059 //=============================================================================
1061 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1062 throw (SALOME::SALOME_Exception)
1066 _preMeshInfo->FullLoadFromFile();
1068 if ( theGroup->_is_nil() )
1071 SMESH_GroupBase_i* aGroup =
1072 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1076 SMESH::long_array_var anIds = aGroup->GetListOfID();
1077 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
1079 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
1082 if ( aGroup->GetType() == SMESH::NODE )
1083 aMeshEditor->RemoveNodes( anIds );
1085 aMeshEditor->RemoveElements( anIds );
1087 // Update Python script (theGroup must be alive for this)
1088 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
1091 RemoveGroup( theGroup );
1093 SMESH_CATCH( SMESH::throwCorbaException );
1096 //================================================================================
1098 * \brief Get the list of groups existing in the mesh
1099 * \retval SMESH::ListOfGroups * - list of groups
1101 //================================================================================
1103 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1105 Unexpect aCatch(SALOME_SalomeException);
1106 if (MYDEBUG) MESSAGE("GetGroups");
1108 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1111 TPythonDump aPythonDump;
1112 if ( !_mapGroups.empty() )
1114 aPythonDump << "[ ";
1116 aList->length( _mapGroups.size() );
1118 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1119 for ( ; it != _mapGroups.end(); it++ ) {
1120 if ( CORBA::is_nil( it->second )) continue;
1121 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1123 if (i > 1) aPythonDump << ", ";
1124 aPythonDump << it->second;
1128 catch(SALOME_Exception & S_ex) {
1129 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1131 aPythonDump << " ] = " << _this() << ".GetGroups()";
1133 return aList._retn();
1136 //=============================================================================
1138 * Get number of groups existing in the mesh
1140 //=============================================================================
1142 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1144 Unexpect aCatch(SALOME_SalomeException);
1145 return _mapGroups.size();
1148 //=============================================================================
1150 * New group is created. All mesh elements that are
1151 * present in initial groups are added to the new one
1153 //=============================================================================
1154 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1155 SMESH::SMESH_GroupBase_ptr theGroup2,
1156 const char* theName )
1157 throw (SALOME::SALOME_Exception)
1159 SMESH::SMESH_Group_var aResGrp;
1163 _preMeshInfo->FullLoadFromFile();
1165 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1166 theGroup1->GetType() != theGroup2->GetType() )
1167 return SMESH::SMESH_Group::_nil();
1172 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1173 if ( aResGrp->_is_nil() )
1174 return SMESH::SMESH_Group::_nil();
1176 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1177 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1179 TColStd_MapOfInteger aResMap;
1181 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1182 aResMap.Add( anIds1[ i1 ] );
1184 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1185 aResMap.Add( anIds2[ i2 ] );
1187 SMESH::long_array_var aResIds = new SMESH::long_array;
1188 aResIds->length( aResMap.Extent() );
1191 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1192 for( ; anIter.More(); anIter.Next() )
1193 aResIds[ resI++ ] = anIter.Key();
1195 aResGrp->Add( aResIds );
1197 // Update Python script
1198 pyDump << aResGrp << " = " << _this() << ".UnionGroups( "
1199 << theGroup1 << ", " << theGroup2 << ", '"
1200 << theName << "' )";
1202 SMESH_CATCH( SMESH::throwCorbaException );
1204 return aResGrp._retn();
1207 //=============================================================================
1209 \brief Union list of groups. New group is created. All mesh elements that are
1210 present in initial groups are added to the new one.
1211 \param theGroups list of groups
1212 \param theName name of group to be created
1213 \return pointer on the group
1215 //=============================================================================
1216 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1217 const char* theName )
1218 throw (SALOME::SALOME_Exception)
1221 _preMeshInfo->FullLoadFromFile();
1224 return SMESH::SMESH_Group::_nil();
1226 SMESH::SMESH_Group_var aResGrp;
1230 vector< int > anIds;
1231 SMESH::ElementType aType = SMESH::ALL;
1232 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1234 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1235 if ( CORBA::is_nil( aGrp ) )
1239 SMESH::ElementType aCurrType = aGrp->GetType();
1240 if ( aType == SMESH::ALL )
1244 if ( aType != aCurrType )
1245 return SMESH::SMESH_Group::_nil();
1249 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1250 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1252 int aCurrId = aCurrIds[ i ];
1253 anIds.push_back( aCurrId );
1260 aResGrp = CreateGroup( aType, theName );
1261 if ( aResGrp->_is_nil() )
1262 return SMESH::SMESH_Group::_nil();
1264 // Create array of identifiers
1265 SMESH::long_array_var aResIds = new SMESH::long_array;
1266 aResIds->length( anIds.size() );
1268 for ( size_t i = 0; i<anIds.size(); i++ )
1269 aResIds[ i ] = anIds[i];
1270 aResGrp->Add( aResIds );
1272 // Update Python script
1273 pyDump << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1274 << &theGroups << ", '" << theName << "' )";
1276 SMESH_CATCH( SMESH::throwCorbaException );
1278 return aResGrp._retn();
1281 //=============================================================================
1283 * New group is created. All mesh elements that are
1284 * present in both initial groups are added to the new one.
1286 //=============================================================================
1287 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1288 SMESH::SMESH_GroupBase_ptr theGroup2,
1289 const char* theName )
1290 throw (SALOME::SALOME_Exception)
1292 SMESH::SMESH_Group_var aResGrp;
1296 _preMeshInfo->FullLoadFromFile();
1298 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1299 theGroup1->GetType() != theGroup2->GetType() )
1300 return SMESH::SMESH_Group::_nil();
1304 // Create Intersection
1305 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1306 if ( aResGrp->_is_nil() )
1309 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1310 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1312 TColStd_MapOfInteger aMap1;
1314 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1315 aMap1.Add( anIds1[ i1 ] );
1317 TColStd_SequenceOfInteger aSeq;
1318 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1319 if ( aMap1.Contains( anIds2[ i2 ] ) )
1320 aSeq.Append( anIds2[ i2 ] );
1322 SMESH::long_array_var aResIds = new SMESH::long_array;
1323 aResIds->length( aSeq.Length() );
1324 for ( size_t resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1325 aResIds[ resI ] = aSeq( resI + 1 );
1326 aResGrp->Add( aResIds );
1328 // Update Python script
1329 pyDump << aResGrp << " = " << _this() << ".IntersectGroups( "
1330 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1332 SMESH_CATCH( SMESH::throwCorbaException );
1334 return aResGrp._retn();
1337 //=============================================================================
1339 \brief Intersect list of groups. New group is created. All mesh elements that
1340 are present in all initial groups simultaneously are added to the new one.
1341 \param theGroups list of groups
1342 \param theName name of group to be created
1343 \return pointer on the group
1345 //=============================================================================
1346 SMESH::SMESH_Group_ptr
1347 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1348 const char* theName )
1349 throw (SALOME::SALOME_Exception)
1351 SMESH::SMESH_Group_var aResGrp;
1355 _preMeshInfo->FullLoadFromFile();
1358 return SMESH::SMESH_Group::_nil();
1360 NCollection_DataMap< int, int > anIdToCount;
1361 SMESH::ElementType aType = SMESH::ALL;
1362 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1364 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1365 if ( CORBA::is_nil( aGrp ) )
1369 SMESH::ElementType aCurrType = aGrp->GetType();
1370 if ( aType == SMESH::ALL )
1374 if ( aType != aCurrType )
1375 return SMESH::SMESH_Group::_nil();
1378 // calculates number of occurance ids in groups
1379 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1380 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1382 int aCurrId = aCurrIds[ i ];
1383 if ( !anIdToCount.IsBound( aCurrId ) )
1384 anIdToCount.Bind( aCurrId, 1 );
1386 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1390 // create map of ids
1391 int nbGrp = theGroups.length();
1392 vector< int > anIds;
1393 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1394 for ( ; anIter.More(); anIter.Next() )
1396 int aCurrId = anIter.Key();
1397 int aCurrNb = anIter.Value();
1398 if ( aCurrNb == nbGrp )
1399 anIds.push_back( aCurrId );
1405 aResGrp = CreateGroup( aType, theName );
1406 if ( aResGrp->_is_nil() )
1407 return SMESH::SMESH_Group::_nil();
1409 // Create array of identifiers
1410 SMESH::long_array_var aResIds = new SMESH::long_array;
1411 aResIds->length( anIds.size() );
1413 for ( size_t i = 0; i<anIds.size(); i++ )
1414 aResIds[ i ] = anIds[i];
1415 aResGrp->Add( aResIds );
1417 // Update Python script
1418 pyDump << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1419 << &theGroups << ", '" << theName << "' )";
1421 SMESH_CATCH( SMESH::throwCorbaException );
1423 return aResGrp._retn();
1426 //=============================================================================
1428 * New group is created. All mesh elements that are present in
1429 * main group but do not present in tool group are added to the new one
1431 //=============================================================================
1432 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1433 SMESH::SMESH_GroupBase_ptr theGroup2,
1434 const char* theName )
1435 throw (SALOME::SALOME_Exception)
1437 SMESH::SMESH_Group_var aResGrp;
1441 _preMeshInfo->FullLoadFromFile();
1443 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1444 theGroup1->GetType() != theGroup2->GetType() )
1445 return SMESH::SMESH_Group::_nil();
1450 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1451 if ( aResGrp->_is_nil() )
1454 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1455 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1457 TColStd_MapOfInteger aMap2;
1459 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1460 aMap2.Add( anIds2[ i2 ] );
1462 TColStd_SequenceOfInteger aSeq;
1463 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1464 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1465 aSeq.Append( anIds1[ i1 ] );
1467 SMESH::long_array_var aResIds = new SMESH::long_array;
1468 aResIds->length( aSeq.Length() );
1470 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1471 aResIds[ resI ] = aSeq( resI + 1 );
1472 aResGrp->Add( aResIds );
1474 // Update Python script
1475 pyDump << aResGrp << " = " << _this() << ".CutGroups( "
1476 << theGroup1 << ", " << theGroup2 << ", '"
1477 << theName << "' )";
1479 SMESH_CATCH( SMESH::throwCorbaException );
1481 return aResGrp._retn();
1484 //=============================================================================
1486 \brief Cut lists of groups. New group is created. All mesh elements that are
1487 present in main groups but do not present in tool groups are added to the new one
1488 \param theMainGroups list of main groups
1489 \param theToolGroups list of tool groups
1490 \param theName name of group to be created
1491 \return pointer on the group
1493 //=============================================================================
1494 SMESH::SMESH_Group_ptr
1495 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1496 const SMESH::ListOfGroups& theToolGroups,
1497 const char* theName )
1498 throw (SALOME::SALOME_Exception)
1500 SMESH::SMESH_Group_var aResGrp;
1504 _preMeshInfo->FullLoadFromFile();
1507 return SMESH::SMESH_Group::_nil();
1509 set< int > aToolIds;
1510 SMESH::ElementType aType = SMESH::ALL;
1512 // iterate through tool groups
1513 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1515 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1516 if ( CORBA::is_nil( aGrp ) )
1520 SMESH::ElementType aCurrType = aGrp->GetType();
1521 if ( aType == SMESH::ALL )
1525 if ( aType != aCurrType )
1526 return SMESH::SMESH_Group::_nil();
1530 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1531 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1533 int aCurrId = aCurrIds[ i ];
1534 aToolIds.insert( aCurrId );
1538 vector< int > anIds; // result
1540 // Iterate through main group
1541 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1543 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1544 if ( CORBA::is_nil( aGrp ) )
1548 SMESH::ElementType aCurrType = aGrp->GetType();
1549 if ( aType == SMESH::ALL )
1553 if ( aType != aCurrType )
1554 return SMESH::SMESH_Group::_nil();
1558 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1559 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1561 int aCurrId = aCurrIds[ i ];
1562 if ( !aToolIds.count( aCurrId ) )
1563 anIds.push_back( aCurrId );
1570 aResGrp = CreateGroup( aType, theName );
1571 if ( aResGrp->_is_nil() )
1572 return SMESH::SMESH_Group::_nil();
1574 // Create array of identifiers
1575 SMESH::long_array_var aResIds = new SMESH::long_array;
1576 aResIds->length( anIds.size() );
1578 for (int i=0; i<anIds.size(); i++ )
1579 aResIds[ i ] = anIds[i];
1580 aResGrp->Add( aResIds );
1582 // Update Python script
1583 pyDump << aResGrp << " = " << _this() << ".CutListOfGroups( "
1584 << &theMainGroups << ", " << &theToolGroups << ", '"
1585 << theName << "' )";
1587 SMESH_CATCH( SMESH::throwCorbaException );
1589 return aResGrp._retn();
1592 //=============================================================================
1594 \brief Create groups of entities from existing groups of superior dimensions
1596 1) extract all nodes from each group,
1597 2) combine all elements of specified dimension laying on these nodes.
1598 \param theGroups list of source groups
1599 \param theElemType dimension of elements
1600 \param theName name of new group
1601 \return pointer on new group
1605 //=============================================================================
1607 SMESH::SMESH_Group_ptr
1608 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1609 SMESH::ElementType theElemType,
1610 const char* theName )
1611 throw (SALOME::SALOME_Exception)
1613 SMESH::SMESH_Group_var aResGrp;
1617 _preMeshInfo->FullLoadFromFile();
1619 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1621 if ( !theName || !aMeshDS )
1622 return SMESH::SMESH_Group::_nil();
1624 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1630 aResGrp = CreateGroup( theElemType, theName );
1631 if ( aResGrp->_is_nil() )
1632 return SMESH::SMESH_Group::_nil();
1634 SMESHDS_GroupBase* groupBaseDS =
1635 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1636 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1638 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1640 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1641 if ( CORBA::is_nil( aGrp ) )
1644 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1645 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1647 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1649 while ( elIt->more() ) {
1650 const SMDS_MeshElement* el = elIt->next();
1651 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1652 while ( nIt->more() )
1653 resGroupCore.Add( nIt->next() );
1656 else // get elements of theElemType based on nodes of every element of group
1658 while ( elIt->more() )
1660 const SMDS_MeshElement* el = elIt->next(); // an element of group
1661 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1662 TIDSortedElemSet checkedElems;
1663 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1664 while ( nIt->more() )
1666 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1667 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1668 // check nodes of elements of theElemType around el
1669 while ( elOfTypeIt->more() )
1671 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1672 if ( !checkedElems.insert( elOfType ).second ) continue;
1674 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1675 bool allNodesOK = true;
1676 while ( nIt2->more() && allNodesOK )
1677 allNodesOK = elNodes.count( nIt2->next() );
1679 resGroupCore.Add( elOfType );
1686 // Update Python script
1687 pyDump << aResGrp << " = " << _this() << ".CreateDimGroup( "
1688 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1690 SMESH_CATCH( SMESH::throwCorbaException );
1692 return aResGrp._retn();
1695 //================================================================================
1697 * \brief Remember GEOM group data
1699 //================================================================================
1701 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1702 CORBA::Object_ptr theSmeshObj)
1704 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1707 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1708 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1709 if ( groupSO->_is_nil() )
1712 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1713 GEOM::GEOM_IGroupOperations_wrap groupOp =
1714 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1715 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1718 _geomGroupData.push_back( TGeomGroupData() );
1719 TGeomGroupData & groupData = _geomGroupData.back();
1721 CORBA::String_var entry = groupSO->GetID();
1722 groupData._groupEntry = entry.in();
1724 for ( int i = 0; i < ids->length(); ++i )
1725 groupData._indices.insert( ids[i] );
1727 groupData._smeshObject = theSmeshObj;
1730 //================================================================================
1732 * Remove GEOM group data relating to removed smesh object
1734 //================================================================================
1736 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1738 list<TGeomGroupData>::iterator
1739 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1740 for ( ; data != dataEnd; ++data ) {
1741 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1742 _geomGroupData.erase( data );
1748 //================================================================================
1750 * \brief Return new group contents if it has been changed and update group data
1752 //================================================================================
1754 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1756 TopoDS_Shape newShape;
1759 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1760 if ( study->_is_nil() ) return newShape; // means "not changed"
1761 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1762 if ( !groupSO->_is_nil() )
1764 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1765 if ( CORBA::is_nil( groupObj )) return newShape;
1766 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1768 // get indices of group items
1769 set<int> curIndices;
1770 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1771 GEOM::GEOM_IGroupOperations_wrap groupOp =
1772 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1773 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1774 for ( int i = 0; i < ids->length(); ++i )
1775 curIndices.insert( ids[i] );
1777 if ( groupData._indices == curIndices )
1778 return newShape; // group not changed
1781 groupData._indices = curIndices;
1783 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1784 if ( !geomClient ) return newShape;
1785 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1786 geomClient->RemoveShapeFromBuffer( groupIOR );
1787 newShape = _gen_i->GeomObjectToShape( geomGroup );
1790 if ( newShape.IsNull() ) {
1791 // geom group becomes empty - return empty compound
1792 TopoDS_Compound compound;
1793 BRep_Builder().MakeCompound(compound);
1794 newShape = compound;
1801 //=============================================================================
1803 * \brief Storage of shape and index used in CheckGeomGroupModif()
1805 //=============================================================================
1806 struct TIndexedShape
1809 TopoDS_Shape _shape;
1810 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1813 //=============================================================================
1815 * \brief Update objects depending on changed geom groups
1817 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1818 * issue 0020210: Update of a smesh group after modification of the associated geom group
1820 //=============================================================================
1822 void SMESH_Mesh_i::CheckGeomGroupModif()
1824 if ( !_impl->HasShapeToMesh() ) return;
1826 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1827 if ( study->_is_nil() ) return;
1829 CORBA::Long nbEntities = NbNodes() + NbElements();
1831 // Check if group contents changed
1833 typedef map< string, TopoDS_Shape > TEntry2Geom;
1834 TEntry2Geom newGroupContents;
1836 list<TGeomGroupData>::iterator
1837 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1838 for ( ; data != dataEnd; ++data )
1840 pair< TEntry2Geom::iterator, bool > it_new =
1841 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1842 bool processedGroup = !it_new.second;
1843 TopoDS_Shape& newShape = it_new.first->second;
1844 if ( !processedGroup )
1845 newShape = newGroupShape( *data );
1846 if ( newShape.IsNull() )
1847 continue; // no changes
1850 _preMeshInfo->ForgetOrLoad();
1852 if ( processedGroup ) { // update group indices
1853 list<TGeomGroupData>::iterator data2 = data;
1854 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1855 data->_indices = data2->_indices;
1858 // Update SMESH objects according to new GEOM group contents
1860 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1861 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1863 int oldID = submesh->GetId();
1864 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1866 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1868 // update hypotheses
1869 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1870 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1871 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1873 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1874 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1876 // care of submeshes
1877 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1878 int newID = newSubmesh->GetId();
1879 if ( newID != oldID ) {
1880 _mapSubMesh [ newID ] = newSubmesh;
1881 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1882 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1883 _mapSubMesh. erase(oldID);
1884 _mapSubMesh_i. erase(oldID);
1885 _mapSubMeshIor.erase(oldID);
1886 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1891 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1892 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1893 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1895 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1897 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1898 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1899 ds->SetShape( newShape );
1904 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1905 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1907 // Remove groups and submeshes basing on removed sub-shapes
1909 TopTools_MapOfShape newShapeMap;
1910 TopoDS_Iterator shapeIt( newShape );
1911 for ( ; shapeIt.More(); shapeIt.Next() )
1912 newShapeMap.Add( shapeIt.Value() );
1914 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1915 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1917 if ( newShapeMap.Contains( shapeIt.Value() ))
1919 TopTools_IndexedMapOfShape oldShapeMap;
1920 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1921 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1923 const TopoDS_Shape& oldShape = oldShapeMap(i);
1924 int oldInd = meshDS->ShapeToIndex( oldShape );
1926 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1927 if ( i_smIor != _mapSubMeshIor.end() ) {
1928 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1931 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1932 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1934 // check if a group bases on oldInd shape
1935 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1936 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1937 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1938 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1940 RemoveGroup( i_grp->second ); // several groups can base on same shape
1941 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1946 // Reassign hypotheses and update groups after setting the new shape to mesh
1948 // collect anassigned hypotheses
1949 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1950 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1951 TShapeHypList assignedHyps;
1952 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1954 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1955 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1956 if ( !hyps.empty() ) {
1957 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1958 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1959 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1962 // collect shapes supporting groups
1963 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1964 TShapeTypeList groupData;
1965 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1966 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1967 for ( ; grIt != groups.end(); ++grIt )
1969 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1971 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1973 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1974 _impl->ShapeToMesh( newShape );
1976 // reassign hypotheses
1977 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1978 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1980 TIndexedShape& geom = indS_hyps->first;
1981 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1982 int oldID = geom._index;
1983 int newID = meshDS->ShapeToIndex( geom._shape );
1984 if ( oldID == 1 ) { // main shape
1986 geom._shape = newShape;
1990 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1991 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1992 // care of submeshes
1993 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1994 if ( newID != oldID ) {
1995 _mapSubMesh [ newID ] = newSubmesh;
1996 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1997 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1998 _mapSubMesh. erase(oldID);
1999 _mapSubMesh_i. erase(oldID);
2000 _mapSubMeshIor.erase(oldID);
2001 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2005 TShapeTypeList::iterator geomType = groupData.begin();
2006 for ( ; geomType != groupData.end(); ++geomType )
2008 const TIndexedShape& geom = geomType->first;
2009 int oldID = geom._index;
2010 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2013 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2014 CORBA::String_var name = groupSO->GetName();
2016 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2018 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2019 group_i->changeLocalId( newID );
2022 break; // everything has been updated
2025 } // loop on group data
2029 CORBA::Long newNbEntities = NbNodes() + NbElements();
2030 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2031 if ( newNbEntities != nbEntities )
2033 // Add all SObjects with icons to soToUpdateIcons
2034 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2036 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2037 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2038 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2040 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2041 i_gr != _mapGroups.end(); ++i_gr ) // groups
2042 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2045 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2046 for ( ; so != soToUpdateIcons.end(); ++so )
2047 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2050 //=============================================================================
2052 * \brief Create standalone group from a group on geometry or filter
2054 //=============================================================================
2056 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2057 throw (SALOME::SALOME_Exception)
2059 SMESH::SMESH_Group_var aGroup;
2064 _preMeshInfo->FullLoadFromFile();
2066 if ( theGroup->_is_nil() )
2067 return aGroup._retn();
2069 SMESH_GroupBase_i* aGroupToRem =
2070 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2072 return aGroup._retn();
2074 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2076 int anId = aGroupToRem->GetLocalID();
2077 if ( !_impl->ConvertToStandalone( anId ) )
2078 return aGroup._retn();
2079 removeGeomGroupData( theGroup );
2081 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2083 // remove old instance of group from own map
2084 _mapGroups.erase( anId );
2086 SALOMEDS::StudyBuilder_var builder;
2087 SALOMEDS::SObject_wrap aGroupSO;
2088 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2089 if ( !aStudy->_is_nil() ) {
2090 builder = aStudy->NewBuilder();
2091 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2092 if ( !aGroupSO->_is_nil() )
2094 // remove reference to geometry
2095 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2096 for ( ; chItr->More(); chItr->Next() )
2097 // Remove group's child SObject
2098 builder->RemoveObject( chItr->Value() );
2100 // Update Python script
2101 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2102 << aGroupSO << " )";
2104 // change icon of Group on Filter
2107 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2108 const int isEmpty = ( elemTypes->length() == 0 );
2111 SALOMEDS::GenericAttribute_wrap anAttr =
2112 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2113 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2114 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2120 // remember new group in own map
2121 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2122 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2124 // register CORBA object for persistence
2125 _gen_i->RegisterObject( aGroup );
2127 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2128 builder->SetIOR( aGroupSO, ior.in() );
2130 SMESH_CATCH( SMESH::throwCorbaException );
2132 return aGroup._retn();
2135 //=============================================================================
2139 //=============================================================================
2141 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2143 if(MYDEBUG) MESSAGE( "createSubMesh" );
2144 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2146 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2147 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2148 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2149 SMESH::SMESH_subMesh_var subMesh
2150 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2152 _mapSubMesh[subMeshId] = mySubMesh;
2153 _mapSubMesh_i[subMeshId] = subMeshServant;
2154 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2156 // register CORBA object for persistence
2157 int nextId = _gen_i->RegisterObject( subMesh );
2158 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2159 else { nextId = 0; } // avoid "unused variable" warning in release mode
2161 // to track changes of GEOM groups
2162 addGeomGroupData( theSubShapeObject, subMesh );
2164 return subMesh._retn();
2167 //=======================================================================
2168 //function : getSubMesh
2170 //=======================================================================
2172 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2174 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2175 if ( it == _mapSubMeshIor.end() )
2176 return SMESH::SMESH_subMesh::_nil();
2178 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2182 //=============================================================================
2186 //=============================================================================
2188 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2189 GEOM::GEOM_Object_ptr theSubShapeObject )
2191 bool isHypChanged = false;
2192 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2193 return isHypChanged;
2195 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2197 CORBA::Long shapeId = theSubMesh->GetId();
2198 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2200 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2203 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2204 isHypChanged = !hyps.empty();
2205 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2206 for ( ; hyp != hyps.end(); ++hyp )
2207 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2214 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2215 isHypChanged = ( aHypList->length() > 0 );
2216 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2217 removeHypothesis( theSubShapeObject, aHypList[i] );
2220 catch( const SALOME::SALOME_Exception& ) {
2221 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2223 removeGeomGroupData( theSubShapeObject );
2225 int subMeshId = theSubMesh->GetId();
2227 _mapSubMesh.erase(subMeshId);
2228 _mapSubMesh_i.erase(subMeshId);
2229 _mapSubMeshIor.erase(subMeshId);
2231 return isHypChanged;
2234 //=============================================================================
2238 //=============================================================================
2240 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2241 const char* theName,
2242 const TopoDS_Shape& theShape,
2243 const SMESH_PredicatePtr& thePredicate )
2245 std::string newName;
2246 if ( !theName || strlen( theName ) == 0 )
2248 std::set< std::string > presentNames;
2249 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2250 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2251 presentNames.insert( i_gr->second->GetName() );
2253 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2254 } while ( !presentNames.insert( newName ).second );
2255 theName = newName.c_str();
2258 SMESH::SMESH_GroupBase_var aGroup;
2259 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2261 SMESH_GroupBase_i* aGroupImpl;
2262 if ( !theShape.IsNull() )
2263 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2264 else if ( thePredicate )
2265 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2267 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2269 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2270 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2272 // register CORBA object for persistence
2273 int nextId = _gen_i->RegisterObject( aGroup );
2274 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2275 else { nextId = 0; } // avoid "unused variable" warning in release mode
2277 // to track changes of GEOM groups
2278 if ( !theShape.IsNull() ) {
2279 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2280 addGeomGroupData( geom, aGroup );
2283 return aGroup._retn();
2286 //=============================================================================
2288 * SMESH_Mesh_i::removeGroup
2290 * Should be called by ~SMESH_Group_i()
2292 //=============================================================================
2294 void SMESH_Mesh_i::removeGroup( const int theId )
2296 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2297 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2298 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2299 _mapGroups.erase( theId );
2300 removeGeomGroupData( group );
2301 if (! _impl->RemoveGroup( theId ))
2303 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2304 RemoveGroup( group );
2309 //=============================================================================
2313 //=============================================================================
2315 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2316 throw(SALOME::SALOME_Exception)
2318 SMESH::log_array_var aLog;
2322 _preMeshInfo->FullLoadFromFile();
2324 list < SMESHDS_Command * >logDS = _impl->GetLog();
2325 aLog = new SMESH::log_array;
2327 int lg = logDS.size();
2330 list < SMESHDS_Command * >::iterator its = logDS.begin();
2331 while(its != logDS.end()){
2332 SMESHDS_Command *com = *its;
2333 int comType = com->GetType();
2335 int lgcom = com->GetNumber();
2337 const list < int >&intList = com->GetIndexes();
2338 int inum = intList.size();
2340 list < int >::const_iterator ii = intList.begin();
2341 const list < double >&coordList = com->GetCoords();
2342 int rnum = coordList.size();
2344 list < double >::const_iterator ir = coordList.begin();
2345 aLog[indexLog].commandType = comType;
2346 aLog[indexLog].number = lgcom;
2347 aLog[indexLog].coords.length(rnum);
2348 aLog[indexLog].indexes.length(inum);
2349 for(int i = 0; i < rnum; i++){
2350 aLog[indexLog].coords[i] = *ir;
2351 //MESSAGE(" "<<i<<" "<<ir.Value());
2354 for(int i = 0; i < inum; i++){
2355 aLog[indexLog].indexes[i] = *ii;
2356 //MESSAGE(" "<<i<<" "<<ii.Value());
2365 SMESH_CATCH( SMESH::throwCorbaException );
2367 return aLog._retn();
2371 //=============================================================================
2375 //=============================================================================
2377 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2381 SMESH_CATCH( SMESH::throwCorbaException );
2384 //=============================================================================
2388 //=============================================================================
2390 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2395 //=============================================================================
2399 //=============================================================================
2401 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2406 //=============================================================================
2409 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2410 // issue 0020918: groups removal is caused by hyp modification
2411 // issue 0021208: to forget not loaded mesh data at hyp modification
2412 struct TCallUp_i : public SMESH_Mesh::TCallUp
2414 SMESH_Mesh_i* _mesh;
2415 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2416 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2417 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2418 virtual void Load () { _mesh->Load(); }
2422 //================================================================================
2424 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2426 //================================================================================
2428 void SMESH_Mesh_i::onHypothesisModified()
2431 _preMeshInfo->ForgetOrLoad();
2434 //=============================================================================
2438 //=============================================================================
2440 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2442 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2445 _impl->SetCallUp( new TCallUp_i(this));
2448 //=============================================================================
2452 //=============================================================================
2454 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2456 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2460 //=============================================================================
2462 * Return mesh editor
2464 //=============================================================================
2466 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2467 throw (SALOME::SALOME_Exception)
2469 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2473 _preMeshInfo->FullLoadFromFile();
2475 // Create MeshEditor
2476 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2477 aMeshEdVar = aMeshEditor->_this();
2479 // Update Python script
2480 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2482 SMESH_CATCH( SMESH::throwCorbaException );
2484 return aMeshEdVar._retn();
2487 //=============================================================================
2489 * Return mesh edition previewer
2491 //=============================================================================
2493 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2494 throw (SALOME::SALOME_Exception)
2496 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2500 _preMeshInfo->FullLoadFromFile();
2502 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2503 aMeshEdVar = aMeshEditor->_this();
2505 SMESH_CATCH( SMESH::throwCorbaException );
2507 return aMeshEdVar._retn();
2510 //================================================================================
2512 * \brief Return true if the mesh has been edited since a last total re-compute
2513 * and those modifications may prevent successful partial re-compute
2515 //================================================================================
2517 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2519 Unexpect aCatch(SALOME_SalomeException);
2520 return _impl->HasModificationsToDiscard();
2523 //================================================================================
2525 * \brief Returns a random unique color
2527 //================================================================================
2529 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2531 const int MAX_ATTEMPTS = 100;
2533 double tolerance = 0.5;
2534 SALOMEDS::Color col;
2538 // generate random color
2539 double red = (double)rand() / RAND_MAX;
2540 double green = (double)rand() / RAND_MAX;
2541 double blue = (double)rand() / RAND_MAX;
2542 // check existence in the list of the existing colors
2543 bool matched = false;
2544 std::list<SALOMEDS::Color>::const_iterator it;
2545 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2546 SALOMEDS::Color color = *it;
2547 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2548 matched = tol < tolerance;
2550 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2551 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2559 //=============================================================================
2561 * Sets auto-color mode. If it is on, groups get unique random colors
2563 //=============================================================================
2565 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2567 Unexpect aCatch(SALOME_SalomeException);
2568 _impl->SetAutoColor(theAutoColor);
2570 TPythonDump pyDump; // not to dump group->SetColor() from below code
2571 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2573 std::list<SALOMEDS::Color> aReservedColors;
2574 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2575 for ( ; it != _mapGroups.end(); it++ ) {
2576 if ( CORBA::is_nil( it->second )) continue;
2577 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2578 it->second->SetColor( aColor );
2579 aReservedColors.push_back( aColor );
2583 //=============================================================================
2585 * Returns true if auto-color mode is on
2587 //=============================================================================
2589 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2591 Unexpect aCatch(SALOME_SalomeException);
2592 return _impl->GetAutoColor();
2595 //=============================================================================
2597 * Checks if there are groups with equal names
2599 //=============================================================================
2601 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2603 return _impl->HasDuplicatedGroupNamesMED();
2606 //================================================================================
2608 * \brief Care of a file before exporting mesh into it
2610 //================================================================================
2612 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2614 TCollection_AsciiString aFullName ((char*)file);
2615 OSD_Path aPath (aFullName);
2616 OSD_File aFile (aPath);
2617 if (aFile.Exists()) {
2618 // existing filesystem node
2619 if (aFile.KindOfFile() == OSD_FILE) {
2620 if (aFile.IsWriteable()) {
2625 if (aFile.Failed()) {
2626 TCollection_AsciiString msg ("File ");
2627 msg += aFullName + " cannot be replaced.";
2628 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2631 TCollection_AsciiString msg ("File ");
2632 msg += aFullName + " cannot be overwritten.";
2633 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2636 TCollection_AsciiString msg ("Location ");
2637 msg += aFullName + " is not a file.";
2638 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2641 // nonexisting file; check if it can be created
2643 aFile.Build(OSD_WriteOnly, OSD_Protection());
2644 if (aFile.Failed()) {
2645 TCollection_AsciiString msg ("You cannot create the file ");
2646 msg += aFullName + ". Check the directory existance and access rights.";
2647 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2655 //================================================================================
2657 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2658 * \param file - file name
2659 * \param overwrite - to erase the file or not
2660 * \retval string - mesh name
2662 //================================================================================
2664 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2665 CORBA::Boolean overwrite)
2668 PrepareForWriting(file, overwrite);
2669 string aMeshName = "Mesh";
2670 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2671 if ( !aStudy->_is_nil() ) {
2672 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2673 if ( !aMeshSO->_is_nil() ) {
2674 CORBA::String_var name = aMeshSO->GetName();
2676 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2677 if ( !aStudy->GetProperties()->IsLocked() )
2679 SALOMEDS::GenericAttribute_wrap anAttr;
2680 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2681 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2682 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2683 ASSERT(!aFileName->_is_nil());
2684 aFileName->SetValue(file);
2685 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2686 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2687 ASSERT(!aFileType->_is_nil());
2688 aFileType->SetValue("FICHIERMED");
2692 // Update Python script
2693 // set name of mesh before export
2694 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2696 // check names of groups
2702 //================================================================================
2704 * \brief Export to med file
2706 //================================================================================
2708 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2709 CORBA::Boolean auto_groups,
2710 SMESH::MED_VERSION theVersion,
2711 CORBA::Boolean overwrite,
2712 CORBA::Boolean autoDimension)
2713 throw(SALOME::SALOME_Exception)
2715 Unexpect aCatch(SALOME_SalomeException);
2717 _preMeshInfo->FullLoadFromFile();
2719 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2720 TPythonDump() << _this() << ".ExportToMEDX( r'"
2721 << file << "', " << auto_groups << ", "
2722 << theVersion << ", " << overwrite << ", "
2723 << autoDimension << " )";
2725 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2728 //================================================================================
2730 * \brief Export a mesh to a med file
2732 //================================================================================
2734 void SMESH_Mesh_i::ExportToMED (const char* file,
2735 CORBA::Boolean auto_groups,
2736 SMESH::MED_VERSION theVersion)
2737 throw(SALOME::SALOME_Exception)
2739 ExportToMEDX(file,auto_groups,theVersion,true);
2742 //================================================================================
2744 * \brief Export a mesh to a med file
2746 //================================================================================
2748 void SMESH_Mesh_i::ExportMED (const char* file,
2749 CORBA::Boolean auto_groups)
2750 throw(SALOME::SALOME_Exception)
2752 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2755 //================================================================================
2757 * \brief Export a mesh to a SAUV file
2759 //================================================================================
2761 void SMESH_Mesh_i::ExportSAUV (const char* file,
2762 CORBA::Boolean auto_groups)
2763 throw(SALOME::SALOME_Exception)
2765 Unexpect aCatch(SALOME_SalomeException);
2767 _preMeshInfo->FullLoadFromFile();
2769 string aMeshName = prepareMeshNameAndGroups(file, true);
2770 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2771 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2775 //================================================================================
2777 * \brief Export a mesh to a DAT file
2779 //================================================================================
2781 void SMESH_Mesh_i::ExportDAT (const char *file)
2782 throw(SALOME::SALOME_Exception)
2784 Unexpect aCatch(SALOME_SalomeException);
2786 _preMeshInfo->FullLoadFromFile();
2788 // Update Python script
2789 // check names of groups
2791 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2794 PrepareForWriting(file);
2795 _impl->ExportDAT(file);
2798 //================================================================================
2800 * \brief Export a mesh to an UNV file
2802 //================================================================================
2804 void SMESH_Mesh_i::ExportUNV (const char *file)
2805 throw(SALOME::SALOME_Exception)
2807 Unexpect aCatch(SALOME_SalomeException);
2809 _preMeshInfo->FullLoadFromFile();
2811 // Update Python script
2812 // check names of groups
2814 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2817 PrepareForWriting(file);
2818 _impl->ExportUNV(file);
2821 //================================================================================
2823 * \brief Export a mesh to an STL file
2825 //================================================================================
2827 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2828 throw(SALOME::SALOME_Exception)
2830 Unexpect aCatch(SALOME_SalomeException);
2832 _preMeshInfo->FullLoadFromFile();
2834 // Update Python script
2835 // check names of groups
2837 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2840 PrepareForWriting(file);
2841 _impl->ExportSTL(file, isascii);
2844 //================================================================================
2846 * \brief Export a part of mesh to a med file
2848 //================================================================================
2850 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2852 CORBA::Boolean auto_groups,
2853 ::SMESH::MED_VERSION version,
2854 ::CORBA::Boolean overwrite,
2855 ::CORBA::Boolean autoDimension)
2856 throw (SALOME::SALOME_Exception)
2858 Unexpect aCatch(SALOME_SalomeException);
2861 if ( SMESH_Mesh_i * mesh = SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
2863 mesh->ExportToMEDX( file, auto_groups, version, autoDimension );
2868 _preMeshInfo->FullLoadFromFile();
2870 PrepareForWriting(file, overwrite);
2872 string aMeshName = "Mesh";
2873 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2874 if ( !aStudy->_is_nil() ) {
2875 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2876 if ( !SO->_is_nil() ) {
2877 CORBA::String_var name = SO->GetName();
2881 SMESH_MeshPartDS partDS( meshPart );
2882 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS, autoDimension );
2884 pyDump << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2885 << auto_groups << ", " << version << ", " << overwrite << ", "
2886 << autoDimension << " )";
2889 //================================================================================
2891 * \brief Export a part of mesh to a DAT file
2893 //================================================================================
2895 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2897 throw (SALOME::SALOME_Exception)
2899 Unexpect aCatch(SALOME_SalomeException);
2901 _preMeshInfo->FullLoadFromFile();
2903 PrepareForWriting(file);
2905 SMESH_MeshPartDS partDS( meshPart );
2906 _impl->ExportDAT(file,&partDS);
2908 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2910 //================================================================================
2912 * \brief Export a part of mesh to an UNV file
2914 //================================================================================
2916 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2918 throw (SALOME::SALOME_Exception)
2920 Unexpect aCatch(SALOME_SalomeException);
2922 _preMeshInfo->FullLoadFromFile();
2924 PrepareForWriting(file);
2926 SMESH_MeshPartDS partDS( meshPart );
2927 _impl->ExportUNV(file, &partDS);
2929 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2931 //================================================================================
2933 * \brief Export a part of mesh to an STL file
2935 //================================================================================
2937 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2939 ::CORBA::Boolean isascii)
2940 throw (SALOME::SALOME_Exception)
2942 Unexpect aCatch(SALOME_SalomeException);
2944 _preMeshInfo->FullLoadFromFile();
2946 PrepareForWriting(file);
2948 SMESH_MeshPartDS partDS( meshPart );
2949 _impl->ExportSTL(file, isascii, &partDS);
2951 TPythonDump() << _this() << ".ExportPartToSTL( "
2952 << meshPart<< ", r'" << file << "', " << isascii << ")";
2955 //================================================================================
2957 * \brief Export a part of mesh to an STL file
2959 //================================================================================
2961 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2963 CORBA::Boolean overwrite)
2964 throw (SALOME::SALOME_Exception)
2967 Unexpect aCatch(SALOME_SalomeException);
2969 _preMeshInfo->FullLoadFromFile();
2971 PrepareForWriting(file,overwrite);
2973 SMESH_MeshPartDS partDS( meshPart );
2974 _impl->ExportCGNS(file, &partDS);
2976 TPythonDump() << _this() << ".ExportCGNS( "
2977 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2979 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2983 //================================================================================
2985 * \brief Export a part of mesh to a GMF file
2987 //================================================================================
2989 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
2991 bool withRequiredGroups)
2992 throw (SALOME::SALOME_Exception)
2994 Unexpect aCatch(SALOME_SalomeException);
2996 _preMeshInfo->FullLoadFromFile();
2998 PrepareForWriting(file,/*overwrite=*/true);
3000 SMESH_MeshPartDS partDS( meshPart );
3001 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3003 TPythonDump() << _this() << ".ExportGMF( "
3004 << meshPart<< ", r'"
3006 << withRequiredGroups << ")";
3009 //=============================================================================
3011 * Return implementation of SALOME_MED::MESH interfaces
3013 //=============================================================================
3015 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
3017 Unexpect aCatch(SALOME_SalomeException);
3019 _preMeshInfo->FullLoadFromFile();
3021 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
3022 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
3023 return aMesh._retn();
3026 //=============================================================================
3028 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3030 Unexpect aCatch(SALOME_SalomeException);
3032 return _preMeshInfo->NbNodes();
3034 return _impl->NbNodes();
3037 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3039 Unexpect aCatch(SALOME_SalomeException);
3041 return _preMeshInfo->NbElements();
3043 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3046 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3048 Unexpect aCatch(SALOME_SalomeException);
3050 return _preMeshInfo->Nb0DElements();
3052 return _impl->Nb0DElements();
3055 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3057 Unexpect aCatch(SALOME_SalomeException);
3059 return _preMeshInfo->NbBalls();
3061 return _impl->NbBalls();
3064 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3066 Unexpect aCatch(SALOME_SalomeException);
3068 return _preMeshInfo->NbEdges();
3070 return _impl->NbEdges();
3073 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3074 throw(SALOME::SALOME_Exception)
3076 Unexpect aCatch(SALOME_SalomeException);
3078 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3080 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3083 //=============================================================================
3085 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3087 Unexpect aCatch(SALOME_SalomeException);
3089 return _preMeshInfo->NbFaces();
3091 return _impl->NbFaces();
3094 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3096 Unexpect aCatch(SALOME_SalomeException);
3098 return _preMeshInfo->NbTriangles();
3100 return _impl->NbTriangles();
3103 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3105 Unexpect aCatch(SALOME_SalomeException);
3107 return _preMeshInfo->NbBiQuadTriangles();
3109 return _impl->NbBiQuadTriangles();
3112 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3114 Unexpect aCatch(SALOME_SalomeException);
3116 return _preMeshInfo->NbQuadrangles();
3118 return _impl->NbQuadrangles();
3121 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3123 Unexpect aCatch(SALOME_SalomeException);
3125 return _preMeshInfo->NbBiQuadQuadrangles();
3127 return _impl->NbBiQuadQuadrangles();
3130 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3132 Unexpect aCatch(SALOME_SalomeException);
3134 return _preMeshInfo->NbPolygons();
3136 return _impl->NbPolygons();
3139 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3140 throw(SALOME::SALOME_Exception)
3142 Unexpect aCatch(SALOME_SalomeException);
3144 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3146 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3149 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3150 throw(SALOME::SALOME_Exception)
3152 Unexpect aCatch(SALOME_SalomeException);
3154 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3156 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3159 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3160 throw(SALOME::SALOME_Exception)
3162 Unexpect aCatch(SALOME_SalomeException);
3164 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3166 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3169 //=============================================================================
3171 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3173 Unexpect aCatch(SALOME_SalomeException);
3175 return _preMeshInfo->NbVolumes();
3177 return _impl->NbVolumes();
3180 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3182 Unexpect aCatch(SALOME_SalomeException);
3184 return _preMeshInfo->NbTetras();
3186 return _impl->NbTetras();
3189 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3191 Unexpect aCatch(SALOME_SalomeException);
3193 return _preMeshInfo->NbHexas();
3195 return _impl->NbHexas();
3198 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3200 Unexpect aCatch(SALOME_SalomeException);
3202 return _preMeshInfo->NbTriQuadHexas();
3204 return _impl->NbTriQuadraticHexas();
3207 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3209 Unexpect aCatch(SALOME_SalomeException);
3211 return _preMeshInfo->NbPyramids();
3213 return _impl->NbPyramids();
3216 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3218 Unexpect aCatch(SALOME_SalomeException);
3220 return _preMeshInfo->NbPrisms();
3222 return _impl->NbPrisms();
3225 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3227 Unexpect aCatch(SALOME_SalomeException);
3229 return _preMeshInfo->NbHexPrisms();
3231 return _impl->NbHexagonalPrisms();
3234 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3236 Unexpect aCatch(SALOME_SalomeException);
3238 return _preMeshInfo->NbPolyhedrons();
3240 return _impl->NbPolyhedrons();
3243 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3244 throw(SALOME::SALOME_Exception)
3246 Unexpect aCatch(SALOME_SalomeException);
3248 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3250 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3253 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3254 throw(SALOME::SALOME_Exception)
3256 Unexpect aCatch(SALOME_SalomeException);
3258 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3260 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3263 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3264 throw(SALOME::SALOME_Exception)
3266 Unexpect aCatch(SALOME_SalomeException);
3268 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3270 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3273 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3274 throw(SALOME::SALOME_Exception)
3276 Unexpect aCatch(SALOME_SalomeException);
3278 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3280 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3283 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3284 throw(SALOME::SALOME_Exception)
3286 Unexpect aCatch(SALOME_SalomeException);
3288 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3290 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3293 //=============================================================================
3295 * Returns nb of published sub-meshes
3297 //=============================================================================
3299 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3301 Unexpect aCatch(SALOME_SalomeException);
3302 return _mapSubMesh_i.size();
3305 //=============================================================================
3307 * Dumps mesh into a string
3309 //=============================================================================
3311 char* SMESH_Mesh_i::Dump()
3315 return CORBA::string_dup( os.str().c_str() );
3318 //=============================================================================
3320 * Method of SMESH_IDSource interface
3322 //=============================================================================
3324 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3326 return GetElementsId();
3329 //=============================================================================
3331 * Returns ids of all elements
3333 //=============================================================================
3335 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3336 throw (SALOME::SALOME_Exception)
3338 Unexpect aCatch(SALOME_SalomeException);
3340 _preMeshInfo->FullLoadFromFile();
3342 SMESH::long_array_var aResult = new SMESH::long_array();
3343 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3345 if ( aSMESHDS_Mesh == NULL )
3346 return aResult._retn();
3348 long nbElements = NbElements();
3349 aResult->length( nbElements );
3350 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3351 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3352 aResult[i] = anIt->next()->GetID();
3354 return aResult._retn();
3358 //=============================================================================
3360 * Returns ids of all elements of given type
3362 //=============================================================================
3364 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3365 throw (SALOME::SALOME_Exception)
3367 Unexpect aCatch(SALOME_SalomeException);
3369 _preMeshInfo->FullLoadFromFile();
3371 SMESH::long_array_var aResult = new SMESH::long_array();
3372 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3374 if ( aSMESHDS_Mesh == NULL )
3375 return aResult._retn();
3377 long nbElements = NbElements();
3379 // No sense in returning ids of elements along with ids of nodes:
3380 // when theElemType == SMESH::ALL, return node ids only if
3381 // there are no elements
3382 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3383 return GetNodesId();
3385 aResult->length( nbElements );
3389 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3390 while ( i < nbElements && anIt->more() ) {
3391 const SMDS_MeshElement* anElem = anIt->next();
3392 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3393 aResult[i++] = anElem->GetID();
3396 aResult->length( i );
3398 return aResult._retn();
3401 //=============================================================================
3403 * Returns ids of all nodes
3405 //=============================================================================
3407 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3408 throw (SALOME::SALOME_Exception)
3410 Unexpect aCatch(SALOME_SalomeException);
3412 _preMeshInfo->FullLoadFromFile();
3414 SMESH::long_array_var aResult = new SMESH::long_array();
3415 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3417 if ( aSMESHDS_Mesh == NULL )
3418 return aResult._retn();
3420 long nbNodes = NbNodes();
3421 aResult->length( nbNodes );
3422 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3423 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3424 aResult[i] = anIt->next()->GetID();
3426 return aResult._retn();
3429 //=============================================================================
3433 //=============================================================================
3435 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3436 throw (SALOME::SALOME_Exception)
3438 SMESH::ElementType type;
3442 _preMeshInfo->FullLoadFromFile();
3444 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3446 SMESH_CATCH( SMESH::throwCorbaException );
3451 //=============================================================================
3455 //=============================================================================
3457 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3458 throw (SALOME::SALOME_Exception)
3461 _preMeshInfo->FullLoadFromFile();
3463 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3465 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3467 return ( SMESH::EntityType ) e->GetEntityType();
3470 //=============================================================================
3472 * Returns ID of elements for given submesh
3474 //=============================================================================
3475 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3476 throw (SALOME::SALOME_Exception)
3478 SMESH::long_array_var aResult = new SMESH::long_array();
3482 _preMeshInfo->FullLoadFromFile();
3484 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3485 if(!SM) return aResult._retn();
3487 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3488 if(!SDSM) return aResult._retn();
3490 aResult->length(SDSM->NbElements());
3492 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3494 while ( eIt->more() ) {
3495 aResult[i++] = eIt->next()->GetID();
3498 SMESH_CATCH( SMESH::throwCorbaException );
3500 return aResult._retn();
3504 //=============================================================================
3506 * Returns ID of nodes for given submesh
3507 * If param all==true - returns all nodes, else -
3508 * returns only nodes on shapes.
3510 //=============================================================================
3511 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3513 throw (SALOME::SALOME_Exception)
3515 SMESH::long_array_var aResult = new SMESH::long_array();
3519 _preMeshInfo->FullLoadFromFile();
3521 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3522 if(!SM) return aResult._retn();
3524 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3525 if(!SDSM) return aResult._retn();
3528 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3529 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3530 while ( nIt->more() ) {
3531 const SMDS_MeshNode* elem = nIt->next();
3532 theElems.insert( elem->GetID() );
3535 else { // all nodes of submesh elements
3536 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3537 while ( eIt->more() ) {
3538 const SMDS_MeshElement* anElem = eIt->next();
3539 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3540 while ( nIt->more() ) {
3541 const SMDS_MeshElement* elem = nIt->next();
3542 theElems.insert( elem->GetID() );
3547 aResult->length(theElems.size());
3548 set<int>::iterator itElem;
3550 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3551 aResult[i++] = *itElem;
3553 SMESH_CATCH( SMESH::throwCorbaException );
3555 return aResult._retn();
3558 //=============================================================================
3560 * Returns type of elements for given submesh
3562 //=============================================================================
3564 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3565 throw (SALOME::SALOME_Exception)
3567 SMESH::ElementType type;
3571 _preMeshInfo->FullLoadFromFile();
3573 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3574 if(!SM) return SMESH::ALL;
3576 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3577 if(!SDSM) return SMESH::ALL;
3579 if(SDSM->NbElements()==0)
3580 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3582 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3583 const SMDS_MeshElement* anElem = eIt->next();
3585 type = ( SMESH::ElementType ) anElem->GetType();
3587 SMESH_CATCH( SMESH::throwCorbaException );
3593 //=============================================================================
3595 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3597 //=============================================================================
3599 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3602 _preMeshInfo->FullLoadFromFile();
3604 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3606 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3611 //=============================================================================
3613 * Get XYZ coordinates of node as list of double
3614 * If there is not node for given ID - returns empty list
3616 //=============================================================================
3618 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3621 _preMeshInfo->FullLoadFromFile();
3623 SMESH::double_array_var aResult = new SMESH::double_array();
3624 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3625 if ( aSMESHDS_Mesh == NULL )
3626 return aResult._retn();
3629 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3631 return aResult._retn();
3635 aResult[0] = aNode->X();
3636 aResult[1] = aNode->Y();
3637 aResult[2] = aNode->Z();
3638 return aResult._retn();
3642 //=============================================================================
3644 * For given node returns list of IDs of inverse elements
3645 * If there is not node for given ID - returns empty list
3647 //=============================================================================
3649 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3652 _preMeshInfo->FullLoadFromFile();
3654 SMESH::long_array_var aResult = new SMESH::long_array();
3655 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3656 if ( aSMESHDS_Mesh == NULL )
3657 return aResult._retn();
3660 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3662 return aResult._retn();
3664 // find inverse elements
3665 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3666 TColStd_SequenceOfInteger IDs;
3667 while(eIt->more()) {
3668 const SMDS_MeshElement* elem = eIt->next();
3669 IDs.Append(elem->GetID());
3671 if(IDs.Length()>0) {
3672 aResult->length(IDs.Length());
3674 for(; i<=IDs.Length(); i++) {
3675 aResult[i-1] = IDs.Value(i);
3678 return aResult._retn();
3681 //=============================================================================
3683 * \brief Return position of a node on shape
3685 //=============================================================================
3687 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3690 _preMeshInfo->FullLoadFromFile();
3692 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3693 aNodePosition->shapeID = 0;
3694 aNodePosition->shapeType = GEOM::SHAPE;
3696 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3697 if ( !mesh ) return aNodePosition;
3699 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3701 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3703 aNodePosition->shapeID = aNode->getshapeId();
3704 switch ( pos->GetTypeOfPosition() ) {
3706 aNodePosition->shapeType = GEOM::EDGE;
3707 aNodePosition->params.length(1);
3708 aNodePosition->params[0] =
3709 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3712 aNodePosition->shapeType = GEOM::FACE;
3713 aNodePosition->params.length(2);
3714 aNodePosition->params[0] =
3715 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3716 aNodePosition->params[1] =
3717 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3719 case SMDS_TOP_VERTEX:
3720 aNodePosition->shapeType = GEOM::VERTEX;
3722 case SMDS_TOP_3DSPACE:
3723 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3724 aNodePosition->shapeType = GEOM::SOLID;
3725 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3726 aNodePosition->shapeType = GEOM::SHELL;
3732 return aNodePosition;
3735 //=============================================================================
3737 * \brief Return position of an element on shape
3739 //=============================================================================
3741 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
3744 _preMeshInfo->FullLoadFromFile();
3746 SMESH::ElementPosition anElementPosition;
3747 anElementPosition.shapeID = 0;
3748 anElementPosition.shapeType = GEOM::SHAPE;
3750 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3751 if ( !mesh ) return anElementPosition;
3753 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
3755 anElementPosition.shapeID = anElem->getshapeId();
3756 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
3757 if ( !aSp.IsNull() ) {
3758 switch ( aSp.ShapeType() ) {
3760 anElementPosition.shapeType = GEOM::EDGE;
3763 anElementPosition.shapeType = GEOM::FACE;
3766 anElementPosition.shapeType = GEOM::VERTEX;
3769 anElementPosition.shapeType = GEOM::SOLID;
3772 anElementPosition.shapeType = GEOM::SHELL;
3778 return anElementPosition;
3781 //=============================================================================
3783 * If given element is node returns IDs of shape from position
3784 * If there is not node for given ID - returns -1
3786 //=============================================================================
3788 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3791 _preMeshInfo->FullLoadFromFile();
3793 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3794 if ( aSMESHDS_Mesh == NULL )
3798 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3800 return aNode->getshapeId();
3807 //=============================================================================
3809 * For given element returns ID of result shape after
3810 * ::FindShape() from SMESH_MeshEditor
3811 * If there is not element for given ID - returns -1
3813 //=============================================================================
3815 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3818 _preMeshInfo->FullLoadFromFile();
3820 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3821 if ( aSMESHDS_Mesh == NULL )
3824 // try to find element
3825 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3829 ::SMESH_MeshEditor aMeshEditor(_impl);
3830 int index = aMeshEditor.FindShape( elem );
3838 //=============================================================================
3840 * Returns number of nodes for given element
3841 * If there is not element for given ID - returns -1
3843 //=============================================================================
3845 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3848 _preMeshInfo->FullLoadFromFile();
3850 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3851 if ( aSMESHDS_Mesh == NULL ) return -1;
3852 // try to find element
3853 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3854 if(!elem) return -1;
3855 return elem->NbNodes();
3859 //=============================================================================
3861 * Returns ID of node by given index for given element
3862 * If there is not element for given ID - returns -1
3863 * If there is not node for given index - returns -2
3865 //=============================================================================
3867 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3870 _preMeshInfo->FullLoadFromFile();
3872 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3873 if ( aSMESHDS_Mesh == NULL ) return -1;
3874 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3875 if(!elem) return -1;
3876 if( index>=elem->NbNodes() || index<0 ) return -1;
3877 return elem->GetNode(index)->GetID();
3880 //=============================================================================
3882 * Returns IDs of nodes of given element
3884 //=============================================================================
3886 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3889 _preMeshInfo->FullLoadFromFile();
3891 SMESH::long_array_var aResult = new SMESH::long_array();
3892 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3894 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3896 aResult->length( elem->NbNodes() );
3897 for ( int i = 0; i < elem->NbNodes(); ++i )
3898 aResult[ i ] = elem->GetNode( i )->GetID();
3901 return aResult._retn();
3904 //=============================================================================
3906 * Returns true if given node is medium node
3907 * in given quadratic element
3909 //=============================================================================
3911 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3914 _preMeshInfo->FullLoadFromFile();
3916 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3917 if ( aSMESHDS_Mesh == NULL ) return false;
3919 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3920 if(!aNode) return false;
3921 // try to find element
3922 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3923 if(!elem) return false;
3925 return elem->IsMediumNode(aNode);
3929 //=============================================================================
3931 * Returns true if given node is medium node
3932 * in one of quadratic elements
3934 //=============================================================================
3936 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3937 SMESH::ElementType theElemType)
3940 _preMeshInfo->FullLoadFromFile();
3942 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3943 if ( aSMESHDS_Mesh == NULL ) return false;
3946 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3947 if(!aNode) return false;
3949 SMESH_MesherHelper aHelper( *(_impl) );
3951 SMDSAbs_ElementType aType;
3952 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3953 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3954 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3955 else aType = SMDSAbs_All;
3957 return aHelper.IsMedium(aNode,aType);
3961 //=============================================================================
3963 * Returns number of edges for given element
3965 //=============================================================================
3967 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3970 _preMeshInfo->FullLoadFromFile();
3972 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3973 if ( aSMESHDS_Mesh == NULL ) return -1;
3974 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3975 if(!elem) return -1;
3976 return elem->NbEdges();
3980 //=============================================================================
3982 * Returns number of faces for given element
3984 //=============================================================================
3986 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3989 _preMeshInfo->FullLoadFromFile();
3991 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3992 if ( aSMESHDS_Mesh == NULL ) return -1;
3993 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3994 if(!elem) return -1;
3995 return elem->NbFaces();
3998 //=======================================================================
3999 //function : GetElemFaceNodes
4000 //purpose : Returns nodes of given face (counted from zero) for given element.
4001 //=======================================================================
4003 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4004 CORBA::Short faceIndex)
4007 _preMeshInfo->FullLoadFromFile();
4009 SMESH::long_array_var aResult = new SMESH::long_array();
4010 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4012 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4014 SMDS_VolumeTool vtool( elem );
4015 if ( faceIndex < vtool.NbFaces() )
4017 aResult->length( vtool.NbFaceNodes( faceIndex ));
4018 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4019 for ( int i = 0; i < aResult->length(); ++i )
4020 aResult[ i ] = nn[ i ]->GetID();
4024 return aResult._retn();
4027 //=======================================================================
4028 //function : FindElementByNodes
4029 //purpose : Returns an element based on all given nodes.
4030 //=======================================================================
4032 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4035 _preMeshInfo->FullLoadFromFile();
4037 CORBA::Long elemID(0);
4038 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4040 vector< const SMDS_MeshNode * > nn( nodes.length() );
4041 for ( int i = 0; i < nodes.length(); ++i )
4042 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4045 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4046 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4047 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4048 _impl->NbVolumes( ORDER_QUADRATIC )))
4049 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4051 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4056 //=============================================================================
4058 * Returns true if given element is polygon
4060 //=============================================================================
4062 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4065 _preMeshInfo->FullLoadFromFile();
4067 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4068 if ( aSMESHDS_Mesh == NULL ) return false;
4069 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4070 if(!elem) return false;
4071 return elem->IsPoly();
4075 //=============================================================================
4077 * Returns true if given element is quadratic
4079 //=============================================================================
4081 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4084 _preMeshInfo->FullLoadFromFile();
4086 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4087 if ( aSMESHDS_Mesh == NULL ) return false;
4088 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4089 if(!elem) return false;
4090 return elem->IsQuadratic();
4093 //=============================================================================
4095 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4097 //=============================================================================
4099 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4102 _preMeshInfo->FullLoadFromFile();
4104 if ( const SMDS_BallElement* ball =
4105 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4106 return ball->GetDiameter();
4111 //=============================================================================
4113 * Returns bary center for given element
4115 //=============================================================================
4117 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4120 _preMeshInfo->FullLoadFromFile();
4122 SMESH::double_array_var aResult = new SMESH::double_array();
4123 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4124 if ( aSMESHDS_Mesh == NULL )
4125 return aResult._retn();
4127 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4129 return aResult._retn();
4131 if(elem->GetType()==SMDSAbs_Volume) {
4132 SMDS_VolumeTool aTool;
4133 if(aTool.Set(elem)) {
4135 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4140 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4142 double x=0., y=0., z=0.;
4143 for(; anIt->more(); ) {
4145 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4159 return aResult._retn();
4162 //================================================================================
4164 * \brief Create a group of elements preventing computation of a sub-shape
4166 //================================================================================
4168 SMESH::ListOfGroups*
4169 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4170 const char* theGroupName )
4171 throw ( SALOME::SALOME_Exception )
4173 Unexpect aCatch(SALOME_SalomeException);
4175 if ( !theGroupName || strlen( theGroupName) == 0 )
4176 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4178 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4180 // submesh by subshape id
4181 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4182 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4185 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4186 if ( error && !error->myBadElements.empty())
4188 // sort bad elements by type
4189 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4190 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4191 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4192 for ( ; elemIt != elemEnd; ++elemIt )
4194 const SMDS_MeshElement* elem = *elemIt;
4195 if ( !elem ) continue;
4197 if ( elem->GetID() < 1 )
4199 // elem is a temporary element, make a real element
4200 vector< const SMDS_MeshNode* > nodes;
4201 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4202 while ( nIt->more() && elem )
4204 nodes.push_back( nIt->next() );
4205 if ( nodes.back()->GetID() < 1 )
4206 elem = 0; // a temporary element on temporary nodes
4210 ::SMESH_MeshEditor editor( _impl );
4211 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4215 elemsByType[ elem->GetType() ].push_back( elem );
4218 // how many groups to create?
4220 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4221 nbTypes += int( !elemsByType[ i ].empty() );
4222 groups->length( nbTypes );
4225 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4227 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4228 if ( elems.empty() ) continue;
4230 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4231 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4233 SALOMEDS::SObject_wrap aSO =
4234 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), groups[ iG ],
4235 GEOM::GEOM_Object::_nil(), theGroupName);
4236 aSO->_is_nil(); // avoid "unused variable" warning
4238 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4239 if ( !grp_i ) continue;
4241 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4242 for ( size_t iE = 0; iE < elems.size(); ++iE )
4243 grpDS->SMDSGroup().Add( elems[ iE ]);
4248 return groups._retn();
4251 //=============================================================================
4253 * Create and publish group servants if any groups were imported or created anyhow
4255 //=============================================================================
4257 void SMESH_Mesh_i::CreateGroupServants()
4259 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4262 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4263 while ( groupIt->more() )
4265 ::SMESH_Group* group = groupIt->next();
4266 int anId = group->GetGroupDS()->GetID();
4268 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4269 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4271 addedIDs.insert( anId );
4273 SMESH_GroupBase_i* aGroupImpl;
4275 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4276 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4278 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4279 shape = groupOnGeom->GetShape();
4282 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4285 SMESH::SMESH_GroupBase_var groupVar =
4286 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4287 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4289 // register CORBA object for persistence
4290 int nextId = _gen_i->RegisterObject( groupVar );
4291 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4292 else { nextId = 0; } // avoid "unused variable" warning in release mode
4294 // publishing the groups in the study
4295 if ( !aStudy->_is_nil() ) {
4296 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4297 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4300 if ( !addedIDs.empty() )
4303 set<int>::iterator id = addedIDs.begin();
4304 for ( ; id != addedIDs.end(); ++id )
4306 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4307 int i = std::distance( _mapGroups.begin(), it );
4308 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4313 //=============================================================================
4315 * \brief Return groups cantained in _mapGroups by their IDs
4317 //=============================================================================
4319 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4321 int nbGroups = groupIDs.size();
4322 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4323 aList->length( nbGroups );
4325 list<int>::const_iterator ids = groupIDs.begin();
4326 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4328 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4329 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4330 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4332 aList->length( nbGroups );
4333 return aList._retn();
4336 //=============================================================================
4338 * \brief Return information about imported file
4340 //=============================================================================
4342 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4344 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4345 if ( !res.operator->() ) {
4346 res = new SALOME_MED::MedFileInfo;
4348 res->fileSize = res->major = res->minor = res->release = -1;
4353 //=============================================================================
4355 * \brief Pass names of mesh groups from study to mesh DS
4357 //=============================================================================
4359 void SMESH_Mesh_i::checkGroupNames()
4361 int nbGrp = NbGroups();
4365 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4366 if ( aStudy->_is_nil() )
4367 return; // nothing to do
4369 SMESH::ListOfGroups* grpList = 0;
4370 // avoid dump of "GetGroups"
4372 // store python dump into a local variable inside local scope
4373 SMESH::TPythonDump pDump; // do not delete this line of code
4374 grpList = GetGroups();
4377 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4378 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4381 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4382 if ( aGrpSO->_is_nil() )
4384 // correct name of the mesh group if necessary
4385 const char* guiName = aGrpSO->GetName();
4386 if ( strcmp(guiName, aGrp->GetName()) )
4387 aGrp->SetName( guiName );
4391 //=============================================================================
4393 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4395 //=============================================================================
4396 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4398 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4402 //=============================================================================
4404 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4406 //=============================================================================
4407 char* SMESH_Mesh_i::GetParameters()
4409 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4410 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4413 //=============================================================================
4415 * \brief Returns list of notebook variables used for last Mesh operation
4417 //=============================================================================
4418 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4420 SMESH::string_array_var aResult = new SMESH::string_array();
4421 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4423 char *aParameters = GetParameters();
4424 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4425 if(!aStudy->_is_nil()) {
4426 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4427 if(aSections->length() > 0) {
4428 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4429 aResult->length(aVars.length());
4430 for(int i = 0;i < aVars.length();i++)
4431 aResult[i] = CORBA::string_dup( aVars[i]);
4435 return aResult._retn();
4438 //=======================================================================
4439 //function : GetTypes
4440 //purpose : Returns types of elements it contains
4441 //=======================================================================
4443 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4446 return _preMeshInfo->GetTypes();
4448 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4452 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4453 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4454 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4455 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4456 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4457 types->length( nbTypes );
4459 return types._retn();
4462 //=======================================================================
4463 //function : GetMesh
4464 //purpose : Returns self
4465 //=======================================================================
4467 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4469 return SMESH::SMESH_Mesh::_duplicate( _this() );
4472 //=======================================================================
4473 //function : IsMeshInfoCorrect
4474 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4475 // * happen if mesh data is not yet fully loaded from the file of study.
4476 //=======================================================================
4478 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4480 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4483 //=============================================================================
4485 * \brief Returns statistic of mesh elements
4487 //=============================================================================
4489 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4492 return _preMeshInfo->GetMeshInfo();
4494 SMESH::long_array_var aRes = new SMESH::long_array();
4495 aRes->length(SMESH::Entity_Last);
4496 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4498 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4500 return aRes._retn();
4501 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4502 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4503 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4504 return aRes._retn();
4507 //=============================================================================
4509 * \brief Collect statistic of mesh elements given by iterator
4511 //=============================================================================
4513 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4514 SMESH::long_array& theInfo)
4516 if (!theItr) return;
4517 while (theItr->more())
4518 theInfo[ theItr->next()->GetEntityType() ]++;
4521 //=============================================================================
4522 namespace // Finding concurrent hypotheses
4523 //=============================================================================
4527 * \brief mapping of mesh dimension into shape type
4529 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4531 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4533 case 0: aType = TopAbs_VERTEX; break;
4534 case 1: aType = TopAbs_EDGE; break;
4535 case 2: aType = TopAbs_FACE; break;
4537 default:aType = TopAbs_SOLID; break;
4542 //-----------------------------------------------------------------------------
4544 * \brief Internal structure used to find concurent submeshes
4546 * It represents a pair < submesh, concurent dimension >, where
4547 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4548 * with another submesh. In other words, it is dimension of a hypothesis assigned
4555 int _dim; //!< a dimension the algo can build (concurrent dimension)
4556 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4557 TopTools_MapOfShape _shapeMap;
4558 SMESH_subMesh* _subMesh;
4559 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4561 //-----------------------------------------------------------------------------
4562 // Return the algorithm
4563 const SMESH_Algo* GetAlgo() const
4564 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4566 //-----------------------------------------------------------------------------
4568 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4570 const TopoDS_Shape& theShape)
4572 _subMesh = (SMESH_subMesh*)theSubMesh;
4573 SetShape( theDim, theShape );
4576 //-----------------------------------------------------------------------------
4578 void SetShape(const int theDim,
4579 const TopoDS_Shape& theShape)
4582 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4583 if (_dim >= _ownDim)
4584 _shapeMap.Add( theShape );
4586 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4587 for( ; anExp.More(); anExp.Next() )
4588 _shapeMap.Add( anExp.Current() );
4592 //-----------------------------------------------------------------------------
4593 //! Check sharing of sub-shapes
4594 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4595 const TopTools_MapOfShape& theToFind,
4596 const TopAbs_ShapeEnum theType)
4598 bool isShared = false;
4599 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4600 for (; !isShared && anItr.More(); anItr.Next() )
4602 const TopoDS_Shape aSubSh = anItr.Key();
4603 // check for case when concurrent dimensions are same
4604 isShared = theToFind.Contains( aSubSh );
4605 // check for sub-shape with concurrent dimension
4606 TopExp_Explorer anExp( aSubSh, theType );
4607 for ( ; !isShared && anExp.More(); anExp.Next() )
4608 isShared = theToFind.Contains( anExp.Current() );
4613 //-----------------------------------------------------------------------------
4614 //! check algorithms
4615 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4616 const SMESHDS_Hypothesis* theA2)
4618 if ( !theA1 || !theA2 ||
4619 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4620 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4621 return false; // one of the hypothesis is not algorithm
4622 // check algorithm names (should be equal)
4623 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4627 //-----------------------------------------------------------------------------
4628 //! Check if sub-shape hypotheses are concurrent
4629 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4631 if ( _subMesh == theOther->_subMesh )
4632 return false; // same sub-shape - should not be
4634 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4635 // any of the two submeshes is not on COMPOUND shape )
4636 // -> no concurrency
4637 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4638 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4639 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4640 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4641 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4644 // bool checkSubShape = ( _dim >= theOther->_dim )
4645 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4646 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4647 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4648 if ( !checkSubShape )
4651 // check algorithms to be same
4652 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4653 return true; // different algorithms -> concurrency !
4655 // check hypothesises for concurrence (skip first as algorithm)
4657 // pointers should be same, because it is referened from mesh hypothesis partition
4658 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4659 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4660 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4661 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4663 // the submeshes are concurrent if their algorithms has different parameters
4664 return nbSame != theOther->_hypotheses.size() - 1;
4667 // Return true if algorithm of this SMESH_DimHyp is used if no
4668 // sub-mesh order is imposed by the user
4669 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4671 // NeedDiscreteBoundary() algo has a higher priority
4672 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4673 theOther->GetAlgo()->NeedDiscreteBoundary() )
4674 return !this->GetAlgo()->NeedDiscreteBoundary();
4676 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4679 }; // end of SMESH_DimHyp
4680 //-----------------------------------------------------------------------------
4682 typedef list<const SMESH_DimHyp*> TDimHypList;
4684 //-----------------------------------------------------------------------------
4686 void addDimHypInstance(const int theDim,
4687 const TopoDS_Shape& theShape,
4688 const SMESH_Algo* theAlgo,
4689 const SMESH_subMesh* theSubMesh,
4690 const list <const SMESHDS_Hypothesis*>& theHypList,
4691 TDimHypList* theDimHypListArr )
4693 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4694 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4695 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4696 dimHyp->_hypotheses.push_front(theAlgo);
4697 listOfdimHyp.push_back( dimHyp );
4700 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4701 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4702 theHypList.begin(), theHypList.end() );
4705 //-----------------------------------------------------------------------------
4706 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4707 TDimHypList& theListOfConcurr)
4709 if ( theListOfConcurr.empty() )
4711 theListOfConcurr.push_back( theDimHyp );
4715 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4716 while ( hypIt != theListOfConcurr.end() &&
4717 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4719 theListOfConcurr.insert( hypIt, theDimHyp );
4723 //-----------------------------------------------------------------------------
4724 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4725 const TDimHypList& theListOfDimHyp,
4726 TDimHypList& theListOfConcurrHyp,
4727 set<int>& theSetOfConcurrId )
4729 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4730 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4732 const SMESH_DimHyp* curDimHyp = *rIt;
4733 if ( curDimHyp == theDimHyp )
4734 break; // meet own dimHyp pointer in same dimension
4736 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4737 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4739 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4744 //-----------------------------------------------------------------------------
4745 void unionLists(TListOfInt& theListOfId,
4746 TListOfListOfInt& theListOfListOfId,
4749 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4750 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4752 continue; //skip already treated lists
4753 // check if other list has any same submesh object
4754 TListOfInt& otherListOfId = *it;
4755 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4756 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4759 // union two lists (from source into target)
4760 TListOfInt::iterator it2 = otherListOfId.begin();
4761 for ( ; it2 != otherListOfId.end(); it2++ ) {
4762 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4763 theListOfId.push_back(*it2);
4765 // clear source list
4766 otherListOfId.clear();
4769 //-----------------------------------------------------------------------------
4771 //! free memory allocated for dimension-hypothesis objects
4772 void removeDimHyps( TDimHypList* theArrOfList )
4774 for (int i = 0; i < 4; i++ ) {
4775 TDimHypList& listOfdimHyp = theArrOfList[i];
4776 TDimHypList::const_iterator it = listOfdimHyp.begin();
4777 for ( ; it != listOfdimHyp.end(); it++ )
4782 //-----------------------------------------------------------------------------
4784 * \brief find common submeshes with given submesh
4785 * \param theSubMeshList list of already collected submesh to check
4786 * \param theSubMesh given submesh to intersect with other
4787 * \param theCommonSubMeshes collected common submeshes
4789 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4790 const SMESH_subMesh* theSubMesh,
4791 set<const SMESH_subMesh*>& theCommon )
4795 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4796 for ( ; it != theSubMeshList.end(); it++ )
4797 theSubMesh->FindIntersection( *it, theCommon );
4798 theSubMeshList.push_back( theSubMesh );
4799 //theCommon.insert( theSubMesh );
4804 //=============================================================================
4806 * \brief Return submesh objects list in meshing order
4808 //=============================================================================
4810 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4812 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4814 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4816 return aResult._retn();
4818 ::SMESH_Mesh& mesh = GetImpl();
4819 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4820 if ( !anOrder.size() ) {
4822 // collect submeshes and detect concurrent algorithms and hypothesises
4823 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4825 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4826 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4827 ::SMESH_subMesh* sm = (*i_sm).second;
4829 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4831 // list of assigned hypothesises
4832 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4833 // Find out dimensions where the submesh can be concurrent.
4834 // We define the dimensions by algo of each of hypotheses in hypList
4835 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4836 for( ; hypIt != hypList.end(); hypIt++ ) {
4837 SMESH_Algo* anAlgo = 0;
4838 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4839 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4840 // hyp it-self is algo
4841 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4843 // try to find algorithm with help of sub-shapes
4844 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4845 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4846 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4849 continue; // no algorithm assigned to a current submesh
4851 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4852 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4854 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4855 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4856 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4858 } // end iterations on submesh
4860 // iterate on created dimension-hypotheses and check for concurrents
4861 for ( int i = 0; i < 4; i++ ) {
4862 const TDimHypList& listOfDimHyp = dimHypListArr[i];
4863 // check for concurrents in own and other dimensions (step-by-step)
4864 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4865 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4866 const SMESH_DimHyp* dimHyp = *dhIt;
4867 TDimHypList listOfConcurr;
4868 set<int> setOfConcurrIds;
4869 // looking for concurrents and collect into own list
4870 for ( int j = i; j < 4; j++ )
4871 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
4872 // check if any concurrents found
4873 if ( listOfConcurr.size() > 0 ) {
4874 // add own submesh to list of concurrent
4875 addInOrderOfPriority( dimHyp, listOfConcurr );
4876 list<int> listOfConcurrIds;
4877 TDimHypList::iterator hypIt = listOfConcurr.begin();
4878 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
4879 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
4880 anOrder.push_back( listOfConcurrIds );
4885 removeDimHyps(dimHypListArr);
4887 // now, minimise the number of concurrent groups
4888 // Here we assume that lists of submeshes can have same submesh
4889 // in case of multi-dimension algorithms, as result
4890 // list with common submesh has to be united into one list
4892 TListOfListOfInt::iterator listIt = anOrder.begin();
4893 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4894 unionLists( *listIt, anOrder, listIndx + 1 );
4896 // convert submesh ids into interface instances
4897 // and dump command into python
4898 convertMeshOrder( anOrder, aResult, false );
4900 return aResult._retn();
4903 //=============================================================================
4905 * \brief Set submesh object order
4906 * \param theSubMeshArray submesh array order
4908 //=============================================================================
4910 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4913 _preMeshInfo->ForgetOrLoad();
4916 ::SMESH_Mesh& mesh = GetImpl();
4918 TPythonDump aPythonDump; // prevent dump of called methods
4919 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4921 TListOfListOfInt subMeshOrder;
4922 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4924 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4925 TListOfInt subMeshIds;
4926 aPythonDump << "[ ";
4927 // Collect subMeshes which should be clear
4928 // do it list-by-list, because modification of submesh order
4929 // take effect between concurrent submeshes only
4930 set<const SMESH_subMesh*> subMeshToClear;
4931 list<const SMESH_subMesh*> subMeshList;
4932 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4934 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4936 aPythonDump << ", ";
4937 aPythonDump << subMesh;
4938 subMeshIds.push_back( subMesh->GetId() );
4939 // detect common parts of submeshes
4940 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4941 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4943 aPythonDump << " ]";
4944 subMeshOrder.push_back( subMeshIds );
4946 // clear collected submeshes
4947 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4948 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
4949 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
4950 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4952 aPythonDump << " ])";
4954 mesh.SetMeshOrder( subMeshOrder );
4960 //=============================================================================
4962 * \brief Convert submesh ids into submesh interfaces
4964 //=============================================================================
4966 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4967 SMESH::submesh_array_array& theResOrder,
4968 const bool theIsDump)
4970 int nbSet = theIdsOrder.size();
4971 TPythonDump aPythonDump; // prevent dump of called methods
4973 aPythonDump << "[ ";
4974 theResOrder.length(nbSet);
4975 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4977 for( ; it != theIdsOrder.end(); it++ ) {
4978 // translate submesh identificators into submesh objects
4979 // takeing into account real number of concurrent lists
4980 const TListOfInt& aSubOrder = (*it);
4981 if (!aSubOrder.size())
4984 aPythonDump << "[ ";
4985 // convert shape indeces into interfaces
4986 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4987 aResSubSet->length(aSubOrder.size());
4988 TListOfInt::const_iterator subIt = aSubOrder.begin();
4989 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4990 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4992 SMESH::SMESH_subMesh_var subMesh =
4993 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4996 aPythonDump << ", ";
4997 aPythonDump << subMesh;
4999 aResSubSet[ j++ ] = subMesh;
5002 aPythonDump << " ]";
5003 theResOrder[ listIndx++ ] = aResSubSet;
5005 // correct number of lists
5006 theResOrder.length( listIndx );
5009 // finilise python dump
5010 aPythonDump << " ]";
5011 aPythonDump << " = " << _this() << ".GetMeshOrder()";
5015 //================================================================================
5017 // Implementation of SMESH_MeshPartDS
5019 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5020 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5022 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5023 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5025 _meshDS = mesh_i->GetImpl().GetMeshDS();
5027 SetPersistentId( _meshDS->GetPersistentId() );
5029 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5031 // <meshPart> is the whole mesh
5032 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5034 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5035 myGroupSet = _meshDS->GetGroups();
5040 SMESH::long_array_var anIDs = meshPart->GetIDs();
5041 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5042 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5044 for (int i=0; i < anIDs->length(); i++)
5045 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5046 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5051 for (int i=0; i < anIDs->length(); i++)
5052 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5053 if ( _elements[ e->GetType() ].insert( e ).second )
5056 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5057 while ( nIt->more() )
5059 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5060 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5067 _meshDS = 0; // to enforce iteration on _elements and _nodes
5070 // -------------------------------------------------------------------------------------
5071 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5072 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5075 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5076 for ( ; partIt != meshPart.end(); ++partIt )
5077 if ( const SMDS_MeshElement * e = *partIt )
5078 if ( _elements[ e->GetType() ].insert( e ).second )
5081 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5082 while ( nIt->more() )
5084 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5085 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5091 // -------------------------------------------------------------------------------------
5092 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5094 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5096 typedef SMDS_SetIterator
5097 <const SMDS_MeshElement*,
5098 TIDSortedElemSet::const_iterator,
5099 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5100 SMDS_MeshElement::GeomFilter
5103 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5105 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5106 _elements[type].end(),
5107 SMDS_MeshElement::GeomFilter( geomType )));
5109 // -------------------------------------------------------------------------------------
5110 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5112 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5114 typedef SMDS_SetIterator
5115 <const SMDS_MeshElement*,
5116 TIDSortedElemSet::const_iterator,
5117 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5118 SMDS_MeshElement::EntityFilter
5121 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5123 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5124 _elements[type].end(),
5125 SMDS_MeshElement::EntityFilter( entity )));
5127 // -------------------------------------------------------------------------------------
5128 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5130 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5131 if ( type == SMDSAbs_All && !_meshDS )
5133 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5135 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5136 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5138 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5140 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5141 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5143 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5144 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5146 // -------------------------------------------------------------------------------------
5147 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5148 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5150 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5151 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5152 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5154 // -------------------------------------------------------------------------------------
5155 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5156 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5157 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5158 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5159 #undef _GET_ITER_DEFINE
5161 // END Implementation of SMESH_MeshPartDS
5163 //================================================================================