1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
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_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_Filter_i.hxx"
45 #include "SMESH_Gen_i.hxx"
46 #include "SMESH_Group.hxx"
47 #include "SMESH_Group_i.hxx"
48 #include "SMESH_MeshAlgos.hxx"
49 #include "SMESH_MeshEditor.hxx"
50 #include "SMESH_MeshEditor_i.hxx"
51 #include "SMESH_MeshPartDS.hxx"
52 #include "SMESH_MesherHelper.hxx"
53 #include "SMESH_PreMeshInfo.hxx"
54 #include "SMESH_PythonDump.hxx"
55 #include "SMESH_subMesh_i.hxx"
58 #include <SALOMEDS_Attributes_wrap.hxx>
59 #include <SALOMEDS_wrap.hxx>
60 #include <SALOME_NamingService.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <Utils_SINGLETON.hxx>
63 #include <utilities.h>
65 #include <GEOMImpl_Types.hxx>
66 #include <GEOM_wrap.hxx>
69 #include <BRep_Builder.hxx>
70 #include <OSD_Directory.hxx>
71 #include <OSD_File.hxx>
72 #include <OSD_Path.hxx>
73 #include <OSD_Protection.hxx>
74 #include <Standard_OutOfMemory.hxx>
75 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
76 #include <TColStd_MapOfInteger.hxx>
77 #include <TColStd_SequenceOfInteger.hxx>
78 #include <TCollection_AsciiString.hxx>
80 #include <TopExp_Explorer.hxx>
81 #include <TopTools_MapIteratorOfMapOfShape.hxx>
82 #include <TopTools_MapOfShape.hxx>
83 #include <TopoDS_Compound.hxx>
93 // to pass CORBA exception through SMESH_TRY
94 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
96 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
99 static int MYDEBUG = 0;
101 static int MYDEBUG = 0;
105 using SMESH::TPythonDump;
107 int SMESH_Mesh_i::_idGenerator = 0;
109 //=============================================================================
113 //=============================================================================
115 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
117 CORBA::Long studyId )
118 : SALOME::GenericObj_i( thePOA )
120 MESSAGE("SMESH_Mesh_i");
123 _id = _idGenerator++;
126 _previewEditor = NULL;
131 //=============================================================================
135 //=============================================================================
137 SMESH_Mesh_i::~SMESH_Mesh_i()
139 MESSAGE("~SMESH_Mesh_i");
142 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
143 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
144 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
146 aGroup->UnRegister();
147 SMESH::SMESH_GroupBase_var( itGr->second );
152 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
153 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
154 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
156 aSubMesh->UnRegister();
157 SMESH::SMESH_subMesh_var( itSM->second );
159 _mapSubMeshIor.clear();
161 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
162 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
163 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
164 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
165 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
166 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
169 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
173 delete _editor; _editor = NULL;
174 delete _previewEditor; _previewEditor = NULL;
175 delete _impl; _impl = NULL;
176 delete _preMeshInfo; _preMeshInfo = NULL;
179 //=============================================================================
183 * Associates <this> mesh with <theShape> and puts a reference
184 * to <theShape> into the current study;
185 * the previous shape is substituted by the new one.
187 //=============================================================================
189 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
190 throw (SALOME::SALOME_Exception)
192 Unexpect aCatch(SALOME_SalomeException);
194 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
196 catch(SALOME_Exception & S_ex) {
197 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
199 // to track changes of GEOM groups
200 SMESH::SMESH_Mesh_var mesh = _this();
201 addGeomGroupData( theShapeObject, mesh );
202 if ( !CORBA::is_nil( theShapeObject ))
203 _mainShapeTick = theShapeObject->GetTick();
206 //================================================================================
208 * \brief return true if mesh has a shape to build a shape on
210 //================================================================================
212 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
213 throw (SALOME::SALOME_Exception)
215 Unexpect aCatch(SALOME_SalomeException);
218 res = _impl->HasShapeToMesh();
220 catch(SALOME_Exception & S_ex) {
221 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
226 //=======================================================================
227 //function : GetShapeToMesh
229 //=======================================================================
231 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
232 throw (SALOME::SALOME_Exception)
234 Unexpect aCatch(SALOME_SalomeException);
235 GEOM::GEOM_Object_var aShapeObj;
237 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
239 aShapeObj = _gen_i->ShapeToGeomObject( S );
241 catch(SALOME_Exception & S_ex) {
242 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
244 return aShapeObj._retn();
247 //================================================================================
249 * \brief Return false if the mesh is not yet fully loaded from the study file
251 //================================================================================
253 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
255 Unexpect aCatch(SALOME_SalomeException);
256 return !_preMeshInfo;
259 //================================================================================
261 * \brief Load full mesh data from the study file
263 //================================================================================
265 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
267 Unexpect aCatch(SALOME_SalomeException);
269 _preMeshInfo->FullLoadFromFile();
272 //================================================================================
274 * \brief Remove all nodes and elements
276 //================================================================================
278 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
280 Unexpect aCatch(SALOME_SalomeException);
282 _preMeshInfo->ForgetAllData();
286 //CheckGeomGroupModif(); // issue 20145
288 catch(SALOME_Exception & S_ex) {
289 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
291 _impl->GetMeshDS()->Modified();
293 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
296 //================================================================================
298 * \brief Remove all nodes and elements for indicated shape
300 //================================================================================
302 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
303 throw (SALOME::SALOME_Exception)
305 Unexpect aCatch(SALOME_SalomeException);
307 _preMeshInfo->FullLoadFromFile();
310 _impl->ClearSubMesh( ShapeID );
312 catch(SALOME_Exception & S_ex) {
313 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
315 _impl->GetMeshDS()->Modified();
317 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
320 //=============================================================================
322 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
324 //=============================================================================
326 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
328 SMESH::DriverMED_ReadStatus res;
331 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
332 res = SMESH::DRS_OK; break;
333 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
334 res = SMESH::DRS_EMPTY; break;
335 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
336 res = SMESH::DRS_WARN_RENUMBER; break;
337 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
338 res = SMESH::DRS_WARN_SKIP_ELEM; break;
339 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
340 res = SMESH::DRS_WARN_DESCENDING; break;
341 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
343 res = SMESH::DRS_FAIL; break;
348 //=============================================================================
350 * Convert ::SMESH_ComputeError to SMESH::ComputeError
352 //=============================================================================
354 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
356 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
357 errVar->subShapeID = -1;
358 errVar->hasBadMesh = false;
360 if ( !errorPtr || errorPtr->IsOK() )
362 errVar->code = SMESH::COMPERR_OK;
366 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
367 errVar->comment = errorPtr->myComment.c_str();
369 return errVar._retn();
372 //=============================================================================
376 * Imports mesh data from MED file
378 //=============================================================================
380 SMESH::DriverMED_ReadStatus
381 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
382 throw ( SALOME::SALOME_Exception )
384 Unexpect aCatch(SALOME_SalomeException);
387 status = _impl->MEDToMesh( theFileName, theMeshName );
389 catch( SALOME_Exception& S_ex ) {
390 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
393 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
396 CreateGroupServants();
398 int major, minor, release;
399 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
400 major = minor = release = -1;
401 _medFileInfo = new SMESH::MedFileInfo();
402 _medFileInfo->fileName = theFileName;
403 _medFileInfo->fileSize = 0;
404 _medFileInfo->major = major;
405 _medFileInfo->minor = minor;
406 _medFileInfo->release = release;
409 if ( ::_stati64( theFileName, &d ) != -1 )
412 if ( ::stat64( theFileName, &d ) != -1 )
414 _medFileInfo->fileSize = d.st_size;
416 return ConvertDriverMEDReadStatus(status);
419 //================================================================================
421 * \brief Imports mesh data from the CGNS file
423 //================================================================================
425 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
426 const int theMeshIndex,
427 std::string& theMeshName )
428 throw ( SALOME::SALOME_Exception )
430 Unexpect aCatch(SALOME_SalomeException);
433 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
435 catch( SALOME_Exception& S_ex ) {
436 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
439 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
442 CreateGroupServants();
444 return ConvertDriverMEDReadStatus(status);
447 //================================================================================
449 * \brief Return string representation of a MED file version comprising nbDigits
451 //================================================================================
453 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
455 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
457 return CORBA::string_dup( ver.c_str() );
460 //=============================================================================
464 * Imports mesh data from MED file
466 //=============================================================================
468 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
469 throw ( SALOME::SALOME_Exception )
473 // Read mesh with name = <theMeshName> into SMESH_Mesh
474 _impl->UNVToMesh( theFileName );
476 CreateGroupServants();
478 SMESH_CATCH( SMESH::throwCorbaException );
483 //=============================================================================
487 * Imports mesh data from STL file
489 //=============================================================================
490 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
491 throw ( SALOME::SALOME_Exception )
495 // Read mesh with name = <theMeshName> into SMESH_Mesh
496 _impl->STLToMesh( theFileName );
498 SMESH_CATCH( SMESH::throwCorbaException );
503 //================================================================================
505 * \brief Function used in SMESH_CATCH by ImportGMFFile()
507 //================================================================================
511 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
513 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
517 //================================================================================
519 * \brief Imports data from a GMF file and returns an error description
521 //================================================================================
523 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
524 bool theMakeRequiredGroups )
525 throw (SALOME::SALOME_Exception)
527 SMESH_ComputeErrorPtr error;
530 #define SMESH_CAUGHT error =
533 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
535 SMESH_CATCH( exceptionToComputeError );
539 CreateGroupServants();
541 return ConvertComputeError( error );
544 //=============================================================================
548 //=============================================================================
550 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
552 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
553 (SMESH_Hypothesis::Hypothesis_Status theStatus)
556 RETURNCASE( HYP_OK );
557 RETURNCASE( HYP_MISSING );
558 RETURNCASE( HYP_CONCURENT );
559 RETURNCASE( HYP_BAD_PARAMETER );
560 RETURNCASE( HYP_HIDDEN_ALGO );
561 RETURNCASE( HYP_HIDING_ALGO );
562 RETURNCASE( HYP_UNKNOWN_FATAL );
563 RETURNCASE( HYP_INCOMPATIBLE );
564 RETURNCASE( HYP_NOTCONFORM );
565 RETURNCASE( HYP_ALREADY_EXIST );
566 RETURNCASE( HYP_BAD_DIM );
567 RETURNCASE( HYP_BAD_SUBSHAPE );
568 RETURNCASE( HYP_BAD_GEOMETRY );
569 RETURNCASE( HYP_NEED_SHAPE );
572 return SMESH::HYP_UNKNOWN_FATAL;
575 //=============================================================================
579 * calls internal addHypothesis() and then adds a reference to <anHyp> under
580 * the SObject actually having a reference to <aSubShape>.
581 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
583 //=============================================================================
585 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
586 SMESH::SMESH_Hypothesis_ptr anHyp)
587 throw(SALOME::SALOME_Exception)
589 Unexpect aCatch(SALOME_SalomeException);
591 _preMeshInfo->ForgetOrLoad();
593 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
595 SMESH::SMESH_Mesh_var mesh( _this() );
596 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
598 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
599 _gen_i->AddHypothesisToShape( study, mesh, aSubShapeObject, anHyp );
601 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
603 // Update Python script
604 //if(_impl->HasShapeToMesh())
606 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
607 << aSubShapeObject << ", " << anHyp << " )";
610 // TPythonDump() << "status = " << mesh << ".AddHypothesis( "<< anHyp << " )";
613 return ConvertHypothesisStatus(status);
616 //=============================================================================
620 //=============================================================================
622 SMESH_Hypothesis::Hypothesis_Status
623 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
624 SMESH::SMESH_Hypothesis_ptr anHyp)
626 if(MYDEBUG) MESSAGE("addHypothesis");
628 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
629 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
631 if (CORBA::is_nil( anHyp ))
632 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
634 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
637 TopoDS_Shape myLocSubShape;
638 //use PseudoShape in case if mesh has no shape
640 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
642 myLocSubShape = _impl->GetShapeToMesh();
644 const int hypId = anHyp->GetId();
645 status = _impl->AddHypothesis(myLocSubShape, hypId);
646 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
647 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
649 // assure there is a corresponding submesh
650 if ( !_impl->IsMainShape( myLocSubShape )) {
651 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
652 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
653 SMESH::SMESH_subMesh_var( createSubMesh( aSubShapeObject ));
657 catch(SALOME_Exception & S_ex)
659 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
664 //=============================================================================
668 //=============================================================================
670 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
671 SMESH::SMESH_Hypothesis_ptr anHyp)
672 throw(SALOME::SALOME_Exception)
674 Unexpect aCatch(SALOME_SalomeException);
676 _preMeshInfo->ForgetOrLoad();
678 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
679 SMESH::SMESH_Mesh_var mesh = _this();
681 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
683 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
684 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShapeObject, anHyp );
686 // Update Python script
687 if(_impl->HasShapeToMesh())
688 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
689 << aSubShapeObject << ", " << anHyp << " )";
691 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
694 return ConvertHypothesisStatus(status);
697 //=============================================================================
701 //=============================================================================
703 SMESH_Hypothesis::Hypothesis_Status
704 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
705 SMESH::SMESH_Hypothesis_ptr anHyp)
707 if(MYDEBUG) MESSAGE("removeHypothesis()");
709 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
710 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
712 if (CORBA::is_nil( anHyp ))
713 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
715 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
718 TopoDS_Shape myLocSubShape;
719 //use PseudoShape in case if mesh has no shape
720 if( _impl->HasShapeToMesh() )
721 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject );
723 myLocSubShape = _impl->GetShapeToMesh();
725 const int hypId = anHyp->GetId();
726 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
727 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
729 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
733 catch(SALOME_Exception & S_ex)
735 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
740 //=============================================================================
744 //=============================================================================
746 SMESH::ListOfHypothesis *
747 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
748 throw(SALOME::SALOME_Exception)
750 Unexpect aCatch(SALOME_SalomeException);
751 if (MYDEBUG) MESSAGE("GetHypothesisList");
752 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
753 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
755 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
758 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
759 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
760 myLocSubShape = _impl->GetShapeToMesh();
761 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
762 int i = 0, n = aLocalList.size();
765 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
766 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
767 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
769 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
770 if ( id_hypptr != _mapHypo.end() )
771 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
775 catch(SALOME_Exception & S_ex) {
776 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
779 return aList._retn();
782 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
784 Unexpect aCatch(SALOME_SalomeException);
785 if (MYDEBUG) MESSAGE("GetSubMeshes");
787 SMESH::submesh_array_var aList = new SMESH::submesh_array();
790 TPythonDump aPythonDump;
791 if ( !_mapSubMeshIor.empty() )
795 aList->length( _mapSubMeshIor.size() );
797 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
798 for ( ; it != _mapSubMeshIor.end(); it++ ) {
799 if ( CORBA::is_nil( it->second )) continue;
800 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
802 if (i > 1) aPythonDump << ", ";
803 aPythonDump << it->second;
807 catch(SALOME_Exception & S_ex) {
808 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
811 // Update Python script
812 if ( !_mapSubMeshIor.empty() )
813 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
815 return aList._retn();
818 //=============================================================================
822 //=============================================================================
824 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
825 const char* theName )
826 throw(SALOME::SALOME_Exception)
828 Unexpect aCatch(SALOME_SalomeException);
829 if (CORBA::is_nil(aSubShapeObject))
830 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
832 SMESH::SMESH_subMesh_var subMesh;
833 SMESH::SMESH_Mesh_var aMesh = _this();
835 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
837 //Get or Create the SMESH_subMesh object implementation
839 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
841 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
843 TopoDS_Iterator it( myLocSubShape );
845 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
847 subMesh = getSubMesh( subMeshId );
849 // create a new subMesh object servant if there is none for the shape
850 if ( subMesh->_is_nil() )
851 subMesh = createSubMesh( aSubShapeObject );
852 if ( _gen_i->CanPublishInStudy( subMesh ))
854 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
855 SALOMEDS::SObject_wrap aSO =
856 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShapeObject, theName );
857 if ( !aSO->_is_nil()) {
858 // Update Python script
859 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
860 << aSubShapeObject << ", '" << theName << "' )";
864 catch(SALOME_Exception & S_ex) {
865 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
867 return subMesh._retn();
870 //=============================================================================
874 //=============================================================================
876 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
877 throw (SALOME::SALOME_Exception)
881 if ( theSubMesh->_is_nil() )
884 GEOM::GEOM_Object_var aSubShapeObject;
885 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
886 if ( !aStudy->_is_nil() ) {
887 // Remove submesh's SObject
888 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
889 if ( !anSO->_is_nil() ) {
890 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
891 SALOMEDS::SObject_wrap anObj, aRef;
892 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
893 anObj->ReferencedObject( aRef.inout() ))
895 CORBA::Object_var obj = aRef->GetObject();
896 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
898 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
899 // aSubShapeObject = theSubMesh->GetSubShape();
901 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
902 builder->RemoveObjectWithChildren( anSO );
904 // Update Python script
905 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
909 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
911 _preMeshInfo->ForgetOrLoad();
913 SMESH_CATCH( SMESH::throwCorbaException );
916 //=============================================================================
920 //=============================================================================
922 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
923 const char* theName )
924 throw(SALOME::SALOME_Exception)
926 Unexpect aCatch(SALOME_SalomeException);
928 _preMeshInfo->FullLoadFromFile();
930 SMESH::SMESH_Group_var aNewGroup =
931 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
933 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
935 SMESH::SMESH_Mesh_var mesh = _this();
936 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
937 SALOMEDS::SObject_wrap aSO =
938 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
939 if ( !aSO->_is_nil())
940 // Update Python script
941 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
942 << theElemType << ", '" << theName << "' )";
944 return aNewGroup._retn();
947 //=============================================================================
951 //=============================================================================
952 SMESH::SMESH_GroupOnGeom_ptr
953 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
955 GEOM::GEOM_Object_ptr theGeomObj)
956 throw(SALOME::SALOME_Exception)
958 Unexpect aCatch(SALOME_SalomeException);
960 _preMeshInfo->FullLoadFromFile();
962 SMESH::SMESH_GroupOnGeom_var aNewGroup;
964 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
965 if ( !aShape.IsNull() )
968 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
970 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
972 SMESH::SMESH_Mesh_var mesh = _this();
973 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
974 SALOMEDS::SObject_wrap aSO =
975 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
976 if ( !aSO->_is_nil())
977 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
978 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
982 return aNewGroup._retn();
985 //================================================================================
987 * \brief Creates a group whose contents is defined by filter
988 * \param theElemType - group type
989 * \param theName - group name
990 * \param theFilter - the filter
991 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
993 //================================================================================
995 SMESH::SMESH_GroupOnFilter_ptr
996 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
998 SMESH::Filter_ptr theFilter )
999 throw (SALOME::SALOME_Exception)
1001 Unexpect aCatch(SALOME_SalomeException);
1003 _preMeshInfo->FullLoadFromFile();
1005 if ( CORBA::is_nil( theFilter ))
1006 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1008 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1010 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1012 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1013 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1016 if ( !aNewGroup->_is_nil() )
1017 aNewGroup->SetFilter( theFilter );
1019 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1021 SMESH::SMESH_Mesh_var mesh = _this();
1022 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1023 SALOMEDS::SObject_wrap aSO =
1024 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1026 if ( !aSO->_is_nil())
1027 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1028 << theElemType << ", '" << theName << "', " << theFilter << " )";
1030 return aNewGroup._retn();
1033 //=============================================================================
1037 //=============================================================================
1039 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1040 throw (SALOME::SALOME_Exception)
1042 if ( theGroup->_is_nil() )
1047 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1051 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1052 if ( !aStudy->_is_nil() )
1054 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1055 if ( !aGroupSO->_is_nil() )
1057 // Update Python script
1058 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1060 // Remove group's SObject
1061 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1062 builder->RemoveObjectWithChildren( aGroupSO );
1066 // Remove the group from SMESH data structures
1067 removeGroup( aGroup->GetLocalID() );
1069 SMESH_CATCH( SMESH::throwCorbaException );
1072 //=============================================================================
1074 * Remove group with its contents
1076 //=============================================================================
1078 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1079 throw (SALOME::SALOME_Exception)
1083 _preMeshInfo->FullLoadFromFile();
1085 if ( theGroup->_is_nil() )
1089 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1090 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1091 while ( elemIt->more() )
1092 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1094 TPythonDump pyDump; // Supress dump from RemoveGroup()
1096 // Update Python script (theGroup must be alive for this)
1097 pyDump << SMESH::SMESH_Mesh_var(_this())
1098 << ".RemoveGroupWithContents( " << theGroup << " )";
1101 RemoveGroup( theGroup );
1103 SMESH_CATCH( SMESH::throwCorbaException );
1106 //================================================================================
1108 * \brief Get the list of groups existing in the mesh
1109 * \retval SMESH::ListOfGroups * - list of groups
1111 //================================================================================
1113 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1115 Unexpect aCatch(SALOME_SalomeException);
1116 if (MYDEBUG) MESSAGE("GetGroups");
1118 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1121 TPythonDump aPythonDump;
1122 if ( !_mapGroups.empty() )
1124 aPythonDump << "[ ";
1126 aList->length( _mapGroups.size() );
1128 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1129 for ( ; it != _mapGroups.end(); it++ ) {
1130 if ( CORBA::is_nil( it->second )) continue;
1131 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1133 if (i > 1) aPythonDump << ", ";
1134 aPythonDump << it->second;
1138 catch(SALOME_Exception & S_ex) {
1139 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1141 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1143 return aList._retn();
1146 //=============================================================================
1148 * Get number of groups existing in the mesh
1150 //=============================================================================
1152 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1154 Unexpect aCatch(SALOME_SalomeException);
1155 return _mapGroups.size();
1158 //=============================================================================
1160 * New group including all mesh elements present in initial groups is created.
1162 //=============================================================================
1164 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1165 SMESH::SMESH_GroupBase_ptr theGroup2,
1166 const char* theName )
1167 throw (SALOME::SALOME_Exception)
1169 SMESH::SMESH_Group_var aResGrp;
1173 _preMeshInfo->FullLoadFromFile();
1175 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1176 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1178 if ( theGroup1->GetType() != theGroup2->GetType() )
1179 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1184 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1185 if ( aResGrp->_is_nil() )
1186 return SMESH::SMESH_Group::_nil();
1188 aResGrp->AddFrom( theGroup1 );
1189 aResGrp->AddFrom( theGroup2 );
1191 // Update Python script
1192 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1193 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1195 SMESH_CATCH( SMESH::throwCorbaException );
1197 return aResGrp._retn();
1200 //=============================================================================
1202 * \brief New group including all mesh elements present in initial groups is created.
1203 * \param theGroups list of groups
1204 * \param theName name of group to be created
1205 * \return pointer to the new group
1207 //=============================================================================
1209 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1210 const char* theName )
1211 throw (SALOME::SALOME_Exception)
1213 SMESH::SMESH_Group_var aResGrp;
1216 _preMeshInfo->FullLoadFromFile();
1219 return SMESH::SMESH_Group::_nil();
1224 SMESH::ElementType aType = SMESH::ALL;
1225 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1227 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1228 if ( CORBA::is_nil( aGrp ) )
1230 if ( aType == SMESH::ALL )
1231 aType = aGrp->GetType();
1232 else if ( aType != aGrp->GetType() )
1233 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1236 if ( aType == SMESH::ALL )
1237 return SMESH::SMESH_Group::_nil();
1242 aResGrp = CreateGroup( aType, theName );
1243 if ( aResGrp->_is_nil() )
1244 return SMESH::SMESH_Group::_nil();
1246 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1247 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1249 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1250 if ( !CORBA::is_nil( aGrp ) )
1252 aResGrp->AddFrom( aGrp );
1253 if ( g > 0 ) pyDump << ", ";
1257 pyDump << " ], '" << theName << "' )";
1259 SMESH_CATCH( SMESH::throwCorbaException );
1261 return aResGrp._retn();
1264 //=============================================================================
1266 * New group is created. All mesh elements that are
1267 * present in both initial groups are added to the new one.
1269 //=============================================================================
1271 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1272 SMESH::SMESH_GroupBase_ptr theGroup2,
1273 const char* theName )
1274 throw (SALOME::SALOME_Exception)
1276 SMESH::SMESH_Group_var aResGrp;
1281 _preMeshInfo->FullLoadFromFile();
1283 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1284 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1286 if ( theGroup1->GetType() != theGroup2->GetType() )
1287 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1291 // Create Intersection
1292 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1293 if ( aResGrp->_is_nil() )
1294 return aResGrp._retn();
1296 SMESHDS_GroupBase* groupDS1 = 0;
1297 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1298 groupDS1 = grp_i->GetGroupDS();
1300 SMESHDS_GroupBase* groupDS2 = 0;
1301 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1302 groupDS2 = grp_i->GetGroupDS();
1304 SMESHDS_Group* resGroupDS = 0;
1305 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1306 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1308 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1310 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1311 while ( elemIt1->more() )
1313 const SMDS_MeshElement* e = elemIt1->next();
1314 if ( groupDS2->Contains( e ))
1315 resGroupDS->SMDSGroup().Add( e );
1318 // Update Python script
1319 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1320 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1322 SMESH_CATCH( SMESH::throwCorbaException );
1324 return aResGrp._retn();
1327 //=============================================================================
1329 \brief Intersect list of groups. New group is created. All mesh elements that
1330 are present in all initial groups simultaneously are added to the new one.
1331 \param theGroups list of groups
1332 \param theName name of group to be created
1333 \return pointer on the group
1335 //=============================================================================
1336 SMESH::SMESH_Group_ptr
1337 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1338 const char* theName )
1339 throw (SALOME::SALOME_Exception)
1341 SMESH::SMESH_Group_var aResGrp;
1346 _preMeshInfo->FullLoadFromFile();
1349 return SMESH::SMESH_Group::_nil();
1351 // check types and get SMESHDS_GroupBase's
1352 SMESH::ElementType aType = SMESH::ALL;
1353 vector< SMESHDS_GroupBase* > groupVec;
1354 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1356 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1357 if ( CORBA::is_nil( aGrp ) )
1359 if ( aType == SMESH::ALL )
1360 aType = aGrp->GetType();
1361 else if ( aType != aGrp->GetType() )
1362 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1365 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1366 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1368 if ( grpDS->IsEmpty() )
1373 groupVec.push_back( grpDS );
1376 if ( aType == SMESH::ALL ) // all groups are nil
1377 return SMESH::SMESH_Group::_nil();
1382 aResGrp = CreateGroup( aType, theName );
1384 SMESHDS_Group* resGroupDS = 0;
1385 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1386 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1387 if ( !resGroupDS || groupVec.empty() )
1388 return aResGrp._retn();
1391 size_t i, nb = groupVec.size();
1392 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1393 while ( elemIt1->more() )
1395 const SMDS_MeshElement* e = elemIt1->next();
1397 for ( i = 1; ( i < nb && inAll ); ++i )
1398 inAll = groupVec[i]->Contains( e );
1401 resGroupDS->SMDSGroup().Add( e );
1404 // Update Python script
1405 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1406 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1408 SMESH_CATCH( SMESH::throwCorbaException );
1410 return aResGrp._retn();
1413 //=============================================================================
1415 * New group is created. All mesh elements that are present in
1416 * a main group but is not present in a tool group are added to the new one
1418 //=============================================================================
1420 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1421 SMESH::SMESH_GroupBase_ptr theGroup2,
1422 const char* theName )
1423 throw (SALOME::SALOME_Exception)
1425 SMESH::SMESH_Group_var aResGrp;
1430 _preMeshInfo->FullLoadFromFile();
1432 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1433 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1435 if ( theGroup1->GetType() != theGroup2->GetType() )
1436 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1440 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1441 if ( aResGrp->_is_nil() )
1442 return aResGrp._retn();
1444 SMESHDS_GroupBase* groupDS1 = 0;
1445 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1446 groupDS1 = grp_i->GetGroupDS();
1448 SMESHDS_GroupBase* groupDS2 = 0;
1449 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1450 groupDS2 = grp_i->GetGroupDS();
1452 SMESHDS_Group* resGroupDS = 0;
1453 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1454 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1456 if ( groupDS1 && groupDS2 && resGroupDS )
1458 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1459 while ( elemIt1->more() )
1461 const SMDS_MeshElement* e = elemIt1->next();
1462 if ( !groupDS2->Contains( e ))
1463 resGroupDS->SMDSGroup().Add( e );
1466 // Update Python script
1467 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1468 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1470 SMESH_CATCH( SMESH::throwCorbaException );
1472 return aResGrp._retn();
1475 //=============================================================================
1477 \brief Cut lists of groups. New group is created. All mesh elements that are
1478 present in main groups but do not present in tool groups are added to the new one
1479 \param theMainGroups list of main groups
1480 \param theToolGroups list of tool groups
1481 \param theName name of group to be created
1482 \return pointer on the group
1484 //=============================================================================
1485 SMESH::SMESH_Group_ptr
1486 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1487 const SMESH::ListOfGroups& theToolGroups,
1488 const char* theName )
1489 throw (SALOME::SALOME_Exception)
1491 SMESH::SMESH_Group_var aResGrp;
1496 _preMeshInfo->FullLoadFromFile();
1499 return SMESH::SMESH_Group::_nil();
1501 // check types and get SMESHDS_GroupBase's
1502 SMESH::ElementType aType = SMESH::ALL;
1503 vector< SMESHDS_GroupBase* > toolGroupVec;
1504 vector< SMDS_ElemIteratorPtr > mainIterVec;
1506 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1508 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1509 if ( CORBA::is_nil( aGrp ) )
1511 if ( aType == SMESH::ALL )
1512 aType = aGrp->GetType();
1513 else if ( aType != aGrp->GetType() )
1514 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1516 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1517 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1518 if ( !grpDS->IsEmpty() )
1519 mainIterVec.push_back( grpDS->GetElements() );
1521 if ( aType == SMESH::ALL ) // all main groups are nil
1522 return SMESH::SMESH_Group::_nil();
1523 if ( mainIterVec.empty() ) // all main groups are empty
1524 return aResGrp._retn();
1526 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1528 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1529 if ( CORBA::is_nil( aGrp ) )
1531 if ( aType != aGrp->GetType() )
1532 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1534 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1535 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1536 toolGroupVec.push_back( grpDS );
1542 aResGrp = CreateGroup( aType, theName );
1544 SMESHDS_Group* resGroupDS = 0;
1545 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1546 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1548 return aResGrp._retn();
1551 size_t i, nb = toolGroupVec.size();
1552 SMDS_ElemIteratorPtr mainElemIt
1553 ( new SMDS_IteratorOnIterators
1554 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1555 while ( mainElemIt->more() )
1557 const SMDS_MeshElement* e = mainElemIt->next();
1559 for ( i = 0; ( i < nb && !isIn ); ++i )
1560 isIn = toolGroupVec[i]->Contains( e );
1563 resGroupDS->SMDSGroup().Add( e );
1566 // Update Python script
1567 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1568 << ".CutListOfGroups( " << theMainGroups
1569 << theToolGroups << ", '" << theName << "' )";
1571 SMESH_CATCH( SMESH::throwCorbaException );
1573 return aResGrp._retn();
1576 //=============================================================================
1578 \brief Create groups of entities from existing groups of superior dimensions
1580 1) extract all nodes from each group,
1581 2) combine all elements of specified dimension laying on these nodes.
1582 \param theGroups list of source groups
1583 \param theElemType dimension of elements
1584 \param theName name of new group
1585 \return pointer on new group
1589 //=============================================================================
1591 SMESH::SMESH_Group_ptr
1592 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1593 SMESH::ElementType theElemType,
1594 const char* theName )
1595 throw (SALOME::SALOME_Exception)
1597 SMESH::SMESH_Group_var aResGrp;
1601 _preMeshInfo->FullLoadFromFile();
1603 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1605 if ( !theName || !aMeshDS )
1606 return SMESH::SMESH_Group::_nil();
1608 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1614 aResGrp = CreateGroup( theElemType, theName );
1615 if ( aResGrp->_is_nil() )
1616 return SMESH::SMESH_Group::_nil();
1618 SMESHDS_GroupBase* groupBaseDS =
1619 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1620 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1622 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1624 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1625 if ( CORBA::is_nil( aGrp ) )
1628 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1629 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1631 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1633 while ( elIt->more() ) {
1634 const SMDS_MeshElement* el = elIt->next();
1635 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1636 while ( nIt->more() )
1637 resGroupCore.Add( nIt->next() );
1640 else // get elements of theElemType based on nodes of every element of group
1642 while ( elIt->more() )
1644 const SMDS_MeshElement* el = elIt->next(); // an element of group
1645 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1646 TIDSortedElemSet checkedElems;
1647 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1648 while ( nIt->more() )
1650 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1651 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1652 // check nodes of elements of theElemType around el
1653 while ( elOfTypeIt->more() )
1655 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1656 if ( !checkedElems.insert( elOfType ).second ) continue;
1658 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1659 bool allNodesOK = true;
1660 while ( nIt2->more() && allNodesOK )
1661 allNodesOK = elNodes.count( nIt2->next() );
1663 resGroupCore.Add( elOfType );
1670 // Update Python script
1671 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1672 << ".CreateDimGroup( "
1673 << theGroups << ", " << theElemType << ", '" << theName << "' )";
1675 SMESH_CATCH( SMESH::throwCorbaException );
1677 return aResGrp._retn();
1680 //================================================================================
1682 * \brief Remember GEOM group data
1684 //================================================================================
1686 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1687 CORBA::Object_ptr theSmeshObj)
1689 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1692 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1693 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1694 if ( groupSO->_is_nil() )
1697 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1698 GEOM::GEOM_IGroupOperations_wrap groupOp =
1699 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1700 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1703 _geomGroupData.push_back( TGeomGroupData() );
1704 TGeomGroupData & groupData = _geomGroupData.back();
1706 CORBA::String_var entry = groupSO->GetID();
1707 groupData._groupEntry = entry.in();
1709 for ( int i = 0; i < ids->length(); ++i )
1710 groupData._indices.insert( ids[i] );
1712 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1713 // shape index in SMESHDS
1714 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1715 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1718 //================================================================================
1720 * Remove GEOM group data relating to removed smesh object
1722 //================================================================================
1724 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1726 list<TGeomGroupData>::iterator
1727 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1728 for ( ; data != dataEnd; ++data ) {
1729 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1730 _geomGroupData.erase( data );
1736 //================================================================================
1738 * \brief Return new group contents if it has been changed and update group data
1740 //================================================================================
1742 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1744 TopoDS_Shape newShape;
1747 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1748 if ( study->_is_nil() ) return newShape; // means "not changed"
1749 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1750 if ( !groupSO->_is_nil() )
1752 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1753 if ( CORBA::is_nil( groupObj )) return newShape;
1754 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1756 // get indices of group items
1757 set<int> curIndices;
1758 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1759 GEOM::GEOM_IGroupOperations_wrap groupOp =
1760 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1761 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1762 for ( int i = 0; i < ids->length(); ++i )
1763 curIndices.insert( ids[i] );
1765 if ( groupData._indices == curIndices )
1766 return newShape; // group not changed
1769 groupData._indices = curIndices;
1771 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1772 if ( !geomClient ) return newShape;
1773 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1774 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1775 newShape = _gen_i->GeomObjectToShape( geomGroup );
1778 if ( newShape.IsNull() ) {
1779 // geom group becomes empty - return empty compound
1780 TopoDS_Compound compound;
1781 BRep_Builder().MakeCompound(compound);
1782 newShape = compound;
1789 //-----------------------------------------------------------------------------
1791 * \brief Storage of shape and index used in CheckGeomGroupModif()
1793 struct TIndexedShape
1796 TopoDS_Shape _shape;
1797 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1799 //-----------------------------------------------------------------------------
1801 * \brief Data to re-create a group on geometry
1803 struct TGroupOnGeomData
1807 SMDSAbs_ElementType _type;
1809 Quantity_Color _color;
1813 //=============================================================================
1815 * \brief Update data if geometry changes
1819 //=============================================================================
1821 void SMESH_Mesh_i::CheckGeomModif()
1823 if ( !_impl->HasShapeToMesh() ) return;
1825 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1826 if ( study->_is_nil() ) return;
1828 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1829 if ( mainGO->_is_nil() ) return;
1831 if ( mainGO->GetType() == GEOM_GROUP ||
1832 mainGO->GetTick() == _mainShapeTick )
1834 CheckGeomGroupModif();
1838 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1839 if ( !geomClient ) return;
1840 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1841 if ( geomGen->_is_nil() ) return;
1843 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1844 geomClient->RemoveShapeFromBuffer( ior.in() );
1846 // Update data taking into account that
1847 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1850 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1851 if ( newShape.IsNull() )
1854 _mainShapeTick = mainGO->GetTick();
1856 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1858 // store data of groups on geometry
1859 vector< TGroupOnGeomData > groupsData;
1860 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1861 groupsData.reserve( groups.size() );
1862 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1863 for ( ; g != groups.end(); ++g )
1864 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1866 TGroupOnGeomData data;
1867 data._oldID = group->GetID();
1868 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1869 data._type = group->GetType();
1870 data._name = group->GetStoreName();
1871 data._color = group->GetColor();
1872 groupsData.push_back( data );
1874 // store assigned hypotheses
1875 vector< pair< int, THypList > > ids2Hyps;
1876 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
1877 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
1879 const TopoDS_Shape& s = s2hyps.Key();
1880 const THypList& hyps = s2hyps.ChangeValue();
1881 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
1884 // change shape to mesh
1885 int oldNbSubShapes = meshDS->MaxShapeIndex();
1886 _impl->ShapeToMesh( TopoDS_Shape() );
1887 _impl->ShapeToMesh( newShape );
1889 // re-add shapes of geom groups
1890 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
1891 for ( ; data != _geomGroupData.end(); ++data )
1893 TopoDS_Shape newShape = newGroupShape( *data );
1894 if ( !newShape.IsNull() )
1896 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
1898 TopoDS_Compound compound;
1899 BRep_Builder().MakeCompound( compound );
1900 BRep_Builder().Add( compound, newShape );
1901 newShape = compound;
1903 _impl->GetSubMesh( newShape );
1906 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
1907 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
1908 SALOME::INTERNAL_ERROR );
1910 // re-assign hypotheses
1911 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
1913 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
1914 const THypList& hyps = ids2Hyps[i].second;
1915 THypList::const_iterator h = hyps.begin();
1916 for ( ; h != hyps.end(); ++h )
1917 _impl->AddHypothesis( s, (*h)->GetID() );
1921 for ( size_t i = 0; i < groupsData.size(); ++i )
1923 const TGroupOnGeomData& data = groupsData[i];
1925 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
1926 if ( i2g == _mapGroups.end() ) continue;
1928 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
1929 if ( !gr_i ) continue;
1932 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
1933 meshDS->IndexToShape( data._shapeID ));
1936 _mapGroups.erase( i2g );
1940 g->GetGroupDS()->SetColor( data._color );
1941 gr_i->changeLocalId( id );
1942 _mapGroups[ id ] = i2g->second;
1943 if ( data._oldID != id )
1944 _mapGroups.erase( i2g );
1948 // update _mapSubMesh
1949 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
1950 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
1951 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
1955 //=============================================================================
1957 * \brief Update objects depending on changed geom groups
1959 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1960 * issue 0020210: Update of a smesh group after modification of the associated geom group
1962 //=============================================================================
1964 void SMESH_Mesh_i::CheckGeomGroupModif()
1966 if ( !_impl->HasShapeToMesh() ) return;
1968 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1969 if ( study->_is_nil() ) return;
1971 CORBA::Long nbEntities = NbNodes() + NbElements();
1973 // Check if group contents changed
1975 typedef map< string, TopoDS_Shape > TEntry2Geom;
1976 TEntry2Geom newGroupContents;
1978 list<TGeomGroupData>::iterator
1979 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1980 for ( ; data != dataEnd; ++data )
1982 pair< TEntry2Geom::iterator, bool > it_new =
1983 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1984 bool processedGroup = !it_new.second;
1985 TopoDS_Shape& newShape = it_new.first->second;
1986 if ( !processedGroup )
1987 newShape = newGroupShape( *data );
1988 if ( newShape.IsNull() )
1989 continue; // no changes
1992 _preMeshInfo->ForgetOrLoad();
1994 if ( processedGroup ) { // update group indices
1995 list<TGeomGroupData>::iterator data2 = data;
1996 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1997 data->_indices = data2->_indices;
2000 // Update SMESH objects according to new GEOM group contents
2002 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2003 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2005 int oldID = submesh->GetId();
2006 if ( !_mapSubMeshIor.count( oldID ))
2008 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2010 // update hypotheses
2011 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2012 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2013 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2015 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2016 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2018 // care of submeshes
2019 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2020 int newID = newSubmesh->GetId();
2021 if ( newID != oldID ) {
2022 _mapSubMesh [ newID ] = newSubmesh;
2023 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2024 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2025 _mapSubMesh. erase(oldID);
2026 _mapSubMesh_i. erase(oldID);
2027 _mapSubMeshIor.erase(oldID);
2028 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2033 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2034 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2035 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2037 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2039 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2040 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2041 ds->SetShape( newShape );
2046 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2047 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2049 // Remove groups and submeshes basing on removed sub-shapes
2051 TopTools_MapOfShape newShapeMap;
2052 TopoDS_Iterator shapeIt( newShape );
2053 for ( ; shapeIt.More(); shapeIt.Next() )
2054 newShapeMap.Add( shapeIt.Value() );
2056 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2057 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2059 if ( newShapeMap.Contains( shapeIt.Value() ))
2061 TopTools_IndexedMapOfShape oldShapeMap;
2062 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2063 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2065 const TopoDS_Shape& oldShape = oldShapeMap(i);
2066 int oldInd = meshDS->ShapeToIndex( oldShape );
2068 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2069 if ( i_smIor != _mapSubMeshIor.end() ) {
2070 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2073 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2074 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2076 // check if a group bases on oldInd shape
2077 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2078 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2079 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2080 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2082 RemoveGroup( i_grp->second ); // several groups can base on same shape
2083 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2088 // Reassign hypotheses and update groups after setting the new shape to mesh
2090 // collect anassigned hypotheses
2091 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2092 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2093 TShapeHypList assignedHyps;
2094 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2096 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2097 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2098 if ( !hyps.empty() ) {
2099 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2100 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2101 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2104 // collect shapes supporting groups
2105 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2106 TShapeTypeList groupData;
2107 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2108 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2109 for ( ; grIt != groups.end(); ++grIt )
2111 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2113 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2115 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2116 _impl->ShapeToMesh( newShape );
2118 // reassign hypotheses
2119 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2120 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2122 TIndexedShape& geom = indS_hyps->first;
2123 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2124 int oldID = geom._index;
2125 int newID = meshDS->ShapeToIndex( geom._shape );
2126 if ( oldID == 1 ) { // main shape
2128 geom._shape = newShape;
2132 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2133 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2134 // care of submeshes
2135 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2136 if ( newID != oldID ) {
2137 _mapSubMesh [ newID ] = newSubmesh;
2138 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2139 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2140 _mapSubMesh. erase(oldID);
2141 _mapSubMesh_i. erase(oldID);
2142 _mapSubMeshIor.erase(oldID);
2143 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2147 TShapeTypeList::iterator geomType = groupData.begin();
2148 for ( ; geomType != groupData.end(); ++geomType )
2150 const TIndexedShape& geom = geomType->first;
2151 int oldID = geom._index;
2152 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2155 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2156 CORBA::String_var name = groupSO->GetName();
2158 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2160 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2161 group_i->changeLocalId( newID );
2164 break; // everything has been updated
2167 } // loop on group data
2171 CORBA::Long newNbEntities = NbNodes() + NbElements();
2172 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2173 if ( newNbEntities != nbEntities )
2175 // Add all SObjects with icons to soToUpdateIcons
2176 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2178 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2179 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2180 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2182 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2183 i_gr != _mapGroups.end(); ++i_gr ) // groups
2184 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2187 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2188 for ( ; so != soToUpdateIcons.end(); ++so )
2189 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2192 //=============================================================================
2194 * \brief Create standalone group from a group on geometry or filter
2196 //=============================================================================
2198 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2199 throw (SALOME::SALOME_Exception)
2201 SMESH::SMESH_Group_var aGroup;
2206 _preMeshInfo->FullLoadFromFile();
2208 if ( theGroup->_is_nil() )
2209 return aGroup._retn();
2211 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2213 return aGroup._retn();
2215 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2217 const int anId = aGroupToRem->GetLocalID();
2218 if ( !_impl->ConvertToStandalone( anId ) )
2219 return aGroup._retn();
2220 removeGeomGroupData( theGroup );
2222 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2224 // remove old instance of group from own map
2225 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2226 _mapGroups.erase( anId );
2228 SALOMEDS::StudyBuilder_var builder;
2229 SALOMEDS::SObject_wrap aGroupSO;
2230 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2231 if ( !aStudy->_is_nil() ) {
2232 builder = aStudy->NewBuilder();
2233 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2234 if ( !aGroupSO->_is_nil() )
2236 // remove reference to geometry
2237 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2238 for ( ; chItr->More(); chItr->Next() )
2239 // Remove group's child SObject
2240 builder->RemoveObject( chItr->Value() );
2242 // Update Python script
2243 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2244 << ".ConvertToStandalone( " << aGroupSO << " )";
2246 // change icon of Group on Filter
2249 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2250 const int isEmpty = ( elemTypes->length() == 0 );
2253 SALOMEDS::GenericAttribute_wrap anAttr =
2254 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2255 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2256 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2262 // remember new group in own map
2263 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2264 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2266 // register CORBA object for persistence
2267 _gen_i->RegisterObject( aGroup );
2269 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2270 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2271 //aGroup->Register();
2272 aGroupToRem->UnRegister();
2274 SMESH_CATCH( SMESH::throwCorbaException );
2276 return aGroup._retn();
2279 //=============================================================================
2283 //=============================================================================
2285 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2287 if(MYDEBUG) MESSAGE( "createSubMesh" );
2288 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2289 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2290 const int subMeshId = mySubMesh->GetId();
2292 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2293 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2295 _mapSubMesh [subMeshId] = mySubMesh;
2296 _mapSubMesh_i [subMeshId] = subMeshServant;
2297 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2299 subMeshServant->Register();
2301 // register CORBA object for persistence
2302 int nextId = _gen_i->RegisterObject( subMesh );
2303 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2304 else { nextId = 0; } // avoid "unused variable" warning
2306 // to track changes of GEOM groups
2307 addGeomGroupData( theSubShapeObject, subMesh );
2309 return subMesh._retn();
2312 //=======================================================================
2313 //function : getSubMesh
2315 //=======================================================================
2317 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2319 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2320 if ( it == _mapSubMeshIor.end() )
2321 return SMESH::SMESH_subMesh::_nil();
2323 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2326 //=============================================================================
2330 //=============================================================================
2332 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2333 GEOM::GEOM_Object_ptr theSubShapeObject )
2335 bool isHypChanged = false;
2336 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2337 return isHypChanged;
2339 const int subMeshId = theSubMesh->GetId();
2341 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2343 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2345 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2348 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2349 isHypChanged = !hyps.empty();
2350 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2351 for ( ; hyp != hyps.end(); ++hyp )
2352 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2359 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2360 isHypChanged = ( aHypList->length() > 0 );
2361 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2362 removeHypothesis( theSubShapeObject, aHypList[i] );
2365 catch( const SALOME::SALOME_Exception& ) {
2366 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2368 removeGeomGroupData( theSubShapeObject );
2372 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2373 if ( id_smi != _mapSubMesh_i.end() )
2374 id_smi->second->UnRegister();
2376 // remove a CORBA object
2377 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2378 if ( id_smptr != _mapSubMeshIor.end() )
2379 SMESH::SMESH_subMesh_var( id_smptr->second );
2381 _mapSubMesh.erase(subMeshId);
2382 _mapSubMesh_i.erase(subMeshId);
2383 _mapSubMeshIor.erase(subMeshId);
2385 return isHypChanged;
2388 //=============================================================================
2392 //=============================================================================
2394 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2395 const char* theName,
2396 const TopoDS_Shape& theShape,
2397 const SMESH_PredicatePtr& thePredicate )
2399 std::string newName;
2400 if ( !theName || strlen( theName ) == 0 )
2402 std::set< std::string > presentNames;
2403 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2404 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2406 CORBA::String_var name = i_gr->second->GetName();
2407 presentNames.insert( name.in() );
2410 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2411 } while ( !presentNames.insert( newName ).second );
2412 theName = newName.c_str();
2415 SMESH::SMESH_GroupBase_var aGroup;
2416 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2418 SMESH_GroupBase_i* aGroupImpl;
2419 if ( !theShape.IsNull() )
2420 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2421 else if ( thePredicate )
2422 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2424 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2426 aGroup = aGroupImpl->_this();
2427 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2428 aGroupImpl->Register();
2430 // register CORBA object for persistence
2431 int nextId = _gen_i->RegisterObject( aGroup );
2432 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2433 else { nextId = 0; } // avoid "unused variable" warning in release mode
2435 // to track changes of GEOM groups
2436 if ( !theShape.IsNull() ) {
2437 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2438 addGeomGroupData( geom, aGroup );
2441 return aGroup._retn();
2444 //=============================================================================
2446 * SMESH_Mesh_i::removeGroup
2448 * Should be called by ~SMESH_Group_i()
2450 //=============================================================================
2452 void SMESH_Mesh_i::removeGroup( const int theId )
2454 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2455 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2456 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2457 _mapGroups.erase( theId );
2458 removeGeomGroupData( group );
2459 if ( !_impl->RemoveGroup( theId ))
2461 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2462 RemoveGroup( group );
2464 group->UnRegister();
2468 //=============================================================================
2472 //=============================================================================
2474 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2475 throw(SALOME::SALOME_Exception)
2477 SMESH::log_array_var aLog;
2481 _preMeshInfo->FullLoadFromFile();
2483 list < SMESHDS_Command * >logDS = _impl->GetLog();
2484 aLog = new SMESH::log_array;
2486 int lg = logDS.size();
2489 list < SMESHDS_Command * >::iterator its = logDS.begin();
2490 while(its != logDS.end()){
2491 SMESHDS_Command *com = *its;
2492 int comType = com->GetType();
2494 int lgcom = com->GetNumber();
2496 const list < int >&intList = com->GetIndexes();
2497 int inum = intList.size();
2499 list < int >::const_iterator ii = intList.begin();
2500 const list < double >&coordList = com->GetCoords();
2501 int rnum = coordList.size();
2503 list < double >::const_iterator ir = coordList.begin();
2504 aLog[indexLog].commandType = comType;
2505 aLog[indexLog].number = lgcom;
2506 aLog[indexLog].coords.length(rnum);
2507 aLog[indexLog].indexes.length(inum);
2508 for(int i = 0; i < rnum; i++){
2509 aLog[indexLog].coords[i] = *ir;
2510 //MESSAGE(" "<<i<<" "<<ir.Value());
2513 for(int i = 0; i < inum; i++){
2514 aLog[indexLog].indexes[i] = *ii;
2515 //MESSAGE(" "<<i<<" "<<ii.Value());
2524 SMESH_CATCH( SMESH::throwCorbaException );
2526 return aLog._retn();
2530 //=============================================================================
2534 //=============================================================================
2536 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2540 SMESH_CATCH( SMESH::throwCorbaException );
2543 //=============================================================================
2547 //=============================================================================
2549 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2554 //=============================================================================
2558 //=============================================================================
2560 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2565 //=============================================================================
2568 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2569 // issue 0020918: groups removal is caused by hyp modification
2570 // issue 0021208: to forget not loaded mesh data at hyp modification
2571 struct TCallUp_i : public SMESH_Mesh::TCallUp
2573 SMESH_Mesh_i* _mesh;
2574 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2575 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2576 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2577 virtual void Load () { _mesh->Load(); }
2581 //================================================================================
2583 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2585 //================================================================================
2587 void SMESH_Mesh_i::onHypothesisModified()
2590 _preMeshInfo->ForgetOrLoad();
2593 //=============================================================================
2597 //=============================================================================
2599 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2601 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2604 _impl->SetCallUp( new TCallUp_i(this));
2607 //=============================================================================
2611 //=============================================================================
2613 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2615 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2619 //=============================================================================
2621 * Return mesh editor
2623 //=============================================================================
2625 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2626 throw (SALOME::SALOME_Exception)
2628 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2632 _preMeshInfo->FullLoadFromFile();
2634 // Create MeshEditor
2636 _editor = new SMESH_MeshEditor_i( this, false );
2637 aMeshEdVar = _editor->_this();
2639 // Update Python script
2640 TPythonDump() << _editor << " = "
2641 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2643 SMESH_CATCH( SMESH::throwCorbaException );
2645 return aMeshEdVar._retn();
2648 //=============================================================================
2650 * Return mesh edition previewer
2652 //=============================================================================
2654 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2655 throw (SALOME::SALOME_Exception)
2657 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2661 _preMeshInfo->FullLoadFromFile();
2663 if ( !_previewEditor )
2664 _previewEditor = new SMESH_MeshEditor_i( this, true );
2665 aMeshEdVar = _previewEditor->_this();
2667 SMESH_CATCH( SMESH::throwCorbaException );
2669 return aMeshEdVar._retn();
2672 //================================================================================
2674 * \brief Return true if the mesh has been edited since a last total re-compute
2675 * and those modifications may prevent successful partial re-compute
2677 //================================================================================
2679 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2681 Unexpect aCatch(SALOME_SalomeException);
2682 return _impl->HasModificationsToDiscard();
2685 //================================================================================
2687 * \brief Returns a random unique color
2689 //================================================================================
2691 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2693 const int MAX_ATTEMPTS = 100;
2695 double tolerance = 0.5;
2696 SALOMEDS::Color col;
2700 // generate random color
2701 double red = (double)rand() / RAND_MAX;
2702 double green = (double)rand() / RAND_MAX;
2703 double blue = (double)rand() / RAND_MAX;
2704 // check existence in the list of the existing colors
2705 bool matched = false;
2706 std::list<SALOMEDS::Color>::const_iterator it;
2707 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2708 SALOMEDS::Color color = *it;
2709 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2710 matched = tol < tolerance;
2712 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2713 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2721 //=============================================================================
2723 * Sets auto-color mode. If it is on, groups get unique random colors
2725 //=============================================================================
2727 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2729 Unexpect aCatch(SALOME_SalomeException);
2730 _impl->SetAutoColor(theAutoColor);
2732 TPythonDump pyDump; // not to dump group->SetColor() from below code
2733 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2735 std::list<SALOMEDS::Color> aReservedColors;
2736 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2737 for ( ; it != _mapGroups.end(); it++ ) {
2738 if ( CORBA::is_nil( it->second )) continue;
2739 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2740 it->second->SetColor( aColor );
2741 aReservedColors.push_back( aColor );
2745 //=============================================================================
2747 * Returns true if auto-color mode is on
2749 //=============================================================================
2751 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2753 Unexpect aCatch(SALOME_SalomeException);
2754 return _impl->GetAutoColor();
2757 //=============================================================================
2759 * Checks if there are groups with equal names
2761 //=============================================================================
2763 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2765 return _impl->HasDuplicatedGroupNamesMED();
2768 //================================================================================
2770 * \brief Care of a file before exporting mesh into it
2772 //================================================================================
2774 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2776 TCollection_AsciiString aFullName ((char*)file);
2777 OSD_Path aPath (aFullName);
2778 OSD_File aFile (aPath);
2779 if (aFile.Exists()) {
2780 // existing filesystem node
2781 if (aFile.KindOfFile() == OSD_FILE) {
2782 if (aFile.IsWriteable()) {
2787 if (aFile.Failed()) {
2788 TCollection_AsciiString msg ("File ");
2789 msg += aFullName + " cannot be replaced.";
2790 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2793 TCollection_AsciiString msg ("File ");
2794 msg += aFullName + " cannot be overwritten.";
2795 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2798 TCollection_AsciiString msg ("Location ");
2799 msg += aFullName + " is not a file.";
2800 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2803 // nonexisting file; check if it can be created
2805 aFile.Build(OSD_WriteOnly, OSD_Protection());
2806 if (aFile.Failed()) {
2807 TCollection_AsciiString msg ("You cannot create the file ");
2808 msg += aFullName + ". Check the directory existance and access rights.";
2809 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2817 //================================================================================
2819 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2820 * \param file - file name
2821 * \param overwrite - to erase the file or not
2822 * \retval string - mesh name
2824 //================================================================================
2826 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2827 CORBA::Boolean overwrite)
2830 PrepareForWriting(file, overwrite);
2831 string aMeshName = "Mesh";
2832 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2833 if ( !aStudy->_is_nil() ) {
2834 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2835 if ( !aMeshSO->_is_nil() ) {
2836 CORBA::String_var name = aMeshSO->GetName();
2838 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2839 if ( !aStudy->GetProperties()->IsLocked() )
2841 SALOMEDS::GenericAttribute_wrap anAttr;
2842 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2843 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2844 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2845 ASSERT(!aFileName->_is_nil());
2846 aFileName->SetValue(file);
2847 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2848 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2849 ASSERT(!aFileType->_is_nil());
2850 aFileType->SetValue("FICHIERMED");
2854 // Update Python script
2855 // set name of mesh before export
2856 TPythonDump() << _gen_i << ".SetName("
2857 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2859 // check names of groups
2865 //================================================================================
2867 * \brief Export to med file
2869 //================================================================================
2871 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2872 CORBA::Boolean auto_groups,
2873 SMESH::MED_VERSION theVersion,
2874 CORBA::Boolean overwrite,
2875 CORBA::Boolean autoDimension)
2876 throw(SALOME::SALOME_Exception)
2880 _preMeshInfo->FullLoadFromFile();
2882 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2883 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2885 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2886 << file << "', " << auto_groups << ", "
2887 << theVersion << ", " << overwrite << ", "
2888 << autoDimension << " )";
2890 SMESH_CATCH( SMESH::throwCorbaException );
2893 //================================================================================
2895 * \brief Export a mesh to a med file
2897 //================================================================================
2899 void SMESH_Mesh_i::ExportToMED (const char* file,
2900 CORBA::Boolean auto_groups,
2901 SMESH::MED_VERSION theVersion)
2902 throw(SALOME::SALOME_Exception)
2904 ExportToMEDX(file,auto_groups,theVersion,true);
2907 //================================================================================
2909 * \brief Export a mesh to a med file
2911 //================================================================================
2913 void SMESH_Mesh_i::ExportMED (const char* file,
2914 CORBA::Boolean auto_groups)
2915 throw(SALOME::SALOME_Exception)
2917 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2920 //================================================================================
2922 * \brief Export a mesh to a SAUV file
2924 //================================================================================
2926 void SMESH_Mesh_i::ExportSAUV (const char* file,
2927 CORBA::Boolean auto_groups)
2928 throw(SALOME::SALOME_Exception)
2930 Unexpect aCatch(SALOME_SalomeException);
2932 _preMeshInfo->FullLoadFromFile();
2934 string aMeshName = prepareMeshNameAndGroups(file, true);
2935 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2936 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2937 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2941 //================================================================================
2943 * \brief Export a mesh to a DAT file
2945 //================================================================================
2947 void SMESH_Mesh_i::ExportDAT (const char *file)
2948 throw(SALOME::SALOME_Exception)
2950 Unexpect aCatch(SALOME_SalomeException);
2952 _preMeshInfo->FullLoadFromFile();
2954 // Update Python script
2955 // check names of groups
2957 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2960 PrepareForWriting(file);
2961 _impl->ExportDAT(file);
2964 //================================================================================
2966 * \brief Export a mesh to an UNV file
2968 //================================================================================
2970 void SMESH_Mesh_i::ExportUNV (const char *file)
2971 throw(SALOME::SALOME_Exception)
2973 Unexpect aCatch(SALOME_SalomeException);
2975 _preMeshInfo->FullLoadFromFile();
2977 // Update Python script
2978 // check names of groups
2980 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2983 PrepareForWriting(file);
2984 _impl->ExportUNV(file);
2987 //================================================================================
2989 * \brief Export a mesh to an STL file
2991 //================================================================================
2993 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2994 throw(SALOME::SALOME_Exception)
2996 Unexpect aCatch(SALOME_SalomeException);
2998 _preMeshInfo->FullLoadFromFile();
3000 // Update Python script
3001 // check names of groups
3003 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3004 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3007 PrepareForWriting(file);
3008 _impl->ExportSTL(file, isascii);
3011 //================================================================================
3013 * \brief Export a part of mesh to a med file
3015 //================================================================================
3017 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3019 CORBA::Boolean auto_groups,
3020 SMESH::MED_VERSION version,
3021 CORBA::Boolean overwrite,
3022 CORBA::Boolean autoDimension,
3023 const GEOM::ListOfFields& fields,
3024 const char* geomAssocFields)
3025 throw (SALOME::SALOME_Exception)
3029 _preMeshInfo->FullLoadFromFile();
3032 bool have0dField = false;
3033 if ( fields.length() > 0 )
3035 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3036 if ( shapeToMesh->_is_nil() )
3037 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3039 for ( size_t i = 0; i < fields.length(); ++i )
3041 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3042 THROW_SALOME_CORBA_EXCEPTION
3043 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3044 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3045 if ( fieldShape->_is_nil() )
3046 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3047 if ( !fieldShape->IsSame( shapeToMesh ) )
3048 THROW_SALOME_CORBA_EXCEPTION
3049 ( "Field defined not on shape", SALOME::BAD_PARAM);
3050 if ( fields[i]->GetDimension() == 0 )
3053 if ( geomAssocFields )
3054 for ( int i = 0; geomAssocFields[i]; ++i )
3055 switch ( geomAssocFields[i] ) {
3056 case 'v':case 'e':case 'f':case 's': break;
3057 case 'V':case 'E':case 'F':case 'S': break;
3058 default: THROW_SALOME_CORBA_EXCEPTION
3059 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3063 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3067 string aMeshName = "Mesh";
3068 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3069 if ( CORBA::is_nil( meshPart ) ||
3070 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3072 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3073 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3074 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3075 meshDS = _impl->GetMeshDS();
3080 _preMeshInfo->FullLoadFromFile();
3082 PrepareForWriting(file, overwrite);
3084 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3085 if ( !aStudy->_is_nil() ) {
3086 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3087 if ( !SO->_is_nil() ) {
3088 CORBA::String_var name = SO->GetName();
3092 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3093 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3094 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3095 meshDS = tmpDSDeleter._obj = partDS;
3100 if ( _impl->HasShapeToMesh() )
3102 DriverMED_W_Field fieldWriter;
3103 fieldWriter.SetFile( file );
3104 fieldWriter.SetMeshName( aMeshName );
3105 fieldWriter.AddODOnVertices( have0dField );
3107 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3111 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3112 goList->length( fields.length() );
3113 for ( size_t i = 0; i < fields.length(); ++i )
3115 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3118 TPythonDump() << _this() << ".ExportPartToMED( "
3119 << meshPart << ", r'" << file << "', "
3120 << auto_groups << ", " << version << ", " << overwrite << ", "
3121 << autoDimension << ", " << goList
3122 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3124 SMESH_CATCH( SMESH::throwCorbaException );
3127 //================================================================================
3129 * Write GEOM fields to MED file
3131 //================================================================================
3133 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3134 SMESHDS_Mesh* meshDS,
3135 const GEOM::ListOfFields& fields,
3136 const char* geomAssocFields)
3138 #define METH "SMESH_Mesh_i::exportMEDFields() "
3140 if (( fields.length() < 1 ) &&
3141 ( !geomAssocFields || !geomAssocFields[0] ))
3144 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3145 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3146 std::vector< int > subIdsByDim[ 4 ];
3147 const double noneDblValue = 0.;
3148 const double noneIntValue = 0;
3150 for ( size_t iF = 0; iF < fields.length(); ++iF )
3154 int dim = fields[ iF ]->GetDimension();
3155 SMDSAbs_ElementType elemType;
3156 TopAbs_ShapeEnum shapeType;
3158 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3159 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3160 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3161 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3163 continue; // skip fields on whole shape
3165 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3166 if ( dataType == GEOM::FDT_String )
3168 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3169 if ( stepIDs->length() < 1 )
3171 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3172 if ( comps->length() < 1 )
3174 CORBA::String_var name = fields[ iF ]->GetName();
3176 if ( !fieldWriter.Set( meshDS,
3180 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3183 for ( size_t iC = 0; iC < comps->length(); ++iC )
3184 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3186 // find sub-shape IDs
3188 std::vector< int >& subIds = subIdsByDim[ dim ];
3189 if ( subIds.empty() )
3190 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3191 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3192 subIds.push_back( id );
3196 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3200 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3202 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3203 if ( step->_is_nil() )
3206 CORBA::Long stamp = step->GetStamp();
3207 CORBA::Long id = step->GetID();
3208 fieldWriter.SetDtIt( int( stamp ), int( id ));
3210 // fill dblVals or intVals
3213 case GEOM::FDT_Double:
3215 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3216 if ( dblStep->_is_nil() ) continue;
3217 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3218 if ( vv->length() != subIds.size() )
3219 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3220 for ( size_t i = 0; i < vv->length(); ++i )
3221 dblVals[ subIds[ i ]] = vv[ i ];
3226 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3227 if ( intStep->_is_nil() ) continue;
3228 GEOM::ListOfLong_var vv = intStep->GetValues();
3229 if ( vv->length() != subIds.size() )
3230 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3231 for ( size_t i = 0; i < vv->length(); ++i )
3232 intVals[ subIds[ i ]] = (int) vv[ i ];
3235 case GEOM::FDT_Bool:
3237 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3238 if ( boolStep->_is_nil() ) continue;
3239 GEOM::short_array_var vv = boolStep->GetValues();
3240 if ( vv->length() != subIds.size() )
3241 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3242 for ( size_t i = 0; i < vv->length(); ++i )
3243 intVals[ subIds[ i ]] = (int) vv[ i ];
3249 // pass values to fieldWriter
3250 elemIt = fieldWriter.GetOrderedElems();
3251 if ( dataType == GEOM::FDT_Double )
3252 while ( elemIt->more() )
3254 const SMDS_MeshElement* e = elemIt->next();
3255 const int shapeID = e->getshapeId();
3256 if ( shapeID < 1 || shapeID >= dblVals.size() )
3257 fieldWriter.AddValue( noneDblValue );
3259 fieldWriter.AddValue( dblVals[ shapeID ]);
3262 while ( elemIt->more() )
3264 const SMDS_MeshElement* e = elemIt->next();
3265 const int shapeID = e->getshapeId();
3266 if ( shapeID < 1 || shapeID >= intVals.size() )
3267 fieldWriter.AddValue( (double) noneIntValue );
3269 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3273 fieldWriter.Perform();
3274 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3275 if ( res && res->IsKO() )
3277 if ( res->myComment.empty() )
3278 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3280 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3286 if ( !geomAssocFields || !geomAssocFields[0] )
3289 // write geomAssocFields
3291 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3292 shapeDim[ TopAbs_COMPOUND ] = 3;
3293 shapeDim[ TopAbs_COMPSOLID ] = 3;
3294 shapeDim[ TopAbs_SOLID ] = 3;
3295 shapeDim[ TopAbs_SHELL ] = 2;
3296 shapeDim[ TopAbs_FACE ] = 2;
3297 shapeDim[ TopAbs_WIRE ] = 1;
3298 shapeDim[ TopAbs_EDGE ] = 1;
3299 shapeDim[ TopAbs_VERTEX ] = 0;
3300 shapeDim[ TopAbs_SHAPE ] = 3;
3302 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3304 std::vector< std::string > compNames;
3305 switch ( geomAssocFields[ iF ]) {
3307 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3308 compNames.push_back( "dim" );
3311 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3314 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3317 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3321 compNames.push_back( "id" );
3322 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3323 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3325 fieldWriter.SetDtIt( -1, -1 );
3327 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3331 if ( compNames.size() == 2 ) // _vertices_
3332 while ( elemIt->more() )
3334 const SMDS_MeshElement* e = elemIt->next();
3335 const int shapeID = e->getshapeId();
3338 fieldWriter.AddValue( (double) -1 );
3339 fieldWriter.AddValue( (double) -1 );
3343 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3344 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3345 fieldWriter.AddValue( (double) shapeID );
3349 while ( elemIt->more() )
3351 const SMDS_MeshElement* e = elemIt->next();
3352 const int shapeID = e->getshapeId();
3354 fieldWriter.AddValue( (double) -1 );
3356 fieldWriter.AddValue( (double) shapeID );
3360 fieldWriter.Perform();
3361 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3362 if ( res && res->IsKO() )
3364 if ( res->myComment.empty() )
3365 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3367 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3370 } // loop on geomAssocFields
3375 //================================================================================
3377 * \brief Export a part of mesh to a DAT file
3379 //================================================================================
3381 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3383 throw (SALOME::SALOME_Exception)
3385 Unexpect aCatch(SALOME_SalomeException);
3387 _preMeshInfo->FullLoadFromFile();
3389 PrepareForWriting(file);
3391 SMESH_MeshPartDS partDS( meshPart );
3392 _impl->ExportDAT(file,&partDS);
3394 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3395 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3397 //================================================================================
3399 * \brief Export a part of mesh to an UNV file
3401 //================================================================================
3403 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3405 throw (SALOME::SALOME_Exception)
3407 Unexpect aCatch(SALOME_SalomeException);
3409 _preMeshInfo->FullLoadFromFile();
3411 PrepareForWriting(file);
3413 SMESH_MeshPartDS partDS( meshPart );
3414 _impl->ExportUNV(file, &partDS);
3416 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3417 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3419 //================================================================================
3421 * \brief Export a part of mesh to an STL file
3423 //================================================================================
3425 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3427 ::CORBA::Boolean isascii)
3428 throw (SALOME::SALOME_Exception)
3430 Unexpect aCatch(SALOME_SalomeException);
3432 _preMeshInfo->FullLoadFromFile();
3434 PrepareForWriting(file);
3436 SMESH_MeshPartDS partDS( meshPart );
3437 _impl->ExportSTL(file, isascii, &partDS);
3439 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3440 << meshPart<< ", r'" << file << "', " << isascii << ")";
3443 //================================================================================
3445 * \brief Export a part of mesh to an STL file
3447 //================================================================================
3449 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3451 CORBA::Boolean overwrite)
3452 throw (SALOME::SALOME_Exception)
3455 Unexpect aCatch(SALOME_SalomeException);
3457 _preMeshInfo->FullLoadFromFile();
3459 PrepareForWriting(file,overwrite);
3461 SMESH_MeshPartDS partDS( meshPart );
3462 _impl->ExportCGNS(file, &partDS);
3464 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3465 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3467 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3471 //================================================================================
3473 * \brief Export a part of mesh to a GMF file
3475 //================================================================================
3477 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3479 bool withRequiredGroups)
3480 throw (SALOME::SALOME_Exception)
3482 Unexpect aCatch(SALOME_SalomeException);
3484 _preMeshInfo->FullLoadFromFile();
3486 PrepareForWriting(file,/*overwrite=*/true);
3488 SMESH_MeshPartDS partDS( meshPart );
3489 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3491 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3492 << meshPart<< ", r'"
3494 << withRequiredGroups << ")";
3497 //=============================================================================
3499 * Return computation progress [0.,1]
3501 //=============================================================================
3503 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3507 return _impl->GetComputeProgress();
3509 SMESH_CATCH( SMESH::doNothing );
3513 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3515 Unexpect aCatch(SALOME_SalomeException);
3517 return _preMeshInfo->NbNodes();
3519 return _impl->NbNodes();
3522 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3524 Unexpect aCatch(SALOME_SalomeException);
3526 return _preMeshInfo->NbElements();
3528 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3531 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3533 Unexpect aCatch(SALOME_SalomeException);
3535 return _preMeshInfo->Nb0DElements();
3537 return _impl->Nb0DElements();
3540 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3542 Unexpect aCatch(SALOME_SalomeException);
3544 return _preMeshInfo->NbBalls();
3546 return _impl->NbBalls();
3549 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3551 Unexpect aCatch(SALOME_SalomeException);
3553 return _preMeshInfo->NbEdges();
3555 return _impl->NbEdges();
3558 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3559 throw(SALOME::SALOME_Exception)
3561 Unexpect aCatch(SALOME_SalomeException);
3563 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3565 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3568 //=============================================================================
3570 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3572 Unexpect aCatch(SALOME_SalomeException);
3574 return _preMeshInfo->NbFaces();
3576 return _impl->NbFaces();
3579 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3581 Unexpect aCatch(SALOME_SalomeException);
3583 return _preMeshInfo->NbTriangles();
3585 return _impl->NbTriangles();
3588 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3590 Unexpect aCatch(SALOME_SalomeException);
3592 return _preMeshInfo->NbBiQuadTriangles();
3594 return _impl->NbBiQuadTriangles();
3597 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3599 Unexpect aCatch(SALOME_SalomeException);
3601 return _preMeshInfo->NbQuadrangles();
3603 return _impl->NbQuadrangles();
3606 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3608 Unexpect aCatch(SALOME_SalomeException);
3610 return _preMeshInfo->NbBiQuadQuadrangles();
3612 return _impl->NbBiQuadQuadrangles();
3615 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3617 Unexpect aCatch(SALOME_SalomeException);
3619 return _preMeshInfo->NbPolygons();
3621 return _impl->NbPolygons();
3624 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3625 throw(SALOME::SALOME_Exception)
3627 Unexpect aCatch(SALOME_SalomeException);
3629 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3631 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3634 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3635 throw(SALOME::SALOME_Exception)
3637 Unexpect aCatch(SALOME_SalomeException);
3639 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3641 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3644 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3645 throw(SALOME::SALOME_Exception)
3647 Unexpect aCatch(SALOME_SalomeException);
3649 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3651 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3654 //=============================================================================
3656 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3658 Unexpect aCatch(SALOME_SalomeException);
3660 return _preMeshInfo->NbVolumes();
3662 return _impl->NbVolumes();
3665 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3667 Unexpect aCatch(SALOME_SalomeException);
3669 return _preMeshInfo->NbTetras();
3671 return _impl->NbTetras();
3674 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3676 Unexpect aCatch(SALOME_SalomeException);
3678 return _preMeshInfo->NbHexas();
3680 return _impl->NbHexas();
3683 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3685 Unexpect aCatch(SALOME_SalomeException);
3687 return _preMeshInfo->NbTriQuadHexas();
3689 return _impl->NbTriQuadraticHexas();
3692 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3694 Unexpect aCatch(SALOME_SalomeException);
3696 return _preMeshInfo->NbPyramids();
3698 return _impl->NbPyramids();
3701 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3703 Unexpect aCatch(SALOME_SalomeException);
3705 return _preMeshInfo->NbPrisms();
3707 return _impl->NbPrisms();
3710 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3712 Unexpect aCatch(SALOME_SalomeException);
3714 return _preMeshInfo->NbHexPrisms();
3716 return _impl->NbHexagonalPrisms();
3719 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3721 Unexpect aCatch(SALOME_SalomeException);
3723 return _preMeshInfo->NbPolyhedrons();
3725 return _impl->NbPolyhedrons();
3728 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3729 throw(SALOME::SALOME_Exception)
3731 Unexpect aCatch(SALOME_SalomeException);
3733 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3735 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3738 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3739 throw(SALOME::SALOME_Exception)
3741 Unexpect aCatch(SALOME_SalomeException);
3743 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3745 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3748 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3749 throw(SALOME::SALOME_Exception)
3751 Unexpect aCatch(SALOME_SalomeException);
3753 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3755 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3758 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3759 throw(SALOME::SALOME_Exception)
3761 Unexpect aCatch(SALOME_SalomeException);
3763 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3765 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3768 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3769 throw(SALOME::SALOME_Exception)
3771 Unexpect aCatch(SALOME_SalomeException);
3773 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3775 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3778 //=============================================================================
3780 * Returns nb of published sub-meshes
3782 //=============================================================================
3784 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3786 Unexpect aCatch(SALOME_SalomeException);
3787 return _mapSubMesh_i.size();
3790 //=============================================================================
3792 * Dumps mesh into a string
3794 //=============================================================================
3796 char* SMESH_Mesh_i::Dump()
3800 return CORBA::string_dup( os.str().c_str() );
3803 //=============================================================================
3805 * Method of SMESH_IDSource interface
3807 //=============================================================================
3809 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3811 return GetElementsId();
3814 //=============================================================================
3816 * Returns ids of all elements
3818 //=============================================================================
3820 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3821 throw (SALOME::SALOME_Exception)
3823 Unexpect aCatch(SALOME_SalomeException);
3825 _preMeshInfo->FullLoadFromFile();
3827 SMESH::long_array_var aResult = new SMESH::long_array();
3828 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3830 if ( aSMESHDS_Mesh == NULL )
3831 return aResult._retn();
3833 long nbElements = NbElements();
3834 aResult->length( nbElements );
3835 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3836 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3837 aResult[i] = anIt->next()->GetID();
3839 return aResult._retn();
3843 //=============================================================================
3845 * Returns ids of all elements of given type
3847 //=============================================================================
3849 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3850 throw (SALOME::SALOME_Exception)
3852 Unexpect aCatch(SALOME_SalomeException);
3854 _preMeshInfo->FullLoadFromFile();
3856 SMESH::long_array_var aResult = new SMESH::long_array();
3857 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3859 if ( aSMESHDS_Mesh == NULL )
3860 return aResult._retn();
3862 long nbElements = NbElements();
3864 // No sense in returning ids of elements along with ids of nodes:
3865 // when theElemType == SMESH::ALL, return node ids only if
3866 // there are no elements
3867 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3868 return GetNodesId();
3870 aResult->length( nbElements );
3874 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3875 while ( i < nbElements && anIt->more() )
3876 aResult[i++] = anIt->next()->GetID();
3878 aResult->length( i );
3880 return aResult._retn();
3883 //=============================================================================
3885 * Returns ids of all nodes
3887 //=============================================================================
3889 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3890 throw (SALOME::SALOME_Exception)
3892 Unexpect aCatch(SALOME_SalomeException);
3894 _preMeshInfo->FullLoadFromFile();
3896 SMESH::long_array_var aResult = new SMESH::long_array();
3897 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3899 if ( aSMESHDS_Mesh == NULL )
3900 return aResult._retn();
3902 long nbNodes = NbNodes();
3903 aResult->length( nbNodes );
3904 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3905 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3906 aResult[i] = anIt->next()->GetID();
3908 return aResult._retn();
3911 //=============================================================================
3915 //=============================================================================
3917 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3918 throw (SALOME::SALOME_Exception)
3920 SMESH::ElementType type;
3924 _preMeshInfo->FullLoadFromFile();
3926 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3928 SMESH_CATCH( SMESH::throwCorbaException );
3933 //=============================================================================
3937 //=============================================================================
3939 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3940 throw (SALOME::SALOME_Exception)
3943 _preMeshInfo->FullLoadFromFile();
3945 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3947 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3949 return ( SMESH::EntityType ) e->GetEntityType();
3952 //=============================================================================
3956 //=============================================================================
3958 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3959 throw (SALOME::SALOME_Exception)
3962 _preMeshInfo->FullLoadFromFile();
3964 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3966 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3968 return ( SMESH::GeometryType ) e->GetGeomType();
3971 //=============================================================================
3973 * Returns ID of elements for given submesh
3975 //=============================================================================
3976 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3977 throw (SALOME::SALOME_Exception)
3979 SMESH::long_array_var aResult = new SMESH::long_array();
3983 _preMeshInfo->FullLoadFromFile();
3985 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3986 if(!SM) return aResult._retn();
3988 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3989 if(!SDSM) return aResult._retn();
3991 aResult->length(SDSM->NbElements());
3993 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3995 while ( eIt->more() ) {
3996 aResult[i++] = eIt->next()->GetID();
3999 SMESH_CATCH( SMESH::throwCorbaException );
4001 return aResult._retn();
4004 //=============================================================================
4006 * Returns ID of nodes for given submesh
4007 * If param all==true - returns all nodes, else -
4008 * returns only nodes on shapes.
4010 //=============================================================================
4012 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4014 throw (SALOME::SALOME_Exception)
4016 SMESH::long_array_var aResult = new SMESH::long_array();
4020 _preMeshInfo->FullLoadFromFile();
4022 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4023 if(!SM) return aResult._retn();
4025 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4026 if(!SDSM) return aResult._retn();
4029 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4030 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4031 while ( nIt->more() ) {
4032 const SMDS_MeshNode* elem = nIt->next();
4033 theElems.insert( elem->GetID() );
4036 else { // all nodes of submesh elements
4037 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4038 while ( eIt->more() ) {
4039 const SMDS_MeshElement* anElem = eIt->next();
4040 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4041 while ( nIt->more() ) {
4042 const SMDS_MeshElement* elem = nIt->next();
4043 theElems.insert( elem->GetID() );
4048 aResult->length(theElems.size());
4049 set<int>::iterator itElem;
4051 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4052 aResult[i++] = *itElem;
4054 SMESH_CATCH( SMESH::throwCorbaException );
4056 return aResult._retn();
4059 //=============================================================================
4061 * Returns type of elements for given submesh
4063 //=============================================================================
4065 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4066 throw (SALOME::SALOME_Exception)
4068 SMESH::ElementType type;
4072 _preMeshInfo->FullLoadFromFile();
4074 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4075 if(!SM) return SMESH::ALL;
4077 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4078 if(!SDSM) return SMESH::ALL;
4080 if(SDSM->NbElements()==0)
4081 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4083 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4084 const SMDS_MeshElement* anElem = eIt->next();
4086 type = ( SMESH::ElementType ) anElem->GetType();
4088 SMESH_CATCH( SMESH::throwCorbaException );
4094 //=============================================================================
4096 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4098 //=============================================================================
4100 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4103 _preMeshInfo->FullLoadFromFile();
4105 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4107 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4112 //=============================================================================
4114 * Get XYZ coordinates of node as list of double
4115 * If there is not node for given ID - returns empty list
4117 //=============================================================================
4119 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4122 _preMeshInfo->FullLoadFromFile();
4124 SMESH::double_array_var aResult = new SMESH::double_array();
4125 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4126 if ( aSMESHDS_Mesh == NULL )
4127 return aResult._retn();
4130 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4132 return aResult._retn();
4136 aResult[0] = aNode->X();
4137 aResult[1] = aNode->Y();
4138 aResult[2] = aNode->Z();
4139 return aResult._retn();
4143 //=============================================================================
4145 * For given node returns list of IDs of inverse elements
4146 * If there is not node for given ID - returns empty list
4148 //=============================================================================
4150 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4153 _preMeshInfo->FullLoadFromFile();
4155 SMESH::long_array_var aResult = new SMESH::long_array();
4156 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4157 if ( aSMESHDS_Mesh == NULL )
4158 return aResult._retn();
4161 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4163 return aResult._retn();
4165 // find inverse elements
4166 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4167 TColStd_SequenceOfInteger IDs;
4168 while(eIt->more()) {
4169 const SMDS_MeshElement* elem = eIt->next();
4170 IDs.Append(elem->GetID());
4172 if(IDs.Length()>0) {
4173 aResult->length(IDs.Length());
4175 for(; i<=IDs.Length(); i++) {
4176 aResult[i-1] = IDs.Value(i);
4179 return aResult._retn();
4182 //=============================================================================
4184 * \brief Return position of a node on shape
4186 //=============================================================================
4188 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4191 _preMeshInfo->FullLoadFromFile();
4193 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4194 aNodePosition->shapeID = 0;
4195 aNodePosition->shapeType = GEOM::SHAPE;
4197 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4198 if ( !mesh ) return aNodePosition;
4200 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4202 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4204 aNodePosition->shapeID = aNode->getshapeId();
4205 switch ( pos->GetTypeOfPosition() ) {
4207 aNodePosition->shapeType = GEOM::EDGE;
4208 aNodePosition->params.length(1);
4209 aNodePosition->params[0] =
4210 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4213 aNodePosition->shapeType = GEOM::FACE;
4214 aNodePosition->params.length(2);
4215 aNodePosition->params[0] =
4216 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4217 aNodePosition->params[1] =
4218 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4220 case SMDS_TOP_VERTEX:
4221 aNodePosition->shapeType = GEOM::VERTEX;
4223 case SMDS_TOP_3DSPACE:
4224 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4225 aNodePosition->shapeType = GEOM::SOLID;
4226 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4227 aNodePosition->shapeType = GEOM::SHELL;
4233 return aNodePosition;
4236 //=============================================================================
4238 * \brief Return position of an element on shape
4240 //=============================================================================
4242 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4245 _preMeshInfo->FullLoadFromFile();
4247 SMESH::ElementPosition anElementPosition;
4248 anElementPosition.shapeID = 0;
4249 anElementPosition.shapeType = GEOM::SHAPE;
4251 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4252 if ( !mesh ) return anElementPosition;
4254 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4256 anElementPosition.shapeID = anElem->getshapeId();
4257 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4258 if ( !aSp.IsNull() ) {
4259 switch ( aSp.ShapeType() ) {
4261 anElementPosition.shapeType = GEOM::EDGE;
4264 anElementPosition.shapeType = GEOM::FACE;
4267 anElementPosition.shapeType = GEOM::VERTEX;
4270 anElementPosition.shapeType = GEOM::SOLID;
4273 anElementPosition.shapeType = GEOM::SHELL;
4279 return anElementPosition;
4282 //=============================================================================
4284 * If given element is node returns IDs of shape from position
4285 * If there is not node for given ID - returns -1
4287 //=============================================================================
4289 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4292 _preMeshInfo->FullLoadFromFile();
4294 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4295 if ( aSMESHDS_Mesh == NULL )
4299 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4301 return aNode->getshapeId();
4308 //=============================================================================
4310 * For given element returns ID of result shape after
4311 * ::FindShape() from SMESH_MeshEditor
4312 * If there is not element for given ID - returns -1
4314 //=============================================================================
4316 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4319 _preMeshInfo->FullLoadFromFile();
4321 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4322 if ( aSMESHDS_Mesh == NULL )
4325 // try to find element
4326 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4330 ::SMESH_MeshEditor aMeshEditor(_impl);
4331 int index = aMeshEditor.FindShape( elem );
4339 //=============================================================================
4341 * Returns number of nodes for given element
4342 * If there is not element for given ID - returns -1
4344 //=============================================================================
4346 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4349 _preMeshInfo->FullLoadFromFile();
4351 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4352 if ( aSMESHDS_Mesh == NULL ) return -1;
4353 // try to find element
4354 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4355 if(!elem) return -1;
4356 return elem->NbNodes();
4360 //=============================================================================
4362 * Returns ID of node by given index for given element
4363 * If there is not element for given ID - returns -1
4364 * If there is not node for given index - returns -2
4366 //=============================================================================
4368 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4371 _preMeshInfo->FullLoadFromFile();
4373 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4374 if ( aSMESHDS_Mesh == NULL ) return -1;
4375 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4376 if(!elem) return -1;
4377 if( index>=elem->NbNodes() || index<0 ) return -1;
4378 return elem->GetNode(index)->GetID();
4381 //=============================================================================
4383 * Returns IDs of nodes of given element
4385 //=============================================================================
4387 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4390 _preMeshInfo->FullLoadFromFile();
4392 SMESH::long_array_var aResult = new SMESH::long_array();
4393 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4395 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4397 aResult->length( elem->NbNodes() );
4398 for ( int i = 0; i < elem->NbNodes(); ++i )
4399 aResult[ i ] = elem->GetNode( i )->GetID();
4402 return aResult._retn();
4405 //=============================================================================
4407 * Returns true if given node is medium node
4408 * in given quadratic element
4410 //=============================================================================
4412 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4415 _preMeshInfo->FullLoadFromFile();
4417 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4418 if ( aSMESHDS_Mesh == NULL ) return false;
4420 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4421 if(!aNode) return false;
4422 // try to find element
4423 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4424 if(!elem) return false;
4426 return elem->IsMediumNode(aNode);
4430 //=============================================================================
4432 * Returns true if given node is medium node
4433 * in one of quadratic elements
4435 //=============================================================================
4437 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4438 SMESH::ElementType theElemType)
4441 _preMeshInfo->FullLoadFromFile();
4443 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4444 if ( aSMESHDS_Mesh == NULL ) return false;
4447 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4448 if(!aNode) return false;
4450 SMESH_MesherHelper aHelper( *(_impl) );
4452 SMDSAbs_ElementType aType;
4453 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4454 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4455 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4456 else aType = SMDSAbs_All;
4458 return aHelper.IsMedium(aNode,aType);
4462 //=============================================================================
4464 * Returns number of edges for given element
4466 //=============================================================================
4468 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4471 _preMeshInfo->FullLoadFromFile();
4473 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4474 if ( aSMESHDS_Mesh == NULL ) return -1;
4475 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4476 if(!elem) return -1;
4477 return elem->NbEdges();
4481 //=============================================================================
4483 * Returns number of faces for given element
4485 //=============================================================================
4487 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4490 _preMeshInfo->FullLoadFromFile();
4492 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4493 if ( aSMESHDS_Mesh == NULL ) return -1;
4494 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4495 if(!elem) return -1;
4496 return elem->NbFaces();
4499 //=======================================================================
4500 //function : GetElemFaceNodes
4501 //purpose : Returns nodes of given face (counted from zero) for given element.
4502 //=======================================================================
4504 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4505 CORBA::Short faceIndex)
4508 _preMeshInfo->FullLoadFromFile();
4510 SMESH::long_array_var aResult = new SMESH::long_array();
4511 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4513 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4515 SMDS_VolumeTool vtool( elem );
4516 if ( faceIndex < vtool.NbFaces() )
4518 aResult->length( vtool.NbFaceNodes( faceIndex ));
4519 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4520 for ( int i = 0; i < aResult->length(); ++i )
4521 aResult[ i ] = nn[ i ]->GetID();
4525 return aResult._retn();
4528 //=======================================================================
4529 //function : GetElemFaceNodes
4530 //purpose : Returns three components of normal of given mesh face.
4531 //=======================================================================
4533 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4534 CORBA::Boolean normalized)
4537 _preMeshInfo->FullLoadFromFile();
4539 SMESH::double_array_var aResult = new SMESH::double_array();
4541 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4544 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4546 aResult->length( 3 );
4547 aResult[ 0 ] = normal.X();
4548 aResult[ 1 ] = normal.Y();
4549 aResult[ 2 ] = normal.Z();
4552 return aResult._retn();
4555 //=======================================================================
4556 //function : FindElementByNodes
4557 //purpose : Returns an element based on all given nodes.
4558 //=======================================================================
4560 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4563 _preMeshInfo->FullLoadFromFile();
4565 CORBA::Long elemID(0);
4566 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4568 vector< const SMDS_MeshNode * > nn( nodes.length() );
4569 for ( int i = 0; i < nodes.length(); ++i )
4570 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4573 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4574 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4575 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4576 _impl->NbVolumes( ORDER_QUADRATIC )))
4577 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4579 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4584 //=============================================================================
4586 * Returns true if given element is polygon
4588 //=============================================================================
4590 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4593 _preMeshInfo->FullLoadFromFile();
4595 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4596 if ( aSMESHDS_Mesh == NULL ) return false;
4597 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4598 if(!elem) return false;
4599 return elem->IsPoly();
4603 //=============================================================================
4605 * Returns true if given element is quadratic
4607 //=============================================================================
4609 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4612 _preMeshInfo->FullLoadFromFile();
4614 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4615 if ( aSMESHDS_Mesh == NULL ) return false;
4616 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4617 if(!elem) return false;
4618 return elem->IsQuadratic();
4621 //=============================================================================
4623 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4625 //=============================================================================
4627 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4630 _preMeshInfo->FullLoadFromFile();
4632 if ( const SMDS_BallElement* ball =
4633 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4634 return ball->GetDiameter();
4639 //=============================================================================
4641 * Returns bary center for given element
4643 //=============================================================================
4645 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4648 _preMeshInfo->FullLoadFromFile();
4650 SMESH::double_array_var aResult = new SMESH::double_array();
4651 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4652 if ( aSMESHDS_Mesh == NULL )
4653 return aResult._retn();
4655 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4657 return aResult._retn();
4659 if(elem->GetType()==SMDSAbs_Volume) {
4660 SMDS_VolumeTool aTool;
4661 if(aTool.Set(elem)) {
4663 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4668 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4670 double x=0., y=0., z=0.;
4671 for(; anIt->more(); ) {
4673 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4687 return aResult._retn();
4690 //================================================================================
4692 * \brief Create a group of elements preventing computation of a sub-shape
4694 //================================================================================
4696 SMESH::ListOfGroups*
4697 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4698 const char* theGroupName )
4699 throw ( SALOME::SALOME_Exception )
4701 Unexpect aCatch(SALOME_SalomeException);
4703 if ( !theGroupName || strlen( theGroupName) == 0 )
4704 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4706 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4708 // submesh by subshape id
4709 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4710 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4713 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4714 if ( error && !error->myBadElements.empty())
4716 // sort bad elements by type
4717 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4718 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4719 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4720 for ( ; elemIt != elemEnd; ++elemIt )
4722 const SMDS_MeshElement* elem = *elemIt;
4723 if ( !elem ) continue;
4725 if ( elem->GetID() < 1 )
4727 // elem is a temporary element, make a real element
4728 vector< const SMDS_MeshNode* > nodes;
4729 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4730 while ( nIt->more() && elem )
4732 nodes.push_back( nIt->next() );
4733 if ( nodes.back()->GetID() < 1 )
4734 elem = 0; // a temporary element on temporary nodes
4738 ::SMESH_MeshEditor editor( _impl );
4739 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4743 elemsByType[ elem->GetType() ].push_back( elem );
4746 // how many groups to create?
4748 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4749 nbTypes += int( !elemsByType[ i ].empty() );
4750 groups->length( nbTypes );
4753 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4755 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4756 if ( elems.empty() ) continue;
4758 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4759 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4761 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4762 SMESH::SMESH_Mesh_var mesh = _this();
4763 SALOMEDS::SObject_wrap aSO =
4764 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4765 GEOM::GEOM_Object::_nil(), theGroupName);
4766 aSO->_is_nil(); // avoid "unused variable" warning
4768 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4769 if ( !grp_i ) continue;
4771 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4772 for ( size_t iE = 0; iE < elems.size(); ++iE )
4773 grpDS->SMDSGroup().Add( elems[ iE ]);
4778 return groups._retn();
4781 //=============================================================================
4783 * Create and publish group servants if any groups were imported or created anyhow
4785 //=============================================================================
4787 void SMESH_Mesh_i::CreateGroupServants()
4789 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4790 SMESH::SMESH_Mesh_var aMesh = _this();
4793 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4794 while ( groupIt->more() )
4796 ::SMESH_Group* group = groupIt->next();
4797 int anId = group->GetGroupDS()->GetID();
4799 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4800 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4802 addedIDs.insert( anId );
4804 SMESH_GroupBase_i* aGroupImpl;
4806 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4807 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4809 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4810 shape = groupOnGeom->GetShape();
4813 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4816 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4817 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4818 aGroupImpl->Register();
4820 // register CORBA object for persistence
4821 int nextId = _gen_i->RegisterObject( groupVar );
4822 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4823 else { nextId = 0; } // avoid "unused variable" warning in release mode
4825 // publishing the groups in the study
4826 if ( !aStudy->_is_nil() ) {
4827 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4828 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4831 if ( !addedIDs.empty() )
4834 set<int>::iterator id = addedIDs.begin();
4835 for ( ; id != addedIDs.end(); ++id )
4837 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4838 int i = std::distance( _mapGroups.begin(), it );
4839 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4844 //=============================================================================
4846 * \brief Return groups cantained in _mapGroups by their IDs
4848 //=============================================================================
4850 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4852 int nbGroups = groupIDs.size();
4853 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4854 aList->length( nbGroups );
4856 list<int>::const_iterator ids = groupIDs.begin();
4857 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4859 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4860 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4861 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4863 aList->length( nbGroups );
4864 return aList._retn();
4867 //=============================================================================
4869 * \brief Return information about imported file
4871 //=============================================================================
4873 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4875 SMESH::MedFileInfo_var res( _medFileInfo );
4876 if ( !res.operator->() ) {
4877 res = new SMESH::MedFileInfo;
4879 res->fileSize = res->major = res->minor = res->release = -1;
4884 //=============================================================================
4886 * \brief Pass names of mesh groups from study to mesh DS
4888 //=============================================================================
4890 void SMESH_Mesh_i::checkGroupNames()
4892 int nbGrp = NbGroups();
4896 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4897 if ( aStudy->_is_nil() )
4898 return; // nothing to do
4900 SMESH::ListOfGroups* grpList = 0;
4901 // avoid dump of "GetGroups"
4903 // store python dump into a local variable inside local scope
4904 SMESH::TPythonDump pDump; // do not delete this line of code
4905 grpList = GetGroups();
4908 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4909 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4912 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4913 if ( aGrpSO->_is_nil() )
4915 // correct name of the mesh group if necessary
4916 const char* guiName = aGrpSO->GetName();
4917 if ( strcmp(guiName, aGrp->GetName()) )
4918 aGrp->SetName( guiName );
4922 //=============================================================================
4924 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4926 //=============================================================================
4927 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4929 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4933 //=============================================================================
4935 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4937 //=============================================================================
4939 char* SMESH_Mesh_i::GetParameters()
4941 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4944 //=============================================================================
4946 * \brief Returns list of notebook variables used for last Mesh operation
4948 //=============================================================================
4949 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4951 SMESH::string_array_var aResult = new SMESH::string_array();
4952 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4954 CORBA::String_var aParameters = GetParameters();
4955 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4956 if ( !aStudy->_is_nil()) {
4957 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4958 if(aSections->length() > 0) {
4959 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4960 aResult->length(aVars.length());
4961 for(int i = 0;i < aVars.length();i++)
4962 aResult[i] = CORBA::string_dup( aVars[i]);
4966 return aResult._retn();
4969 //=======================================================================
4970 //function : GetTypes
4971 //purpose : Returns types of elements it contains
4972 //=======================================================================
4974 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4977 return _preMeshInfo->GetTypes();
4979 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4983 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4984 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4985 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4986 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4987 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4988 types->length( nbTypes );
4990 return types._retn();
4993 //=======================================================================
4994 //function : GetMesh
4995 //purpose : Returns self
4996 //=======================================================================
4998 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5000 return SMESH::SMESH_Mesh::_duplicate( _this() );
5003 //=======================================================================
5004 //function : IsMeshInfoCorrect
5005 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5006 // * happen if mesh data is not yet fully loaded from the file of study.
5007 //=======================================================================
5009 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5011 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5014 //=============================================================================
5016 * \brief Returns number of mesh elements per each \a EntityType
5018 //=============================================================================
5020 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5023 return _preMeshInfo->GetMeshInfo();
5025 SMESH::long_array_var aRes = new SMESH::long_array();
5026 aRes->length(SMESH::Entity_Last);
5027 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5029 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5031 return aRes._retn();
5032 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5033 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5034 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5035 return aRes._retn();
5038 //=============================================================================
5040 * \brief Returns number of mesh elements per each \a ElementType
5042 //=============================================================================
5044 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5046 SMESH::long_array_var aRes = new SMESH::long_array();
5047 aRes->length(SMESH::NB_ELEMENT_TYPES);
5048 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5051 const SMDS_MeshInfo* meshInfo = 0;
5053 meshInfo = _preMeshInfo;
5054 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5055 meshInfo = & meshDS->GetMeshInfo();
5058 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5059 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5061 return aRes._retn();
5064 //=============================================================================
5066 * Collect statistic of mesh elements given by iterator
5068 //=============================================================================
5070 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5071 SMESH::long_array& theInfo)
5073 if (!theItr) return;
5074 while (theItr->more())
5075 theInfo[ theItr->next()->GetEntityType() ]++;
5078 //=============================================================================
5079 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5080 * SMESH::ElementType type) */
5082 using namespace SMESH::Controls;
5083 //-----------------------------------------------------------------------------
5084 struct PredicateIterator : public SMDS_ElemIterator
5086 SMDS_ElemIteratorPtr _elemIter;
5087 PredicatePtr _predicate;
5088 const SMDS_MeshElement* _elem;
5090 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5091 PredicatePtr predicate):
5092 _elemIter(iterator), _predicate(predicate)
5100 virtual const SMDS_MeshElement* next()
5102 const SMDS_MeshElement* res = _elem;
5104 while ( _elemIter->more() && !_elem )
5106 _elem = _elemIter->next();
5107 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5114 //-----------------------------------------------------------------------------
5115 struct IDSourceIterator : public SMDS_ElemIterator
5117 const CORBA::Long* _idPtr;
5118 const CORBA::Long* _idEndPtr;
5119 SMESH::long_array_var _idArray;
5120 const SMDS_Mesh* _mesh;
5121 const SMDSAbs_ElementType _type;
5122 const SMDS_MeshElement* _elem;
5124 IDSourceIterator( const SMDS_Mesh* mesh,
5125 const CORBA::Long* ids,
5127 SMDSAbs_ElementType type):
5128 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5130 if ( _idPtr && nbIds && _mesh )
5133 IDSourceIterator( const SMDS_Mesh* mesh,
5134 SMESH::long_array* idArray,
5135 SMDSAbs_ElementType type):
5136 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5138 if ( idArray && _mesh )
5140 _idPtr = &_idArray[0];
5141 _idEndPtr = _idPtr + _idArray->length();
5149 virtual const SMDS_MeshElement* next()
5151 const SMDS_MeshElement* res = _elem;
5153 while ( _idPtr < _idEndPtr && !_elem )
5155 if ( _type == SMDSAbs_Node )
5157 _elem = _mesh->FindNode( *_idPtr++ );
5159 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5160 _elem->GetType() != _type )
5168 //-----------------------------------------------------------------------------
5170 struct NodeOfElemIterator : public SMDS_ElemIterator
5172 TColStd_MapOfInteger _checkedNodeIDs;
5173 SMDS_ElemIteratorPtr _elemIter;
5174 SMDS_ElemIteratorPtr _nodeIter;
5175 const SMDS_MeshElement* _node;
5177 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5179 if ( _elemIter && _elemIter->more() )
5181 _nodeIter = _elemIter->next()->nodesIterator();
5189 virtual const SMDS_MeshElement* next()
5191 const SMDS_MeshElement* res = _node;
5193 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5195 if ( _nodeIter->more() )
5197 _node = _nodeIter->next();
5198 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5203 _nodeIter = _elemIter->next()->nodesIterator();
5211 //=============================================================================
5213 * Return iterator on elements of given type in given object
5215 //=============================================================================
5217 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5218 SMESH::ElementType theType)
5220 SMDS_ElemIteratorPtr elemIt;
5221 bool typeOK = false;
5222 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5224 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5225 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5226 if ( !mesh_i ) return elemIt;
5227 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5229 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5231 elemIt = meshDS->elementsIterator( elemType );
5234 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5236 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5239 elemIt = sm->GetElements();
5240 if ( elemType != SMDSAbs_Node )
5242 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5243 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5247 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5249 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5250 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5252 elemIt = groupDS->GetElements();
5253 typeOK = ( groupDS->GetType() == elemType );
5256 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5258 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5260 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5261 if ( pred_i && pred_i->GetPredicate() )
5263 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5264 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5265 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5266 typeOK = ( filterType == elemType );
5272 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5273 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5274 if ( isNodes && elemType != SMDSAbs_Node )
5276 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5279 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5280 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5284 SMESH::long_array_var ids = theObject->GetIDs();
5285 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5287 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5290 if ( elemIt && elemIt->more() && !typeOK )
5292 if ( elemType == SMDSAbs_Node )
5294 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5298 elemIt = SMDS_ElemIteratorPtr();
5304 //=============================================================================
5305 namespace // Finding concurrent hypotheses
5306 //=============================================================================
5310 * \brief mapping of mesh dimension into shape type
5312 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5314 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5316 case 0: aType = TopAbs_VERTEX; break;
5317 case 1: aType = TopAbs_EDGE; break;
5318 case 2: aType = TopAbs_FACE; break;
5320 default:aType = TopAbs_SOLID; break;
5325 //-----------------------------------------------------------------------------
5327 * \brief Internal structure used to find concurent submeshes
5329 * It represents a pair < submesh, concurent dimension >, where
5330 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5331 * with another submesh. In other words, it is dimension of a hypothesis assigned
5338 int _dim; //!< a dimension the algo can build (concurrent dimension)
5339 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5340 TopTools_MapOfShape _shapeMap;
5341 SMESH_subMesh* _subMesh;
5342 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5344 //-----------------------------------------------------------------------------
5345 // Return the algorithm
5346 const SMESH_Algo* GetAlgo() const
5347 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5349 //-----------------------------------------------------------------------------
5351 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5353 const TopoDS_Shape& theShape)
5355 _subMesh = (SMESH_subMesh*)theSubMesh;
5356 SetShape( theDim, theShape );
5359 //-----------------------------------------------------------------------------
5361 void SetShape(const int theDim,
5362 const TopoDS_Shape& theShape)
5365 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5366 if (_dim >= _ownDim)
5367 _shapeMap.Add( theShape );
5369 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5370 for( ; anExp.More(); anExp.Next() )
5371 _shapeMap.Add( anExp.Current() );
5375 //-----------------------------------------------------------------------------
5376 //! Check sharing of sub-shapes
5377 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5378 const TopTools_MapOfShape& theToFind,
5379 const TopAbs_ShapeEnum theType)
5381 bool isShared = false;
5382 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5383 for (; !isShared && anItr.More(); anItr.Next() )
5385 const TopoDS_Shape aSubSh = anItr.Key();
5386 // check for case when concurrent dimensions are same
5387 isShared = theToFind.Contains( aSubSh );
5388 // check for sub-shape with concurrent dimension
5389 TopExp_Explorer anExp( aSubSh, theType );
5390 for ( ; !isShared && anExp.More(); anExp.Next() )
5391 isShared = theToFind.Contains( anExp.Current() );
5396 //-----------------------------------------------------------------------------
5397 //! check algorithms
5398 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5399 const SMESHDS_Hypothesis* theA2)
5401 if ( !theA1 || !theA2 ||
5402 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5403 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5404 return false; // one of the hypothesis is not algorithm
5405 // check algorithm names (should be equal)
5406 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5410 //-----------------------------------------------------------------------------
5411 //! Check if sub-shape hypotheses are concurrent
5412 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5414 if ( _subMesh == theOther->_subMesh )
5415 return false; // same sub-shape - should not be
5417 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5418 // any of the two submeshes is not on COMPOUND shape )
5419 // -> no concurrency
5420 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5421 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5422 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5423 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5424 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5427 // bool checkSubShape = ( _dim >= theOther->_dim )
5428 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5429 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5430 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5431 if ( !checkSubShape )
5434 // check algorithms to be same
5435 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5436 return true; // different algorithms -> concurrency !
5438 // check hypothesises for concurrence (skip first as algorithm)
5440 // pointers should be same, because it is referened from mesh hypothesis partition
5441 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5442 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5443 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5444 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5446 // the submeshes are concurrent if their algorithms has different parameters
5447 return nbSame != theOther->_hypotheses.size() - 1;
5450 // Return true if algorithm of this SMESH_DimHyp is used if no
5451 // sub-mesh order is imposed by the user
5452 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5454 // NeedDiscreteBoundary() algo has a higher priority
5455 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5456 theOther->GetAlgo()->NeedDiscreteBoundary() )
5457 return !this->GetAlgo()->NeedDiscreteBoundary();
5459 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5462 }; // end of SMESH_DimHyp
5463 //-----------------------------------------------------------------------------
5465 typedef list<const SMESH_DimHyp*> TDimHypList;
5467 //-----------------------------------------------------------------------------
5469 void addDimHypInstance(const int theDim,
5470 const TopoDS_Shape& theShape,
5471 const SMESH_Algo* theAlgo,
5472 const SMESH_subMesh* theSubMesh,
5473 const list <const SMESHDS_Hypothesis*>& theHypList,
5474 TDimHypList* theDimHypListArr )
5476 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5477 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5478 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5479 dimHyp->_hypotheses.push_front(theAlgo);
5480 listOfdimHyp.push_back( dimHyp );
5483 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5484 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5485 theHypList.begin(), theHypList.end() );
5488 //-----------------------------------------------------------------------------
5489 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5490 TDimHypList& theListOfConcurr)
5492 if ( theListOfConcurr.empty() )
5494 theListOfConcurr.push_back( theDimHyp );
5498 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5499 while ( hypIt != theListOfConcurr.end() &&
5500 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5502 theListOfConcurr.insert( hypIt, theDimHyp );
5506 //-----------------------------------------------------------------------------
5507 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5508 const TDimHypList& theListOfDimHyp,
5509 TDimHypList& theListOfConcurrHyp,
5510 set<int>& theSetOfConcurrId )
5512 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5513 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5515 const SMESH_DimHyp* curDimHyp = *rIt;
5516 if ( curDimHyp == theDimHyp )
5517 break; // meet own dimHyp pointer in same dimension
5519 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5520 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5522 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5527 //-----------------------------------------------------------------------------
5528 void unionLists(TListOfInt& theListOfId,
5529 TListOfListOfInt& theListOfListOfId,
5532 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5533 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5535 continue; //skip already treated lists
5536 // check if other list has any same submesh object
5537 TListOfInt& otherListOfId = *it;
5538 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5539 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5542 // union two lists (from source into target)
5543 TListOfInt::iterator it2 = otherListOfId.begin();
5544 for ( ; it2 != otherListOfId.end(); it2++ ) {
5545 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5546 theListOfId.push_back(*it2);
5548 // clear source list
5549 otherListOfId.clear();
5552 //-----------------------------------------------------------------------------
5554 //! free memory allocated for dimension-hypothesis objects
5555 void removeDimHyps( TDimHypList* theArrOfList )
5557 for (int i = 0; i < 4; i++ ) {
5558 TDimHypList& listOfdimHyp = theArrOfList[i];
5559 TDimHypList::const_iterator it = listOfdimHyp.begin();
5560 for ( ; it != listOfdimHyp.end(); it++ )
5565 //-----------------------------------------------------------------------------
5567 * \brief find common submeshes with given submesh
5568 * \param theSubMeshList list of already collected submesh to check
5569 * \param theSubMesh given submesh to intersect with other
5570 * \param theCommonSubMeshes collected common submeshes
5572 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5573 const SMESH_subMesh* theSubMesh,
5574 set<const SMESH_subMesh*>& theCommon )
5578 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5579 for ( ; it != theSubMeshList.end(); it++ )
5580 theSubMesh->FindIntersection( *it, theCommon );
5581 theSubMeshList.push_back( theSubMesh );
5582 //theCommon.insert( theSubMesh );
5585 //-----------------------------------------------------------------------------
5586 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5588 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5589 for ( ; listsIt != smLists.end(); ++listsIt )
5591 const TListOfInt& smIDs = *listsIt;
5592 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5600 //=============================================================================
5602 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5604 //=============================================================================
5606 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5608 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5609 if ( isSubMeshInList( submeshID, anOrder ))
5612 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5613 return isSubMeshInList( submeshID, allConurrent );
5616 //=============================================================================
5618 * \brief Return submesh objects list in meshing order
5620 //=============================================================================
5622 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5624 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5626 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5628 return aResult._retn();
5630 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5631 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5632 anOrder.splice( anOrder.end(), allConurrent );
5635 TListOfListOfInt::iterator listIt = anOrder.begin();
5636 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5637 unionLists( *listIt, anOrder, listIndx + 1 );
5639 // convert submesh ids into interface instances
5640 // and dump command into python
5641 convertMeshOrder( anOrder, aResult, false );
5643 return aResult._retn();
5646 //=============================================================================
5648 * \brief Finds concurrent sub-meshes
5650 //=============================================================================
5652 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5654 TListOfListOfInt anOrder;
5655 ::SMESH_Mesh& mesh = GetImpl();
5657 // collect submeshes and detect concurrent algorithms and hypothesises
5658 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5660 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5661 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5662 ::SMESH_subMesh* sm = (*i_sm).second;
5664 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5666 // list of assigned hypothesises
5667 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5668 // Find out dimensions where the submesh can be concurrent.
5669 // We define the dimensions by algo of each of hypotheses in hypList
5670 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5671 for( ; hypIt != hypList.end(); hypIt++ ) {
5672 SMESH_Algo* anAlgo = 0;
5673 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5674 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5675 // hyp it-self is algo
5676 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5678 // try to find algorithm with help of sub-shapes
5679 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5680 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5681 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5684 continue; // no algorithm assigned to a current submesh
5686 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5687 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5689 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5690 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5691 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5693 } // end iterations on submesh
5695 // iterate on created dimension-hypotheses and check for concurrents
5696 for ( int i = 0; i < 4; i++ ) {
5697 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5698 // check for concurrents in own and other dimensions (step-by-step)
5699 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5700 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5701 const SMESH_DimHyp* dimHyp = *dhIt;
5702 TDimHypList listOfConcurr;
5703 set<int> setOfConcurrIds;
5704 // looking for concurrents and collect into own list
5705 for ( int j = i; j < 4; j++ )
5706 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5707 // check if any concurrents found
5708 if ( listOfConcurr.size() > 0 ) {
5709 // add own submesh to list of concurrent
5710 addInOrderOfPriority( dimHyp, listOfConcurr );
5711 list<int> listOfConcurrIds;
5712 TDimHypList::iterator hypIt = listOfConcurr.begin();
5713 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5714 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5715 anOrder.push_back( listOfConcurrIds );
5720 removeDimHyps(dimHypListArr);
5722 // now, minimise the number of concurrent groups
5723 // Here we assume that lists of submeshes can have same submesh
5724 // in case of multi-dimension algorithms, as result
5725 // list with common submesh has to be united into one list
5727 TListOfListOfInt::iterator listIt = anOrder.begin();
5728 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5729 unionLists( *listIt, anOrder, listIndx + 1 );
5735 //=============================================================================
5737 * \brief Set submesh object order
5738 * \param theSubMeshArray submesh array order
5740 //=============================================================================
5742 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5745 _preMeshInfo->ForgetOrLoad();
5748 ::SMESH_Mesh& mesh = GetImpl();
5750 TPythonDump aPythonDump; // prevent dump of called methods
5751 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5753 TListOfListOfInt subMeshOrder;
5754 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5756 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5757 TListOfInt subMeshIds;
5758 aPythonDump << "[ ";
5759 // Collect subMeshes which should be clear
5760 // do it list-by-list, because modification of submesh order
5761 // take effect between concurrent submeshes only
5762 set<const SMESH_subMesh*> subMeshToClear;
5763 list<const SMESH_subMesh*> subMeshList;
5764 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5766 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5768 aPythonDump << ", ";
5769 aPythonDump << subMesh;
5770 subMeshIds.push_back( subMesh->GetId() );
5771 // detect common parts of submeshes
5772 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5773 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5775 aPythonDump << " ]";
5776 subMeshOrder.push_back( subMeshIds );
5778 // clear collected submeshes
5779 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5780 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5781 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5782 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5784 aPythonDump << " ])";
5786 mesh.SetMeshOrder( subMeshOrder );
5792 //=============================================================================
5794 * \brief Convert submesh ids into submesh interfaces
5796 //=============================================================================
5798 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5799 SMESH::submesh_array_array& theResOrder,
5800 const bool theIsDump)
5802 int nbSet = theIdsOrder.size();
5803 TPythonDump aPythonDump; // prevent dump of called methods
5805 aPythonDump << "[ ";
5806 theResOrder.length(nbSet);
5807 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5809 for( ; it != theIdsOrder.end(); it++ ) {
5810 // translate submesh identificators into submesh objects
5811 // takeing into account real number of concurrent lists
5812 const TListOfInt& aSubOrder = (*it);
5813 if (!aSubOrder.size())
5816 aPythonDump << "[ ";
5817 // convert shape indeces into interfaces
5818 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5819 aResSubSet->length(aSubOrder.size());
5820 TListOfInt::const_iterator subIt = aSubOrder.begin();
5822 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5823 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5825 SMESH::SMESH_subMesh_var subMesh =
5826 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5829 aPythonDump << ", ";
5830 aPythonDump << subMesh;
5832 aResSubSet[ j++ ] = subMesh;
5835 aPythonDump << " ]";
5837 theResOrder[ listIndx++ ] = aResSubSet;
5839 // correct number of lists
5840 theResOrder.length( listIndx );
5843 // finilise python dump
5844 aPythonDump << " ]";
5845 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5849 //================================================================================
5851 // Implementation of SMESH_MeshPartDS
5853 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5854 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5856 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5857 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5859 _meshDS = mesh_i->GetImpl().GetMeshDS();
5861 SetPersistentId( _meshDS->GetPersistentId() );
5863 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5865 // <meshPart> is the whole mesh
5866 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5868 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5869 myGroupSet = _meshDS->GetGroups();
5874 SMESH::long_array_var anIDs = meshPart->GetIDs();
5875 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5876 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5878 for (int i=0; i < anIDs->length(); i++)
5879 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5880 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5885 for (int i=0; i < anIDs->length(); i++)
5886 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5887 if ( _elements[ e->GetType() ].insert( e ).second )
5890 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5891 while ( nIt->more() )
5893 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5894 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5901 _meshDS = 0; // to enforce iteration on _elements and _nodes
5904 // -------------------------------------------------------------------------------------
5905 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5906 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5909 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5910 for ( ; partIt != meshPart.end(); ++partIt )
5911 if ( const SMDS_MeshElement * e = *partIt )
5912 if ( _elements[ e->GetType() ].insert( e ).second )
5915 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5916 while ( nIt->more() )
5918 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5919 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5925 // -------------------------------------------------------------------------------------
5926 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5928 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5930 typedef SMDS_SetIterator
5931 <const SMDS_MeshElement*,
5932 TIDSortedElemSet::const_iterator,
5933 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5934 SMDS_MeshElement::GeomFilter
5937 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5939 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5940 _elements[type].end(),
5941 SMDS_MeshElement::GeomFilter( geomType )));
5943 // -------------------------------------------------------------------------------------
5944 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5946 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5948 typedef SMDS_SetIterator
5949 <const SMDS_MeshElement*,
5950 TIDSortedElemSet::const_iterator,
5951 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5952 SMDS_MeshElement::EntityFilter
5955 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5957 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5958 _elements[type].end(),
5959 SMDS_MeshElement::EntityFilter( entity )));
5961 // -------------------------------------------------------------------------------------
5962 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5964 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5965 if ( type == SMDSAbs_All && !_meshDS )
5967 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5969 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5970 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5972 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5974 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5975 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5977 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5978 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5980 // -------------------------------------------------------------------------------------
5981 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5982 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5984 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5985 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5986 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5988 // -------------------------------------------------------------------------------------
5989 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5990 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5991 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5992 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5993 #undef _GET_ITER_DEFINE
5995 // END Implementation of SMESH_MeshPartDS
5997 //================================================================================