1 // Copyright (C) 2007-2015 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_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
111 MESSAGE("SMESH_Mesh_i");
114 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
130 MESSAGE("~SMESH_Mesh_i");
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 aGroup->UnRegister();
138 SMESH::SMESH_GroupBase_var( itGr->second );
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
145 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
147 aSubMesh->UnRegister();
148 SMESH::SMESH_subMesh_var( itSM->second );
150 _mapSubMeshIor.clear();
152 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
156 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
157 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
160 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
164 // clear cashed shapes if no more meshes remain; (the cash is blame,
165 // together with publishing, of spent time increasing in issue 22874)
166 if ( _impl->NbMeshes() == 1 )
167 _gen_i->GetShapeReader()->ClearClientBuffer();
169 delete _editor; _editor = NULL;
170 delete _previewEditor; _previewEditor = NULL;
171 delete _impl; _impl = NULL;
172 delete _preMeshInfo; _preMeshInfo = NULL;
175 //=============================================================================
179 * Associates <this> mesh with <theShape> and puts a reference
180 * to <theShape> into the current study;
181 * the previous shape is substituted by the new one.
183 //=============================================================================
185 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
190 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
192 catch(SALOME_Exception & S_ex) {
193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
195 // to track changes of GEOM groups
196 SMESH::SMESH_Mesh_var mesh = _this();
197 addGeomGroupData( theShapeObject, mesh );
198 if ( !CORBA::is_nil( theShapeObject ))
199 _mainShapeTick = theShapeObject->GetTick();
202 //================================================================================
204 * \brief return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 throw (SALOME::SALOME_Exception)
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //=======================================================================
223 //function : GetShapeToMesh
225 //=======================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 throw (SALOME::SALOME_Exception)
230 Unexpect aCatch(SALOME_SalomeException);
231 GEOM::GEOM_Object_var aShapeObj;
233 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 catch(SALOME_Exception & S_ex) {
238 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
240 return aShapeObj._retn();
243 //================================================================================
245 * \brief Return false if the mesh is not yet fully loaded from the study file
247 //================================================================================
249 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
251 Unexpect aCatch(SALOME_SalomeException);
252 return !_preMeshInfo;
255 //================================================================================
257 * \brief Load full mesh data from the study file
259 //================================================================================
261 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
263 Unexpect aCatch(SALOME_SalomeException);
265 _preMeshInfo->FullLoadFromFile();
268 //================================================================================
270 * \brief Remove all nodes and elements
272 //================================================================================
274 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->ForgetAllData();
282 //CheckGeomGroupModif(); // issue 20145
284 catch(SALOME_Exception & S_ex) {
285 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
287 _impl->GetMeshDS()->Modified();
289 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
292 //================================================================================
294 * \brief Remove all nodes and elements for indicated shape
296 //================================================================================
298 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
299 throw (SALOME::SALOME_Exception)
301 Unexpect aCatch(SALOME_SalomeException);
303 _preMeshInfo->FullLoadFromFile();
306 _impl->ClearSubMesh( ShapeID );
308 catch(SALOME_Exception & S_ex) {
309 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
311 _impl->GetMeshDS()->Modified();
313 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
316 //=============================================================================
318 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
320 //=============================================================================
322 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
324 SMESH::DriverMED_ReadStatus res;
327 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
328 res = SMESH::DRS_OK; break;
329 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
330 res = SMESH::DRS_EMPTY; break;
331 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
332 res = SMESH::DRS_WARN_RENUMBER; break;
333 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
334 res = SMESH::DRS_WARN_SKIP_ELEM; break;
335 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
336 res = SMESH::DRS_WARN_DESCENDING; break;
337 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
339 res = SMESH::DRS_FAIL; break;
344 //=============================================================================
346 * Convert ::SMESH_ComputeError to SMESH::ComputeError
348 //=============================================================================
350 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
352 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
353 errVar->subShapeID = -1;
354 errVar->hasBadMesh = false;
356 if ( !errorPtr || errorPtr->IsOK() )
358 errVar->code = SMESH::COMPERR_OK;
362 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
363 errVar->comment = errorPtr->myComment.c_str();
365 return errVar._retn();
368 //=============================================================================
372 * Imports mesh data from MED file
374 //=============================================================================
376 SMESH::DriverMED_ReadStatus
377 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
378 throw ( SALOME::SALOME_Exception )
380 Unexpect aCatch(SALOME_SalomeException);
383 status = _impl->MEDToMesh( theFileName, theMeshName );
385 catch( SALOME_Exception& S_ex ) {
386 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
389 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
392 CreateGroupServants();
394 int major, minor, release;
395 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
396 major = minor = release = -1;
397 _medFileInfo = new SMESH::MedFileInfo();
398 _medFileInfo->fileName = theFileName;
399 _medFileInfo->fileSize = 0;
400 _medFileInfo->major = major;
401 _medFileInfo->minor = minor;
402 _medFileInfo->release = release;
403 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
405 return ConvertDriverMEDReadStatus(status);
408 //================================================================================
410 * \brief Imports mesh data from the CGNS file
412 //================================================================================
414 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
415 const int theMeshIndex,
416 std::string& theMeshName )
417 throw ( SALOME::SALOME_Exception )
419 Unexpect aCatch(SALOME_SalomeException);
422 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
424 catch( SALOME_Exception& S_ex ) {
425 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
428 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
431 CreateGroupServants();
433 return ConvertDriverMEDReadStatus(status);
436 //================================================================================
438 * \brief Return string representation of a MED file version comprising nbDigits
440 //================================================================================
442 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
444 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
446 return CORBA::string_dup( ver.c_str() );
449 //=============================================================================
453 * Imports mesh data from MED file
455 //=============================================================================
457 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
458 throw ( SALOME::SALOME_Exception )
462 // Read mesh with name = <theMeshName> into SMESH_Mesh
463 _impl->UNVToMesh( theFileName );
465 CreateGroupServants();
467 SMESH_CATCH( SMESH::throwCorbaException );
472 //=============================================================================
476 * Imports mesh data from STL file
478 //=============================================================================
479 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
480 throw ( SALOME::SALOME_Exception )
484 // Read mesh with name = <theMeshName> into SMESH_Mesh
485 _impl->STLToMesh( theFileName );
487 SMESH_CATCH( SMESH::throwCorbaException );
492 //================================================================================
494 * \brief Function used in SMESH_CATCH by ImportGMFFile()
496 //================================================================================
500 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
502 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
506 //================================================================================
508 * \brief Imports data from a GMF file and returns an error description
510 //================================================================================
512 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
513 bool theMakeRequiredGroups )
514 throw (SALOME::SALOME_Exception)
516 SMESH_ComputeErrorPtr error;
519 #define SMESH_CAUGHT error =
522 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
524 SMESH_CATCH( exceptionToComputeError );
528 CreateGroupServants();
530 return ConvertComputeError( error );
533 //=============================================================================
537 //=============================================================================
539 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
541 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
542 (SMESH_Hypothesis::Hypothesis_Status theStatus)
545 RETURNCASE( HYP_OK );
546 RETURNCASE( HYP_MISSING );
547 RETURNCASE( HYP_CONCURENT );
548 RETURNCASE( HYP_BAD_PARAMETER );
549 RETURNCASE( HYP_HIDDEN_ALGO );
550 RETURNCASE( HYP_HIDING_ALGO );
551 RETURNCASE( HYP_UNKNOWN_FATAL );
552 RETURNCASE( HYP_INCOMPATIBLE );
553 RETURNCASE( HYP_NOTCONFORM );
554 RETURNCASE( HYP_ALREADY_EXIST );
555 RETURNCASE( HYP_BAD_DIM );
556 RETURNCASE( HYP_BAD_SUBSHAPE );
557 RETURNCASE( HYP_BAD_GEOMETRY );
558 RETURNCASE( HYP_NEED_SHAPE );
559 RETURNCASE( HYP_INCOMPAT_HYPS );
562 return SMESH::HYP_UNKNOWN_FATAL;
565 //=============================================================================
569 * calls internal addHypothesis() and then adds a reference to <anHyp> under
570 * the SObject actually having a reference to <aSubShape>.
571 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
573 //=============================================================================
575 SMESH::Hypothesis_Status
576 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
577 SMESH::SMESH_Hypothesis_ptr anHyp,
578 CORBA::String_out anErrorText)
579 throw(SALOME::SALOME_Exception)
581 Unexpect aCatch(SALOME_SalomeException);
583 _preMeshInfo->ForgetOrLoad();
586 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
587 anErrorText = error.c_str();
589 SMESH::SMESH_Mesh_var mesh( _this() );
590 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
592 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
593 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
595 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
597 // Update Python script
598 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
599 << aSubShape << ", " << anHyp << " )";
601 return ConvertHypothesisStatus(status);
604 //=============================================================================
608 //=============================================================================
610 SMESH_Hypothesis::Hypothesis_Status
611 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
612 SMESH::SMESH_Hypothesis_ptr anHyp,
613 std::string* anErrorText)
615 if(MYDEBUG) MESSAGE("addHypothesis");
617 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
618 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
620 if (CORBA::is_nil( anHyp ))
621 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
623 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
626 TopoDS_Shape myLocSubShape;
627 //use PseudoShape in case if mesh has no shape
629 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
631 myLocSubShape = _impl->GetShapeToMesh();
633 const int hypId = anHyp->GetId();
635 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
636 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
638 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
640 // assure there is a corresponding submesh
641 if ( !_impl->IsMainShape( myLocSubShape )) {
642 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
643 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
644 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
647 else if ( anErrorText )
649 *anErrorText = error;
652 catch(SALOME_Exception & S_ex)
654 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
659 //=============================================================================
663 //=============================================================================
665 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
666 SMESH::SMESH_Hypothesis_ptr anHyp)
667 throw(SALOME::SALOME_Exception)
669 Unexpect aCatch(SALOME_SalomeException);
671 _preMeshInfo->ForgetOrLoad();
673 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
674 SMESH::SMESH_Mesh_var mesh = _this();
676 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
678 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
679 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
681 // Update Python script
682 if(_impl->HasShapeToMesh())
683 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
684 << aSubShape << ", " << anHyp << " )";
686 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
689 return ConvertHypothesisStatus(status);
692 //=============================================================================
696 //=============================================================================
698 SMESH_Hypothesis::Hypothesis_Status
699 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
700 SMESH::SMESH_Hypothesis_ptr anHyp)
702 if(MYDEBUG) MESSAGE("removeHypothesis()");
704 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
705 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
707 if (CORBA::is_nil( anHyp ))
708 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
710 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
713 TopoDS_Shape myLocSubShape;
714 //use PseudoShape in case if mesh has no shape
715 if( _impl->HasShapeToMesh() )
716 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
718 myLocSubShape = _impl->GetShapeToMesh();
720 const int hypId = anHyp->GetId();
721 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
722 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
724 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
728 catch(SALOME_Exception & S_ex)
730 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
735 //=============================================================================
739 //=============================================================================
741 SMESH::ListOfHypothesis *
742 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
743 throw(SALOME::SALOME_Exception)
745 Unexpect aCatch(SALOME_SalomeException);
746 if (MYDEBUG) MESSAGE("GetHypothesisList");
747 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
748 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
750 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
753 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
754 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
755 myLocSubShape = _impl->GetShapeToMesh();
756 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
757 int i = 0, n = aLocalList.size();
760 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
761 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
762 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
764 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
765 if ( id_hypptr != _mapHypo.end() )
766 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
770 catch(SALOME_Exception & S_ex) {
771 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
774 return aList._retn();
777 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
779 Unexpect aCatch(SALOME_SalomeException);
780 if (MYDEBUG) MESSAGE("GetSubMeshes");
782 SMESH::submesh_array_var aList = new SMESH::submesh_array();
785 TPythonDump aPythonDump;
786 if ( !_mapSubMeshIor.empty() )
790 aList->length( _mapSubMeshIor.size() );
792 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
793 for ( ; it != _mapSubMeshIor.end(); it++ ) {
794 if ( CORBA::is_nil( it->second )) continue;
795 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
797 if (i > 1) aPythonDump << ", ";
798 aPythonDump << it->second;
802 catch(SALOME_Exception & S_ex) {
803 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
806 // Update Python script
807 if ( !_mapSubMeshIor.empty() )
808 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
810 return aList._retn();
813 //=============================================================================
817 //=============================================================================
819 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
820 const char* theName )
821 throw(SALOME::SALOME_Exception)
823 Unexpect aCatch(SALOME_SalomeException);
824 if (CORBA::is_nil(aSubShape))
825 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
827 SMESH::SMESH_subMesh_var subMesh;
828 SMESH::SMESH_Mesh_var aMesh = _this();
830 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
832 //Get or Create the SMESH_subMesh object implementation
834 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
836 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
838 TopoDS_Iterator it( myLocSubShape );
840 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
842 subMesh = getSubMesh( subMeshId );
844 // create a new subMesh object servant if there is none for the shape
845 if ( subMesh->_is_nil() )
846 subMesh = createSubMesh( aSubShape );
847 if ( _gen_i->CanPublishInStudy( subMesh ))
849 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
850 SALOMEDS::SObject_wrap aSO =
851 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
852 if ( !aSO->_is_nil()) {
853 // Update Python script
854 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
855 << aSubShape << ", '" << theName << "' )";
859 catch(SALOME_Exception & S_ex) {
860 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
862 return subMesh._retn();
865 //=============================================================================
869 //=============================================================================
871 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
872 throw (SALOME::SALOME_Exception)
876 if ( theSubMesh->_is_nil() )
879 GEOM::GEOM_Object_var aSubShape;
880 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
881 if ( !aStudy->_is_nil() ) {
882 // Remove submesh's SObject
883 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
884 if ( !anSO->_is_nil() ) {
885 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
886 SALOMEDS::SObject_wrap anObj, aRef;
887 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
888 anObj->ReferencedObject( aRef.inout() ))
890 CORBA::Object_var obj = aRef->GetObject();
891 aSubShape = GEOM::GEOM_Object::_narrow( obj );
893 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
894 // aSubShape = theSubMesh->GetSubShape();
896 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
897 builder->RemoveObjectWithChildren( anSO );
899 // Update Python script
900 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
904 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
906 _preMeshInfo->ForgetOrLoad();
908 SMESH_CATCH( SMESH::throwCorbaException );
911 //=============================================================================
915 //=============================================================================
917 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
918 const char* theName )
919 throw(SALOME::SALOME_Exception)
921 Unexpect aCatch(SALOME_SalomeException);
923 _preMeshInfo->FullLoadFromFile();
925 SMESH::SMESH_Group_var aNewGroup =
926 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
928 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
930 SMESH::SMESH_Mesh_var mesh = _this();
931 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
932 SALOMEDS::SObject_wrap aSO =
933 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
934 if ( !aSO->_is_nil())
935 // Update Python script
936 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
937 << theElemType << ", '" << theName << "' )";
939 return aNewGroup._retn();
942 //=============================================================================
946 //=============================================================================
947 SMESH::SMESH_GroupOnGeom_ptr
948 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
950 GEOM::GEOM_Object_ptr theGeomObj)
951 throw(SALOME::SALOME_Exception)
953 Unexpect aCatch(SALOME_SalomeException);
955 _preMeshInfo->FullLoadFromFile();
957 SMESH::SMESH_GroupOnGeom_var aNewGroup;
959 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
960 if ( !aShape.IsNull() )
963 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
965 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
967 SMESH::SMESH_Mesh_var mesh = _this();
968 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
969 SALOMEDS::SObject_wrap aSO =
970 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
971 if ( !aSO->_is_nil())
972 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
973 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
977 return aNewGroup._retn();
980 //================================================================================
982 * \brief Creates a group whose contents is defined by filter
983 * \param theElemType - group type
984 * \param theName - group name
985 * \param theFilter - the filter
986 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
988 //================================================================================
990 SMESH::SMESH_GroupOnFilter_ptr
991 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
993 SMESH::Filter_ptr theFilter )
994 throw (SALOME::SALOME_Exception)
996 Unexpect aCatch(SALOME_SalomeException);
998 _preMeshInfo->FullLoadFromFile();
1000 if ( CORBA::is_nil( theFilter ))
1001 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1003 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1005 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1007 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1008 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1011 if ( !aNewGroup->_is_nil() )
1012 aNewGroup->SetFilter( theFilter );
1014 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1016 SMESH::SMESH_Mesh_var mesh = _this();
1017 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1018 SALOMEDS::SObject_wrap aSO =
1019 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1021 if ( !aSO->_is_nil())
1022 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1023 << theElemType << ", '" << theName << "', " << theFilter << " )";
1025 return aNewGroup._retn();
1028 //=============================================================================
1032 //=============================================================================
1034 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1035 throw (SALOME::SALOME_Exception)
1037 if ( theGroup->_is_nil() )
1042 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1046 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1047 if ( !aStudy->_is_nil() )
1049 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1050 if ( !aGroupSO->_is_nil() )
1052 // Update Python script
1053 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1055 // Remove group's SObject
1056 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1057 builder->RemoveObjectWithChildren( aGroupSO );
1061 // Remove the group from SMESH data structures
1062 removeGroup( aGroup->GetLocalID() );
1064 SMESH_CATCH( SMESH::throwCorbaException );
1067 //=============================================================================
1069 * Remove group with its contents
1071 //=============================================================================
1073 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1074 throw (SALOME::SALOME_Exception)
1078 _preMeshInfo->FullLoadFromFile();
1080 if ( theGroup->_is_nil() || theGroup->IsEmpty() )
1083 vector<int> nodeIds; // to remove nodes becoming free
1084 CORBA::Long elemID = theGroup->GetID( 1 );
1085 int nbElemNodes = GetElemNbNodes( elemID );
1086 if ( nbElemNodes > 0 )
1087 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1090 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1091 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1092 while ( elemIt->more() )
1094 const SMDS_MeshElement* e = elemIt->next();
1096 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1097 while ( nIt->more() )
1098 nodeIds.push_back( nIt->next()->GetID() );
1100 _impl->GetMeshDS()->RemoveElement( e );
1103 // Remove free nodes
1104 if ( theGroup->GetType() != SMESH::NODE )
1105 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1106 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1107 if ( n->NbInverseElements() == 0 )
1108 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1110 TPythonDump pyDump; // Supress dump from RemoveGroup()
1112 // Update Python script (theGroup must be alive for this)
1113 pyDump << SMESH::SMESH_Mesh_var(_this())
1114 << ".RemoveGroupWithContents( " << theGroup << " )";
1117 RemoveGroup( theGroup );
1119 SMESH_CATCH( SMESH::throwCorbaException );
1122 //================================================================================
1124 * \brief Get the list of groups existing in the mesh
1125 * \retval SMESH::ListOfGroups * - list of groups
1127 //================================================================================
1129 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1131 Unexpect aCatch(SALOME_SalomeException);
1132 if (MYDEBUG) MESSAGE("GetGroups");
1134 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1137 TPythonDump aPythonDump;
1138 if ( !_mapGroups.empty() )
1140 aPythonDump << "[ ";
1142 aList->length( _mapGroups.size() );
1144 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1145 for ( ; it != _mapGroups.end(); it++ ) {
1146 if ( CORBA::is_nil( it->second )) continue;
1147 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1149 if (i > 1) aPythonDump << ", ";
1150 aPythonDump << it->second;
1154 catch(SALOME_Exception & S_ex) {
1155 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1157 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1159 return aList._retn();
1162 //=============================================================================
1164 * Get number of groups existing in the mesh
1166 //=============================================================================
1168 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1170 Unexpect aCatch(SALOME_SalomeException);
1171 return _mapGroups.size();
1174 //=============================================================================
1176 * New group including all mesh elements present in initial groups is created.
1178 //=============================================================================
1180 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1181 SMESH::SMESH_GroupBase_ptr theGroup2,
1182 const char* theName )
1183 throw (SALOME::SALOME_Exception)
1185 SMESH::SMESH_Group_var aResGrp;
1189 _preMeshInfo->FullLoadFromFile();
1191 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1192 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1194 if ( theGroup1->GetType() != theGroup2->GetType() )
1195 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1200 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1201 if ( aResGrp->_is_nil() )
1202 return SMESH::SMESH_Group::_nil();
1204 aResGrp->AddFrom( theGroup1 );
1205 aResGrp->AddFrom( theGroup2 );
1207 // Update Python script
1208 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1209 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1211 SMESH_CATCH( SMESH::throwCorbaException );
1213 return aResGrp._retn();
1216 //=============================================================================
1218 * \brief New group including all mesh elements present in initial groups is created.
1219 * \param theGroups list of groups
1220 * \param theName name of group to be created
1221 * \return pointer to the new group
1223 //=============================================================================
1225 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1226 const char* theName )
1227 throw (SALOME::SALOME_Exception)
1229 SMESH::SMESH_Group_var aResGrp;
1232 _preMeshInfo->FullLoadFromFile();
1235 return SMESH::SMESH_Group::_nil();
1240 SMESH::ElementType aType = SMESH::ALL;
1241 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1243 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1244 if ( CORBA::is_nil( aGrp ) )
1246 if ( aType == SMESH::ALL )
1247 aType = aGrp->GetType();
1248 else if ( aType != aGrp->GetType() )
1249 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1252 if ( aType == SMESH::ALL )
1253 return SMESH::SMESH_Group::_nil();
1258 aResGrp = CreateGroup( aType, theName );
1259 if ( aResGrp->_is_nil() )
1260 return SMESH::SMESH_Group::_nil();
1262 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1263 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1265 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1266 if ( !CORBA::is_nil( aGrp ) )
1268 aResGrp->AddFrom( aGrp );
1269 if ( g > 0 ) pyDump << ", ";
1273 pyDump << " ], '" << theName << "' )";
1275 SMESH_CATCH( SMESH::throwCorbaException );
1277 return aResGrp._retn();
1280 //=============================================================================
1282 * New group is created. All mesh elements that are
1283 * present in both initial groups are added to the new one.
1285 //=============================================================================
1287 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1288 SMESH::SMESH_GroupBase_ptr theGroup2,
1289 const char* theName )
1290 throw (SALOME::SALOME_Exception)
1292 SMESH::SMESH_Group_var aResGrp;
1297 _preMeshInfo->FullLoadFromFile();
1299 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1300 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1302 if ( theGroup1->GetType() != theGroup2->GetType() )
1303 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1307 // Create Intersection
1308 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1309 if ( aResGrp->_is_nil() )
1310 return aResGrp._retn();
1312 SMESHDS_GroupBase* groupDS1 = 0;
1313 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1314 groupDS1 = grp_i->GetGroupDS();
1316 SMESHDS_GroupBase* groupDS2 = 0;
1317 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1318 groupDS2 = grp_i->GetGroupDS();
1320 SMESHDS_Group* resGroupDS = 0;
1321 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1322 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1324 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1326 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1327 while ( elemIt1->more() )
1329 const SMDS_MeshElement* e = elemIt1->next();
1330 if ( groupDS2->Contains( e ))
1331 resGroupDS->SMDSGroup().Add( e );
1334 // Update Python script
1335 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1336 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1338 SMESH_CATCH( SMESH::throwCorbaException );
1340 return aResGrp._retn();
1343 //=============================================================================
1345 \brief Intersect list of groups. New group is created. All mesh elements that
1346 are present in all initial groups simultaneously are added to the new one.
1347 \param theGroups list of groups
1348 \param theName name of group to be created
1349 \return pointer on the group
1351 //=============================================================================
1352 SMESH::SMESH_Group_ptr
1353 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1354 const char* theName )
1355 throw (SALOME::SALOME_Exception)
1357 SMESH::SMESH_Group_var aResGrp;
1362 _preMeshInfo->FullLoadFromFile();
1365 return SMESH::SMESH_Group::_nil();
1367 // check types and get SMESHDS_GroupBase's
1368 SMESH::ElementType aType = SMESH::ALL;
1369 vector< SMESHDS_GroupBase* > groupVec;
1370 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1372 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1373 if ( CORBA::is_nil( aGrp ) )
1375 if ( aType == SMESH::ALL )
1376 aType = aGrp->GetType();
1377 else if ( aType != aGrp->GetType() )
1378 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1381 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1382 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1384 if ( grpDS->IsEmpty() )
1389 groupVec.push_back( grpDS );
1392 if ( aType == SMESH::ALL ) // all groups are nil
1393 return SMESH::SMESH_Group::_nil();
1398 aResGrp = CreateGroup( aType, theName );
1400 SMESHDS_Group* resGroupDS = 0;
1401 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1402 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1403 if ( !resGroupDS || groupVec.empty() )
1404 return aResGrp._retn();
1407 size_t i, nb = groupVec.size();
1408 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1409 while ( elemIt1->more() )
1411 const SMDS_MeshElement* e = elemIt1->next();
1413 for ( i = 1; ( i < nb && inAll ); ++i )
1414 inAll = groupVec[i]->Contains( e );
1417 resGroupDS->SMDSGroup().Add( e );
1420 // Update Python script
1421 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1422 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1424 SMESH_CATCH( SMESH::throwCorbaException );
1426 return aResGrp._retn();
1429 //=============================================================================
1431 * New group is created. All mesh elements that are present in
1432 * a main group but is not present in a tool group are added to the new one
1434 //=============================================================================
1436 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1437 SMESH::SMESH_GroupBase_ptr theGroup2,
1438 const char* theName )
1439 throw (SALOME::SALOME_Exception)
1441 SMESH::SMESH_Group_var aResGrp;
1446 _preMeshInfo->FullLoadFromFile();
1448 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1449 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1451 if ( theGroup1->GetType() != theGroup2->GetType() )
1452 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1456 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1457 if ( aResGrp->_is_nil() )
1458 return aResGrp._retn();
1460 SMESHDS_GroupBase* groupDS1 = 0;
1461 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1462 groupDS1 = grp_i->GetGroupDS();
1464 SMESHDS_GroupBase* groupDS2 = 0;
1465 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1466 groupDS2 = grp_i->GetGroupDS();
1468 SMESHDS_Group* resGroupDS = 0;
1469 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1470 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1472 if ( groupDS1 && groupDS2 && resGroupDS )
1474 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1475 while ( elemIt1->more() )
1477 const SMDS_MeshElement* e = elemIt1->next();
1478 if ( !groupDS2->Contains( e ))
1479 resGroupDS->SMDSGroup().Add( e );
1482 // Update Python script
1483 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1484 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1486 SMESH_CATCH( SMESH::throwCorbaException );
1488 return aResGrp._retn();
1491 //=============================================================================
1493 \brief Cut lists of groups. New group is created. All mesh elements that are
1494 present in main groups but do not present in tool groups are added to the new one
1495 \param theMainGroups list of main groups
1496 \param theToolGroups list of tool groups
1497 \param theName name of group to be created
1498 \return pointer on the group
1500 //=============================================================================
1501 SMESH::SMESH_Group_ptr
1502 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1503 const SMESH::ListOfGroups& theToolGroups,
1504 const char* theName )
1505 throw (SALOME::SALOME_Exception)
1507 SMESH::SMESH_Group_var aResGrp;
1512 _preMeshInfo->FullLoadFromFile();
1515 return SMESH::SMESH_Group::_nil();
1517 // check types and get SMESHDS_GroupBase's
1518 SMESH::ElementType aType = SMESH::ALL;
1519 vector< SMESHDS_GroupBase* > toolGroupVec;
1520 vector< SMDS_ElemIteratorPtr > mainIterVec;
1522 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1524 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1525 if ( CORBA::is_nil( aGrp ) )
1527 if ( aType == SMESH::ALL )
1528 aType = aGrp->GetType();
1529 else if ( aType != aGrp->GetType() )
1530 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1532 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1533 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1534 if ( !grpDS->IsEmpty() )
1535 mainIterVec.push_back( grpDS->GetElements() );
1537 if ( aType == SMESH::ALL ) // all main groups are nil
1538 return SMESH::SMESH_Group::_nil();
1539 if ( mainIterVec.empty() ) // all main groups are empty
1540 return aResGrp._retn();
1542 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1544 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1545 if ( CORBA::is_nil( aGrp ) )
1547 if ( aType != aGrp->GetType() )
1548 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1550 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1551 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1552 toolGroupVec.push_back( grpDS );
1558 aResGrp = CreateGroup( aType, theName );
1560 SMESHDS_Group* resGroupDS = 0;
1561 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1562 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1564 return aResGrp._retn();
1567 size_t i, nb = toolGroupVec.size();
1568 SMDS_ElemIteratorPtr mainElemIt
1569 ( new SMDS_IteratorOnIterators
1570 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1571 while ( mainElemIt->more() )
1573 const SMDS_MeshElement* e = mainElemIt->next();
1575 for ( i = 0; ( i < nb && !isIn ); ++i )
1576 isIn = toolGroupVec[i]->Contains( e );
1579 resGroupDS->SMDSGroup().Add( e );
1582 // Update Python script
1583 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1584 << ".CutListOfGroups( " << theMainGroups << ", "
1585 << theToolGroups << ", '" << theName << "' )";
1587 SMESH_CATCH( SMESH::throwCorbaException );
1589 return aResGrp._retn();
1592 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1594 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1595 bool & toStopChecking )
1597 toStopChecking = ( nbCommon < nbChecked );
1598 return nbCommon == nbNodes;
1600 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1601 bool & toStopChecking )
1603 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1604 return nbCommon == nbCorners;
1606 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1607 bool & toStopChecking )
1609 return nbCommon > 0;
1611 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1612 bool & toStopChecking )
1614 return nbCommon >= nbNodes / 2;
1618 //=============================================================================
1620 * Create a group of entities basing on nodes of other groups.
1621 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1622 * \param [in] anElemType - a type of elements to include to the new group.
1623 * \param [in] theName - a name of the new group.
1624 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1625 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1626 * new group provided that it is based on nodes of an element of \a aListOfGroups
1627 * \return SMESH_Group - the created group
1629 // IMP 19939, bug 22010, IMP 22635
1630 //=============================================================================
1632 SMESH::SMESH_Group_ptr
1633 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1634 SMESH::ElementType theElemType,
1635 const char* theName,
1636 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1637 CORBA::Boolean theUnderlyingOnly)
1638 throw (SALOME::SALOME_Exception)
1640 SMESH::SMESH_Group_var aResGrp;
1644 _preMeshInfo->FullLoadFromFile();
1646 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1648 if ( !theName || !aMeshDS )
1649 return SMESH::SMESH_Group::_nil();
1651 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1653 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1654 SMESH_Comment nbCoNoStr( "SMESH.");
1655 switch ( theNbCommonNodes ) {
1656 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1657 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1658 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1659 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1660 default: return aResGrp._retn();
1662 int nbChecked, nbCommon, nbNodes, nbCorners;
1668 aResGrp = CreateGroup( theElemType, theName );
1669 if ( aResGrp->_is_nil() )
1670 return SMESH::SMESH_Group::_nil();
1672 SMESHDS_GroupBase* groupBaseDS =
1673 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1674 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1676 vector<bool> isNodeInGroups;
1678 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1680 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1681 if ( CORBA::is_nil( aGrp ) )
1683 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1684 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1687 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1688 if ( !elIt ) continue;
1690 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1692 while ( elIt->more() ) {
1693 const SMDS_MeshElement* el = elIt->next();
1694 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1695 while ( nIt->more() )
1696 resGroupCore.Add( nIt->next() );
1699 // get elements of theElemType based on nodes of every element of group
1700 else if ( theUnderlyingOnly )
1702 while ( elIt->more() )
1704 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1705 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1706 TIDSortedElemSet checkedElems;
1707 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1708 while ( nIt->more() )
1710 const SMDS_MeshNode* n = nIt->next();
1711 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1712 // check nodes of elements of theElemType around el
1713 while ( elOfTypeIt->more() )
1715 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1716 if ( !checkedElems.insert( elOfType ).second ) continue;
1717 nbNodes = elOfType->NbNodes();
1718 nbCorners = elOfType->NbCornerNodes();
1720 bool toStopChecking = false;
1721 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1722 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1723 if ( elNodes.count( nIt2->next() ) &&
1724 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1726 resGroupCore.Add( elOfType );
1733 // get all nodes of elements of groups
1736 while ( elIt->more() )
1738 const SMDS_MeshElement* el = elIt->next(); // an element of group
1739 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1740 while ( nIt->more() )
1742 const SMDS_MeshNode* n = nIt->next();
1743 if ( n->GetID() >= isNodeInGroups.size() )
1744 isNodeInGroups.resize( n->GetID() + 1, false );
1745 isNodeInGroups[ n->GetID() ] = true;
1751 // Get elements of theElemType based on a certain number of nodes of elements of groups
1752 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1754 const SMDS_MeshNode* n;
1755 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1756 const int isNodeInGroupsSize = isNodeInGroups.size();
1757 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1759 if ( !isNodeInGroups[ iN ] ||
1760 !( n = aMeshDS->FindNode( iN )))
1763 // check nodes of elements of theElemType around n
1764 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1765 while ( elOfTypeIt->more() )
1767 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1768 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1773 nbNodes = elOfType->NbNodes();
1774 nbCorners = elOfType->NbCornerNodes();
1776 bool toStopChecking = false;
1777 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1778 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1780 const int nID = nIt->next()->GetID();
1781 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1782 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1784 resGroupCore.Add( elOfType );
1792 // Update Python script
1793 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1794 << ".CreateDimGroup( "
1795 << theGroups << ", " << theElemType << ", '" << theName << "', "
1796 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1798 SMESH_CATCH( SMESH::throwCorbaException );
1800 return aResGrp._retn();
1803 //================================================================================
1805 * \brief Remember GEOM group data
1807 //================================================================================
1809 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1810 CORBA::Object_ptr theSmeshObj)
1812 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1815 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1816 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1817 if ( groupSO->_is_nil() )
1820 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1821 GEOM::GEOM_IGroupOperations_wrap groupOp =
1822 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1823 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1826 _geomGroupData.push_back( TGeomGroupData() );
1827 TGeomGroupData & groupData = _geomGroupData.back();
1829 CORBA::String_var entry = groupSO->GetID();
1830 groupData._groupEntry = entry.in();
1832 for ( int i = 0; i < ids->length(); ++i )
1833 groupData._indices.insert( ids[i] );
1835 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1836 // shape index in SMESHDS
1837 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1838 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1841 //================================================================================
1843 * Remove GEOM group data relating to removed smesh object
1845 //================================================================================
1847 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1849 list<TGeomGroupData>::iterator
1850 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1851 for ( ; data != dataEnd; ++data ) {
1852 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1853 _geomGroupData.erase( data );
1859 //================================================================================
1861 * \brief Return new group contents if it has been changed and update group data
1863 //================================================================================
1865 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1867 TopoDS_Shape newShape;
1870 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1871 if ( study->_is_nil() ) return newShape; // means "not changed"
1872 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1873 if ( !groupSO->_is_nil() )
1875 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1876 if ( CORBA::is_nil( groupObj )) return newShape;
1877 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1879 // get indices of group items
1880 set<int> curIndices;
1881 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1882 GEOM::GEOM_IGroupOperations_wrap groupOp =
1883 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1884 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1885 for ( int i = 0; i < ids->length(); ++i )
1886 curIndices.insert( ids[i] );
1888 if ( groupData._indices == curIndices )
1889 return newShape; // group not changed
1892 groupData._indices = curIndices;
1894 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1895 if ( !geomClient ) return newShape;
1896 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1897 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1898 newShape = _gen_i->GeomObjectToShape( geomGroup );
1901 if ( newShape.IsNull() ) {
1902 // geom group becomes empty - return empty compound
1903 TopoDS_Compound compound;
1904 BRep_Builder().MakeCompound(compound);
1905 newShape = compound;
1912 //-----------------------------------------------------------------------------
1914 * \brief Storage of shape and index used in CheckGeomGroupModif()
1916 struct TIndexedShape
1919 TopoDS_Shape _shape;
1920 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1922 //-----------------------------------------------------------------------------
1924 * \brief Data to re-create a group on geometry
1926 struct TGroupOnGeomData
1930 SMDSAbs_ElementType _type;
1932 Quantity_Color _color;
1936 //=============================================================================
1938 * \brief Update data if geometry changes
1942 //=============================================================================
1944 void SMESH_Mesh_i::CheckGeomModif()
1946 if ( !_impl->HasShapeToMesh() ) return;
1948 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1949 if ( study->_is_nil() ) return;
1951 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1952 if ( mainGO->_is_nil() ) return;
1954 if ( mainGO->GetType() == GEOM_GROUP ||
1955 mainGO->GetTick() == _mainShapeTick )
1957 CheckGeomGroupModif();
1961 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1962 if ( !geomClient ) return;
1963 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1964 if ( geomGen->_is_nil() ) return;
1966 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1967 geomClient->RemoveShapeFromBuffer( ior.in() );
1969 // Update data taking into account that
1970 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1973 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1974 if ( newShape.IsNull() )
1977 _mainShapeTick = mainGO->GetTick();
1979 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1981 // store data of groups on geometry
1982 vector< TGroupOnGeomData > groupsData;
1983 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1984 groupsData.reserve( groups.size() );
1985 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1986 for ( ; g != groups.end(); ++g )
1987 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1989 TGroupOnGeomData data;
1990 data._oldID = group->GetID();
1991 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1992 data._type = group->GetType();
1993 data._name = group->GetStoreName();
1994 data._color = group->GetColor();
1995 groupsData.push_back( data );
1997 // store assigned hypotheses
1998 vector< pair< int, THypList > > ids2Hyps;
1999 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2000 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2002 const TopoDS_Shape& s = s2hyps.Key();
2003 const THypList& hyps = s2hyps.ChangeValue();
2004 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2007 // change shape to mesh
2008 int oldNbSubShapes = meshDS->MaxShapeIndex();
2009 _impl->ShapeToMesh( TopoDS_Shape() );
2010 _impl->ShapeToMesh( newShape );
2012 // re-add shapes of geom groups
2013 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2014 for ( ; data != _geomGroupData.end(); ++data )
2016 TopoDS_Shape newShape = newGroupShape( *data );
2017 if ( !newShape.IsNull() )
2019 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2021 TopoDS_Compound compound;
2022 BRep_Builder().MakeCompound( compound );
2023 BRep_Builder().Add( compound, newShape );
2024 newShape = compound;
2026 _impl->GetSubMesh( newShape );
2029 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2030 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2031 SALOME::INTERNAL_ERROR );
2033 // re-assign hypotheses
2034 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2036 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2037 const THypList& hyps = ids2Hyps[i].second;
2038 THypList::const_iterator h = hyps.begin();
2039 for ( ; h != hyps.end(); ++h )
2040 _impl->AddHypothesis( s, (*h)->GetID() );
2044 for ( size_t i = 0; i < groupsData.size(); ++i )
2046 const TGroupOnGeomData& data = groupsData[i];
2048 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2049 if ( i2g == _mapGroups.end() ) continue;
2051 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2052 if ( !gr_i ) continue;
2055 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2056 meshDS->IndexToShape( data._shapeID ));
2059 _mapGroups.erase( i2g );
2063 g->GetGroupDS()->SetColor( data._color );
2064 gr_i->changeLocalId( id );
2065 _mapGroups[ id ] = i2g->second;
2066 if ( data._oldID != id )
2067 _mapGroups.erase( i2g );
2071 // update _mapSubMesh
2072 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2073 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2074 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2078 //=============================================================================
2080 * \brief Update objects depending on changed geom groups
2082 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2083 * issue 0020210: Update of a smesh group after modification of the associated geom group
2085 //=============================================================================
2087 void SMESH_Mesh_i::CheckGeomGroupModif()
2089 if ( !_impl->HasShapeToMesh() ) return;
2091 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2092 if ( study->_is_nil() ) return;
2094 CORBA::Long nbEntities = NbNodes() + NbElements();
2096 // Check if group contents changed
2098 typedef map< string, TopoDS_Shape > TEntry2Geom;
2099 TEntry2Geom newGroupContents;
2101 list<TGeomGroupData>::iterator
2102 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2103 for ( ; data != dataEnd; ++data )
2105 pair< TEntry2Geom::iterator, bool > it_new =
2106 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2107 bool processedGroup = !it_new.second;
2108 TopoDS_Shape& newShape = it_new.first->second;
2109 if ( !processedGroup )
2110 newShape = newGroupShape( *data );
2111 if ( newShape.IsNull() )
2112 continue; // no changes
2115 _preMeshInfo->ForgetOrLoad();
2117 if ( processedGroup ) { // update group indices
2118 list<TGeomGroupData>::iterator data2 = data;
2119 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2120 data->_indices = data2->_indices;
2123 // Update SMESH objects according to new GEOM group contents
2125 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2126 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2128 int oldID = submesh->GetId();
2129 if ( !_mapSubMeshIor.count( oldID ))
2131 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2133 // update hypotheses
2134 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2135 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2136 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2138 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2139 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2141 // care of submeshes
2142 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2143 int newID = newSubmesh->GetId();
2144 if ( newID != oldID ) {
2145 _mapSubMesh [ newID ] = newSubmesh;
2146 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2147 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2148 _mapSubMesh. erase(oldID);
2149 _mapSubMesh_i. erase(oldID);
2150 _mapSubMeshIor.erase(oldID);
2151 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2156 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2157 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2158 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2160 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2162 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2163 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2164 ds->SetShape( newShape );
2169 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2170 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2172 // Remove groups and submeshes basing on removed sub-shapes
2174 TopTools_MapOfShape newShapeMap;
2175 TopoDS_Iterator shapeIt( newShape );
2176 for ( ; shapeIt.More(); shapeIt.Next() )
2177 newShapeMap.Add( shapeIt.Value() );
2179 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2180 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2182 if ( newShapeMap.Contains( shapeIt.Value() ))
2184 TopTools_IndexedMapOfShape oldShapeMap;
2185 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2186 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2188 const TopoDS_Shape& oldShape = oldShapeMap(i);
2189 int oldInd = meshDS->ShapeToIndex( oldShape );
2191 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2192 if ( i_smIor != _mapSubMeshIor.end() ) {
2193 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2196 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2197 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2199 // check if a group bases on oldInd shape
2200 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2201 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2202 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2203 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2205 RemoveGroup( i_grp->second ); // several groups can base on same shape
2206 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2211 // Reassign hypotheses and update groups after setting the new shape to mesh
2213 // collect anassigned hypotheses
2214 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2215 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2216 TShapeHypList assignedHyps;
2217 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2219 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2220 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2221 if ( !hyps.empty() ) {
2222 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2223 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2224 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2227 // collect shapes supporting groups
2228 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2229 TShapeTypeList groupData;
2230 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2231 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2232 for ( ; grIt != groups.end(); ++grIt )
2234 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2236 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2238 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2239 _impl->ShapeToMesh( newShape );
2241 // reassign hypotheses
2242 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2243 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2245 TIndexedShape& geom = indS_hyps->first;
2246 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2247 int oldID = geom._index;
2248 int newID = meshDS->ShapeToIndex( geom._shape );
2249 if ( oldID == 1 ) { // main shape
2251 geom._shape = newShape;
2255 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2256 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2257 // care of submeshes
2258 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2259 if ( newID != oldID ) {
2260 _mapSubMesh [ newID ] = newSubmesh;
2261 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2262 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2263 _mapSubMesh. erase(oldID);
2264 _mapSubMesh_i. erase(oldID);
2265 _mapSubMeshIor.erase(oldID);
2266 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2270 TShapeTypeList::iterator geomType = groupData.begin();
2271 for ( ; geomType != groupData.end(); ++geomType )
2273 const TIndexedShape& geom = geomType->first;
2274 int oldID = geom._index;
2275 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2278 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2279 CORBA::String_var name = groupSO->GetName();
2281 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2283 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2284 group_i->changeLocalId( newID );
2287 break; // everything has been updated
2290 } // loop on group data
2294 CORBA::Long newNbEntities = NbNodes() + NbElements();
2295 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2296 if ( newNbEntities != nbEntities )
2298 // Add all SObjects with icons to soToUpdateIcons
2299 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2301 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2302 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2303 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2305 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2306 i_gr != _mapGroups.end(); ++i_gr ) // groups
2307 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2310 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2311 for ( ; so != soToUpdateIcons.end(); ++so )
2312 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2315 //=============================================================================
2317 * \brief Create standalone group from a group on geometry or filter
2319 //=============================================================================
2321 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2322 throw (SALOME::SALOME_Exception)
2324 SMESH::SMESH_Group_var aGroup;
2329 _preMeshInfo->FullLoadFromFile();
2331 if ( theGroup->_is_nil() )
2332 return aGroup._retn();
2334 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2336 return aGroup._retn();
2338 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2340 const int anId = aGroupToRem->GetLocalID();
2341 if ( !_impl->ConvertToStandalone( anId ) )
2342 return aGroup._retn();
2343 removeGeomGroupData( theGroup );
2345 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2347 // remove old instance of group from own map
2348 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2349 _mapGroups.erase( anId );
2351 SALOMEDS::StudyBuilder_var builder;
2352 SALOMEDS::SObject_wrap aGroupSO;
2353 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2354 if ( !aStudy->_is_nil() ) {
2355 builder = aStudy->NewBuilder();
2356 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2357 if ( !aGroupSO->_is_nil() )
2359 // remove reference to geometry
2360 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2361 for ( ; chItr->More(); chItr->Next() )
2362 // Remove group's child SObject
2363 builder->RemoveObject( chItr->Value() );
2365 // Update Python script
2366 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2367 << ".ConvertToStandalone( " << aGroupSO << " )";
2369 // change icon of Group on Filter
2372 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2373 const int isEmpty = ( elemTypes->length() == 0 );
2376 SALOMEDS::GenericAttribute_wrap anAttr =
2377 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2378 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2379 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2385 // remember new group in own map
2386 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2387 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2389 // register CORBA object for persistence
2390 _gen_i->RegisterObject( aGroup );
2392 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2393 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2394 //aGroup->Register();
2395 aGroupToRem->UnRegister();
2397 SMESH_CATCH( SMESH::throwCorbaException );
2399 return aGroup._retn();
2402 //=============================================================================
2406 //=============================================================================
2408 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2410 if(MYDEBUG) MESSAGE( "createSubMesh" );
2411 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2412 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2413 const int subMeshId = mySubMesh->GetId();
2415 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2416 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2418 _mapSubMesh [subMeshId] = mySubMesh;
2419 _mapSubMesh_i [subMeshId] = subMeshServant;
2420 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2422 subMeshServant->Register();
2424 // register CORBA object for persistence
2425 int nextId = _gen_i->RegisterObject( subMesh );
2426 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2427 else { nextId = 0; } // avoid "unused variable" warning
2429 // to track changes of GEOM groups
2430 addGeomGroupData( theSubShapeObject, subMesh );
2432 return subMesh._retn();
2435 //=======================================================================
2436 //function : getSubMesh
2438 //=======================================================================
2440 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2442 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2443 if ( it == _mapSubMeshIor.end() )
2444 return SMESH::SMESH_subMesh::_nil();
2446 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2449 //=============================================================================
2453 //=============================================================================
2455 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2456 GEOM::GEOM_Object_ptr theSubShapeObject )
2458 bool isHypChanged = false;
2459 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2460 return isHypChanged;
2462 const int subMeshId = theSubMesh->GetId();
2464 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2466 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2468 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2471 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2472 isHypChanged = !hyps.empty();
2473 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2474 for ( ; hyp != hyps.end(); ++hyp )
2475 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2482 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2483 isHypChanged = ( aHypList->length() > 0 );
2484 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2485 removeHypothesis( theSubShapeObject, aHypList[i] );
2488 catch( const SALOME::SALOME_Exception& ) {
2489 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2491 removeGeomGroupData( theSubShapeObject );
2495 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2496 if ( id_smi != _mapSubMesh_i.end() )
2497 id_smi->second->UnRegister();
2499 // remove a CORBA object
2500 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2501 if ( id_smptr != _mapSubMeshIor.end() )
2502 SMESH::SMESH_subMesh_var( id_smptr->second );
2504 _mapSubMesh.erase(subMeshId);
2505 _mapSubMesh_i.erase(subMeshId);
2506 _mapSubMeshIor.erase(subMeshId);
2508 return isHypChanged;
2511 //=============================================================================
2515 //=============================================================================
2517 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2518 const char* theName,
2519 const TopoDS_Shape& theShape,
2520 const SMESH_PredicatePtr& thePredicate )
2522 std::string newName;
2523 if ( !theName || strlen( theName ) == 0 )
2525 std::set< std::string > presentNames;
2526 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2527 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2529 CORBA::String_var name = i_gr->second->GetName();
2530 presentNames.insert( name.in() );
2533 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2534 } while ( !presentNames.insert( newName ).second );
2535 theName = newName.c_str();
2538 SMESH::SMESH_GroupBase_var aGroup;
2539 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2541 SMESH_GroupBase_i* aGroupImpl;
2542 if ( !theShape.IsNull() )
2543 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2544 else if ( thePredicate )
2545 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2547 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2549 aGroup = aGroupImpl->_this();
2550 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2551 aGroupImpl->Register();
2553 // register CORBA object for persistence
2554 int nextId = _gen_i->RegisterObject( aGroup );
2555 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2556 else { nextId = 0; } // avoid "unused variable" warning in release mode
2558 // to track changes of GEOM groups
2559 if ( !theShape.IsNull() ) {
2560 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2561 addGeomGroupData( geom, aGroup );
2564 return aGroup._retn();
2567 //=============================================================================
2569 * SMESH_Mesh_i::removeGroup
2571 * Should be called by ~SMESH_Group_i()
2573 //=============================================================================
2575 void SMESH_Mesh_i::removeGroup( const int theId )
2577 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2578 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2579 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2580 _mapGroups.erase( theId );
2581 removeGeomGroupData( group );
2582 if ( !_impl->RemoveGroup( theId ))
2584 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2585 RemoveGroup( group );
2587 group->UnRegister();
2591 //=============================================================================
2595 //=============================================================================
2597 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2598 throw(SALOME::SALOME_Exception)
2600 SMESH::log_array_var aLog;
2604 _preMeshInfo->FullLoadFromFile();
2606 list < SMESHDS_Command * >logDS = _impl->GetLog();
2607 aLog = new SMESH::log_array;
2609 int lg = logDS.size();
2612 list < SMESHDS_Command * >::iterator its = logDS.begin();
2613 while(its != logDS.end()){
2614 SMESHDS_Command *com = *its;
2615 int comType = com->GetType();
2617 int lgcom = com->GetNumber();
2619 const list < int >&intList = com->GetIndexes();
2620 int inum = intList.size();
2622 list < int >::const_iterator ii = intList.begin();
2623 const list < double >&coordList = com->GetCoords();
2624 int rnum = coordList.size();
2626 list < double >::const_iterator ir = coordList.begin();
2627 aLog[indexLog].commandType = comType;
2628 aLog[indexLog].number = lgcom;
2629 aLog[indexLog].coords.length(rnum);
2630 aLog[indexLog].indexes.length(inum);
2631 for(int i = 0; i < rnum; i++){
2632 aLog[indexLog].coords[i] = *ir;
2633 //MESSAGE(" "<<i<<" "<<ir.Value());
2636 for(int i = 0; i < inum; i++){
2637 aLog[indexLog].indexes[i] = *ii;
2638 //MESSAGE(" "<<i<<" "<<ii.Value());
2647 SMESH_CATCH( SMESH::throwCorbaException );
2649 return aLog._retn();
2653 //=============================================================================
2657 //=============================================================================
2659 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2663 SMESH_CATCH( SMESH::throwCorbaException );
2666 //=============================================================================
2670 //=============================================================================
2672 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2677 //=============================================================================
2681 //=============================================================================
2683 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2688 //=============================================================================
2691 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2692 // issue 0020918: groups removal is caused by hyp modification
2693 // issue 0021208: to forget not loaded mesh data at hyp modification
2694 struct TCallUp_i : public SMESH_Mesh::TCallUp
2696 SMESH_Mesh_i* _mesh;
2697 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2698 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2699 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2700 virtual void Load () { _mesh->Load(); }
2704 //================================================================================
2706 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2708 //================================================================================
2710 void SMESH_Mesh_i::onHypothesisModified()
2713 _preMeshInfo->ForgetOrLoad();
2716 //=============================================================================
2720 //=============================================================================
2722 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2724 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2727 _impl->SetCallUp( new TCallUp_i(this));
2730 //=============================================================================
2734 //=============================================================================
2736 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2738 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2742 //=============================================================================
2744 * Return mesh editor
2746 //=============================================================================
2748 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2749 throw (SALOME::SALOME_Exception)
2751 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2755 _preMeshInfo->FullLoadFromFile();
2757 // Create MeshEditor
2759 _editor = new SMESH_MeshEditor_i( this, false );
2760 aMeshEdVar = _editor->_this();
2762 // Update Python script
2763 TPythonDump() << _editor << " = "
2764 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2766 SMESH_CATCH( SMESH::throwCorbaException );
2768 return aMeshEdVar._retn();
2771 //=============================================================================
2773 * Return mesh edition previewer
2775 //=============================================================================
2777 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2778 throw (SALOME::SALOME_Exception)
2780 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2784 _preMeshInfo->FullLoadFromFile();
2786 if ( !_previewEditor )
2787 _previewEditor = new SMESH_MeshEditor_i( this, true );
2788 aMeshEdVar = _previewEditor->_this();
2790 SMESH_CATCH( SMESH::throwCorbaException );
2792 return aMeshEdVar._retn();
2795 //================================================================================
2797 * \brief Return true if the mesh has been edited since a last total re-compute
2798 * and those modifications may prevent successful partial re-compute
2800 //================================================================================
2802 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2804 Unexpect aCatch(SALOME_SalomeException);
2805 return _impl->HasModificationsToDiscard();
2808 //================================================================================
2810 * \brief Returns a random unique color
2812 //================================================================================
2814 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2816 const int MAX_ATTEMPTS = 100;
2818 double tolerance = 0.5;
2819 SALOMEDS::Color col;
2823 // generate random color
2824 double red = (double)rand() / RAND_MAX;
2825 double green = (double)rand() / RAND_MAX;
2826 double blue = (double)rand() / RAND_MAX;
2827 // check existence in the list of the existing colors
2828 bool matched = false;
2829 std::list<SALOMEDS::Color>::const_iterator it;
2830 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2831 SALOMEDS::Color color = *it;
2832 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2833 matched = tol < tolerance;
2835 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2836 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2844 //=============================================================================
2846 * Sets auto-color mode. If it is on, groups get unique random colors
2848 //=============================================================================
2850 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2852 Unexpect aCatch(SALOME_SalomeException);
2853 _impl->SetAutoColor(theAutoColor);
2855 TPythonDump pyDump; // not to dump group->SetColor() from below code
2856 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2858 std::list<SALOMEDS::Color> aReservedColors;
2859 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2860 for ( ; it != _mapGroups.end(); it++ ) {
2861 if ( CORBA::is_nil( it->second )) continue;
2862 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2863 it->second->SetColor( aColor );
2864 aReservedColors.push_back( aColor );
2868 //=============================================================================
2870 * Returns true if auto-color mode is on
2872 //=============================================================================
2874 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2876 Unexpect aCatch(SALOME_SalomeException);
2877 return _impl->GetAutoColor();
2880 //=============================================================================
2882 * Checks if there are groups with equal names
2884 //=============================================================================
2886 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2888 return _impl->HasDuplicatedGroupNamesMED();
2891 //================================================================================
2893 * \brief Care of a file before exporting mesh into it
2895 //================================================================================
2897 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2899 SMESH_File aFile( file );
2901 if (aFile.exists()) {
2902 // existing filesystem node
2903 if ( !aFile.isDirectory() ) {
2904 if ( aFile.openForWriting() ) {
2905 if ( overwrite && ! aFile.remove()) {
2906 msg << "Can't replace " << aFile.getName();
2909 msg << "Can't write into " << aFile.getName();
2912 msg << "Location " << aFile.getName() << " is not a file";
2916 // nonexisting file; check if it can be created
2917 if ( !aFile.openForWriting() ) {
2918 msg << "You cannot create the file "
2920 << ". Check the directory existance and access rights";
2928 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2932 //================================================================================
2934 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2935 * \param file - file name
2936 * \param overwrite - to erase the file or not
2937 * \retval string - mesh name
2939 //================================================================================
2941 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2942 CORBA::Boolean overwrite)
2945 PrepareForWriting(file, overwrite);
2946 string aMeshName = "Mesh";
2947 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2948 if ( !aStudy->_is_nil() ) {
2949 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2950 if ( !aMeshSO->_is_nil() ) {
2951 CORBA::String_var name = aMeshSO->GetName();
2953 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2954 if ( !aStudy->GetProperties()->IsLocked() )
2956 SALOMEDS::GenericAttribute_wrap anAttr;
2957 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2958 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2959 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2960 ASSERT(!aFileName->_is_nil());
2961 aFileName->SetValue(file);
2962 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2963 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2964 ASSERT(!aFileType->_is_nil());
2965 aFileType->SetValue("FICHIERMED");
2969 // Update Python script
2970 // set name of mesh before export
2971 TPythonDump() << _gen_i << ".SetName("
2972 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2974 // check names of groups
2980 //================================================================================
2982 * \brief Export to med file
2984 //================================================================================
2986 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2987 CORBA::Boolean auto_groups,
2988 SMESH::MED_VERSION theVersion,
2989 CORBA::Boolean overwrite,
2990 CORBA::Boolean autoDimension)
2991 throw(SALOME::SALOME_Exception)
2995 _preMeshInfo->FullLoadFromFile();
2997 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2998 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3000 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3001 << file << "', " << auto_groups << ", "
3002 << theVersion << ", " << overwrite << ", "
3003 << autoDimension << " )";
3005 SMESH_CATCH( SMESH::throwCorbaException );
3008 //================================================================================
3010 * \brief Export a mesh to a med file
3012 //================================================================================
3014 void SMESH_Mesh_i::ExportToMED (const char* file,
3015 CORBA::Boolean auto_groups,
3016 SMESH::MED_VERSION theVersion)
3017 throw(SALOME::SALOME_Exception)
3019 ExportToMEDX(file,auto_groups,theVersion,true);
3022 //================================================================================
3024 * \brief Export a mesh to a med file
3026 //================================================================================
3028 void SMESH_Mesh_i::ExportMED (const char* file,
3029 CORBA::Boolean auto_groups)
3030 throw(SALOME::SALOME_Exception)
3032 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3035 //================================================================================
3037 * \brief Export a mesh to a SAUV file
3039 //================================================================================
3041 void SMESH_Mesh_i::ExportSAUV (const char* file,
3042 CORBA::Boolean auto_groups)
3043 throw(SALOME::SALOME_Exception)
3045 Unexpect aCatch(SALOME_SalomeException);
3047 _preMeshInfo->FullLoadFromFile();
3049 string aMeshName = prepareMeshNameAndGroups(file, true);
3050 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3051 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3052 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3056 //================================================================================
3058 * \brief Export a mesh to a DAT file
3060 //================================================================================
3062 void SMESH_Mesh_i::ExportDAT (const char *file)
3063 throw(SALOME::SALOME_Exception)
3065 Unexpect aCatch(SALOME_SalomeException);
3067 _preMeshInfo->FullLoadFromFile();
3069 // Update Python script
3070 // check names of groups
3072 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3075 PrepareForWriting(file);
3076 _impl->ExportDAT(file);
3079 //================================================================================
3081 * \brief Export a mesh to an UNV file
3083 //================================================================================
3085 void SMESH_Mesh_i::ExportUNV (const char *file)
3086 throw(SALOME::SALOME_Exception)
3088 Unexpect aCatch(SALOME_SalomeException);
3090 _preMeshInfo->FullLoadFromFile();
3092 // Update Python script
3093 // check names of groups
3095 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3098 PrepareForWriting(file);
3099 _impl->ExportUNV(file);
3102 //================================================================================
3104 * \brief Export a mesh to an STL file
3106 //================================================================================
3108 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3109 throw(SALOME::SALOME_Exception)
3111 Unexpect aCatch(SALOME_SalomeException);
3113 _preMeshInfo->FullLoadFromFile();
3115 // Update Python script
3116 // check names of groups
3118 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3119 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3122 PrepareForWriting(file);
3123 _impl->ExportSTL(file, isascii);
3126 //================================================================================
3128 * \brief Export a part of mesh to a med file
3130 //================================================================================
3132 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3134 CORBA::Boolean auto_groups,
3135 SMESH::MED_VERSION version,
3136 CORBA::Boolean overwrite,
3137 CORBA::Boolean autoDimension,
3138 const GEOM::ListOfFields& fields,
3139 const char* geomAssocFields)
3140 throw (SALOME::SALOME_Exception)
3144 _preMeshInfo->FullLoadFromFile();
3147 bool have0dField = false;
3148 if ( fields.length() > 0 )
3150 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3151 if ( shapeToMesh->_is_nil() )
3152 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3154 for ( size_t i = 0; i < fields.length(); ++i )
3156 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3157 THROW_SALOME_CORBA_EXCEPTION
3158 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3159 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3160 if ( fieldShape->_is_nil() )
3161 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3162 if ( !fieldShape->IsSame( shapeToMesh ) )
3163 THROW_SALOME_CORBA_EXCEPTION
3164 ( "Field defined not on shape", SALOME::BAD_PARAM);
3165 if ( fields[i]->GetDimension() == 0 )
3168 if ( geomAssocFields )
3169 for ( int i = 0; geomAssocFields[i]; ++i )
3170 switch ( geomAssocFields[i] ) {
3171 case 'v':case 'e':case 'f':case 's': break;
3172 case 'V':case 'E':case 'F':case 'S': break;
3173 default: THROW_SALOME_CORBA_EXCEPTION
3174 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3178 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3182 string aMeshName = "Mesh";
3183 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3184 if ( CORBA::is_nil( meshPart ) ||
3185 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3187 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3188 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3189 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3190 meshDS = _impl->GetMeshDS();
3195 _preMeshInfo->FullLoadFromFile();
3197 PrepareForWriting(file, overwrite);
3199 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3200 if ( !aStudy->_is_nil() ) {
3201 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3202 if ( !SO->_is_nil() ) {
3203 CORBA::String_var name = SO->GetName();
3207 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3208 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3209 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3210 meshDS = tmpDSDeleter._obj = partDS;
3215 if ( _impl->HasShapeToMesh() )
3217 DriverMED_W_Field fieldWriter;
3218 fieldWriter.SetFile( file );
3219 fieldWriter.SetMeshName( aMeshName );
3220 fieldWriter.AddODOnVertices( have0dField );
3222 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3226 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3227 goList->length( fields.length() );
3228 for ( size_t i = 0; i < fields.length(); ++i )
3230 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3233 TPythonDump() << _this() << ".ExportPartToMED( "
3234 << meshPart << ", r'" << file << "', "
3235 << auto_groups << ", " << version << ", " << overwrite << ", "
3236 << autoDimension << ", " << goList
3237 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3239 SMESH_CATCH( SMESH::throwCorbaException );
3242 //================================================================================
3244 * Write GEOM fields to MED file
3246 //================================================================================
3248 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3249 SMESHDS_Mesh* meshDS,
3250 const GEOM::ListOfFields& fields,
3251 const char* geomAssocFields)
3253 #define METH "SMESH_Mesh_i::exportMEDFields() "
3255 if (( fields.length() < 1 ) &&
3256 ( !geomAssocFields || !geomAssocFields[0] ))
3259 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3260 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3261 std::vector< int > subIdsByDim[ 4 ];
3262 const double noneDblValue = 0.;
3263 const double noneIntValue = 0;
3265 for ( size_t iF = 0; iF < fields.length(); ++iF )
3269 int dim = fields[ iF ]->GetDimension();
3270 SMDSAbs_ElementType elemType;
3271 TopAbs_ShapeEnum shapeType;
3273 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3274 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3275 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3276 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3278 continue; // skip fields on whole shape
3280 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3281 if ( dataType == GEOM::FDT_String )
3283 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3284 if ( stepIDs->length() < 1 )
3286 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3287 if ( comps->length() < 1 )
3289 CORBA::String_var name = fields[ iF ]->GetName();
3291 if ( !fieldWriter.Set( meshDS,
3295 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3298 for ( size_t iC = 0; iC < comps->length(); ++iC )
3299 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3301 // find sub-shape IDs
3303 std::vector< int >& subIds = subIdsByDim[ dim ];
3304 if ( subIds.empty() )
3305 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3306 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3307 subIds.push_back( id );
3311 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3315 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3317 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3318 if ( step->_is_nil() )
3321 CORBA::Long stamp = step->GetStamp();
3322 CORBA::Long id = step->GetID();
3323 fieldWriter.SetDtIt( int( stamp ), int( id ));
3325 // fill dblVals or intVals
3328 case GEOM::FDT_Double:
3330 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3331 if ( dblStep->_is_nil() ) continue;
3332 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3333 if ( vv->length() != subIds.size() )
3334 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3335 for ( size_t i = 0; i < vv->length(); ++i )
3336 dblVals[ subIds[ i ]] = vv[ i ];
3341 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3342 if ( intStep->_is_nil() ) continue;
3343 GEOM::ListOfLong_var vv = intStep->GetValues();
3344 if ( vv->length() != subIds.size() )
3345 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3346 for ( size_t i = 0; i < vv->length(); ++i )
3347 intVals[ subIds[ i ]] = (int) vv[ i ];
3350 case GEOM::FDT_Bool:
3352 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3353 if ( boolStep->_is_nil() ) continue;
3354 GEOM::short_array_var vv = boolStep->GetValues();
3355 if ( vv->length() != subIds.size() )
3356 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3357 for ( size_t i = 0; i < vv->length(); ++i )
3358 intVals[ subIds[ i ]] = (int) vv[ i ];
3364 // pass values to fieldWriter
3365 elemIt = fieldWriter.GetOrderedElems();
3366 if ( dataType == GEOM::FDT_Double )
3367 while ( elemIt->more() )
3369 const SMDS_MeshElement* e = elemIt->next();
3370 const int shapeID = e->getshapeId();
3371 if ( shapeID < 1 || shapeID >= dblVals.size() )
3372 fieldWriter.AddValue( noneDblValue );
3374 fieldWriter.AddValue( dblVals[ shapeID ]);
3377 while ( elemIt->more() )
3379 const SMDS_MeshElement* e = elemIt->next();
3380 const int shapeID = e->getshapeId();
3381 if ( shapeID < 1 || shapeID >= intVals.size() )
3382 fieldWriter.AddValue( (double) noneIntValue );
3384 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3388 fieldWriter.Perform();
3389 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3390 if ( res && res->IsKO() )
3392 if ( res->myComment.empty() )
3393 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3395 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3401 if ( !geomAssocFields || !geomAssocFields[0] )
3404 // write geomAssocFields
3406 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3407 shapeDim[ TopAbs_COMPOUND ] = 3;
3408 shapeDim[ TopAbs_COMPSOLID ] = 3;
3409 shapeDim[ TopAbs_SOLID ] = 3;
3410 shapeDim[ TopAbs_SHELL ] = 2;
3411 shapeDim[ TopAbs_FACE ] = 2;
3412 shapeDim[ TopAbs_WIRE ] = 1;
3413 shapeDim[ TopAbs_EDGE ] = 1;
3414 shapeDim[ TopAbs_VERTEX ] = 0;
3415 shapeDim[ TopAbs_SHAPE ] = 3;
3417 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3419 std::vector< std::string > compNames;
3420 switch ( geomAssocFields[ iF ]) {
3422 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3423 compNames.push_back( "dim" );
3426 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3429 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3432 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3436 compNames.push_back( "id" );
3437 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3438 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3440 fieldWriter.SetDtIt( -1, -1 );
3442 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3446 if ( compNames.size() == 2 ) // _vertices_
3447 while ( elemIt->more() )
3449 const SMDS_MeshElement* e = elemIt->next();
3450 const int shapeID = e->getshapeId();
3453 fieldWriter.AddValue( (double) -1 );
3454 fieldWriter.AddValue( (double) -1 );
3458 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3459 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3460 fieldWriter.AddValue( (double) shapeID );
3464 while ( elemIt->more() )
3466 const SMDS_MeshElement* e = elemIt->next();
3467 const int shapeID = e->getshapeId();
3469 fieldWriter.AddValue( (double) -1 );
3471 fieldWriter.AddValue( (double) shapeID );
3475 fieldWriter.Perform();
3476 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3477 if ( res && res->IsKO() )
3479 if ( res->myComment.empty() )
3480 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3482 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3485 } // loop on geomAssocFields
3490 //================================================================================
3492 * \brief Export a part of mesh to a DAT file
3494 //================================================================================
3496 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3498 throw (SALOME::SALOME_Exception)
3500 Unexpect aCatch(SALOME_SalomeException);
3502 _preMeshInfo->FullLoadFromFile();
3504 PrepareForWriting(file);
3506 SMESH_MeshPartDS partDS( meshPart );
3507 _impl->ExportDAT(file,&partDS);
3509 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3510 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3512 //================================================================================
3514 * \brief Export a part of mesh to an UNV file
3516 //================================================================================
3518 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3520 throw (SALOME::SALOME_Exception)
3522 Unexpect aCatch(SALOME_SalomeException);
3524 _preMeshInfo->FullLoadFromFile();
3526 PrepareForWriting(file);
3528 SMESH_MeshPartDS partDS( meshPart );
3529 _impl->ExportUNV(file, &partDS);
3531 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3532 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3534 //================================================================================
3536 * \brief Export a part of mesh to an STL file
3538 //================================================================================
3540 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3542 ::CORBA::Boolean isascii)
3543 throw (SALOME::SALOME_Exception)
3545 Unexpect aCatch(SALOME_SalomeException);
3547 _preMeshInfo->FullLoadFromFile();
3549 PrepareForWriting(file);
3551 SMESH_MeshPartDS partDS( meshPart );
3552 _impl->ExportSTL(file, isascii, &partDS);
3554 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3555 << meshPart<< ", r'" << file << "', " << isascii << ")";
3558 //================================================================================
3560 * \brief Export a part of mesh to an STL file
3562 //================================================================================
3564 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3566 CORBA::Boolean overwrite)
3567 throw (SALOME::SALOME_Exception)
3570 Unexpect aCatch(SALOME_SalomeException);
3572 _preMeshInfo->FullLoadFromFile();
3574 PrepareForWriting(file,overwrite);
3576 SMESH_MeshPartDS partDS( meshPart );
3577 _impl->ExportCGNS(file, &partDS);
3579 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3580 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3582 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3586 //================================================================================
3588 * \brief Export a part of mesh to a GMF file
3590 //================================================================================
3592 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3594 bool withRequiredGroups)
3595 throw (SALOME::SALOME_Exception)
3597 Unexpect aCatch(SALOME_SalomeException);
3599 _preMeshInfo->FullLoadFromFile();
3601 PrepareForWriting(file,/*overwrite=*/true);
3603 SMESH_MeshPartDS partDS( meshPart );
3604 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3606 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3607 << meshPart<< ", r'"
3609 << withRequiredGroups << ")";
3612 //=============================================================================
3614 * Return computation progress [0.,1]
3616 //=============================================================================
3618 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3622 return _impl->GetComputeProgress();
3624 SMESH_CATCH( SMESH::doNothing );
3628 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3630 Unexpect aCatch(SALOME_SalomeException);
3632 return _preMeshInfo->NbNodes();
3634 return _impl->NbNodes();
3637 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3639 Unexpect aCatch(SALOME_SalomeException);
3641 return _preMeshInfo->NbElements();
3643 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3646 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3648 Unexpect aCatch(SALOME_SalomeException);
3650 return _preMeshInfo->Nb0DElements();
3652 return _impl->Nb0DElements();
3655 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3657 Unexpect aCatch(SALOME_SalomeException);
3659 return _preMeshInfo->NbBalls();
3661 return _impl->NbBalls();
3664 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3666 Unexpect aCatch(SALOME_SalomeException);
3668 return _preMeshInfo->NbEdges();
3670 return _impl->NbEdges();
3673 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3674 throw(SALOME::SALOME_Exception)
3676 Unexpect aCatch(SALOME_SalomeException);
3678 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3680 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3683 //=============================================================================
3685 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3687 Unexpect aCatch(SALOME_SalomeException);
3689 return _preMeshInfo->NbFaces();
3691 return _impl->NbFaces();
3694 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3696 Unexpect aCatch(SALOME_SalomeException);
3698 return _preMeshInfo->NbTriangles();
3700 return _impl->NbTriangles();
3703 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3705 Unexpect aCatch(SALOME_SalomeException);
3707 return _preMeshInfo->NbBiQuadTriangles();
3709 return _impl->NbBiQuadTriangles();
3712 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3714 Unexpect aCatch(SALOME_SalomeException);
3716 return _preMeshInfo->NbQuadrangles();
3718 return _impl->NbQuadrangles();
3721 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3723 Unexpect aCatch(SALOME_SalomeException);
3725 return _preMeshInfo->NbBiQuadQuadrangles();
3727 return _impl->NbBiQuadQuadrangles();
3730 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3732 Unexpect aCatch(SALOME_SalomeException);
3734 return _preMeshInfo->NbPolygons();
3736 return _impl->NbPolygons();
3739 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3740 throw(SALOME::SALOME_Exception)
3742 Unexpect aCatch(SALOME_SalomeException);
3744 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3746 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3749 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3750 throw(SALOME::SALOME_Exception)
3752 Unexpect aCatch(SALOME_SalomeException);
3754 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3756 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3759 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3760 throw(SALOME::SALOME_Exception)
3762 Unexpect aCatch(SALOME_SalomeException);
3764 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3766 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3769 //=============================================================================
3771 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3773 Unexpect aCatch(SALOME_SalomeException);
3775 return _preMeshInfo->NbVolumes();
3777 return _impl->NbVolumes();
3780 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3782 Unexpect aCatch(SALOME_SalomeException);
3784 return _preMeshInfo->NbTetras();
3786 return _impl->NbTetras();
3789 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3791 Unexpect aCatch(SALOME_SalomeException);
3793 return _preMeshInfo->NbHexas();
3795 return _impl->NbHexas();
3798 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3800 Unexpect aCatch(SALOME_SalomeException);
3802 return _preMeshInfo->NbTriQuadHexas();
3804 return _impl->NbTriQuadraticHexas();
3807 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3809 Unexpect aCatch(SALOME_SalomeException);
3811 return _preMeshInfo->NbPyramids();
3813 return _impl->NbPyramids();
3816 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3818 Unexpect aCatch(SALOME_SalomeException);
3820 return _preMeshInfo->NbPrisms();
3822 return _impl->NbPrisms();
3825 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3827 Unexpect aCatch(SALOME_SalomeException);
3829 return _preMeshInfo->NbHexPrisms();
3831 return _impl->NbHexagonalPrisms();
3834 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3836 Unexpect aCatch(SALOME_SalomeException);
3838 return _preMeshInfo->NbPolyhedrons();
3840 return _impl->NbPolyhedrons();
3843 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3844 throw(SALOME::SALOME_Exception)
3846 Unexpect aCatch(SALOME_SalomeException);
3848 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3850 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3853 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3854 throw(SALOME::SALOME_Exception)
3856 Unexpect aCatch(SALOME_SalomeException);
3858 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3860 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3863 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3864 throw(SALOME::SALOME_Exception)
3866 Unexpect aCatch(SALOME_SalomeException);
3868 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3870 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3873 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3874 throw(SALOME::SALOME_Exception)
3876 Unexpect aCatch(SALOME_SalomeException);
3878 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3880 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3883 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3884 throw(SALOME::SALOME_Exception)
3886 Unexpect aCatch(SALOME_SalomeException);
3888 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3890 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3893 //=============================================================================
3895 * Returns nb of published sub-meshes
3897 //=============================================================================
3899 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3901 Unexpect aCatch(SALOME_SalomeException);
3902 return _mapSubMesh_i.size();
3905 //=============================================================================
3907 * Dumps mesh into a string
3909 //=============================================================================
3911 char* SMESH_Mesh_i::Dump()
3915 return CORBA::string_dup( os.str().c_str() );
3918 //=============================================================================
3920 * Method of SMESH_IDSource interface
3922 //=============================================================================
3924 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3926 return GetElementsId();
3929 //=============================================================================
3931 * Returns ids of all elements
3933 //=============================================================================
3935 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3936 throw (SALOME::SALOME_Exception)
3938 Unexpect aCatch(SALOME_SalomeException);
3940 _preMeshInfo->FullLoadFromFile();
3942 SMESH::long_array_var aResult = new SMESH::long_array();
3943 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3945 if ( aSMESHDS_Mesh == NULL )
3946 return aResult._retn();
3948 long nbElements = NbElements();
3949 aResult->length( nbElements );
3950 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3951 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3952 aResult[i] = anIt->next()->GetID();
3954 return aResult._retn();
3958 //=============================================================================
3960 * Returns ids of all elements of given type
3962 //=============================================================================
3964 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3965 throw (SALOME::SALOME_Exception)
3967 Unexpect aCatch(SALOME_SalomeException);
3969 _preMeshInfo->FullLoadFromFile();
3971 SMESH::long_array_var aResult = new SMESH::long_array();
3972 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3974 if ( aSMESHDS_Mesh == NULL )
3975 return aResult._retn();
3977 long nbElements = NbElements();
3979 // No sense in returning ids of elements along with ids of nodes:
3980 // when theElemType == SMESH::ALL, return node ids only if
3981 // there are no elements
3982 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3983 return GetNodesId();
3985 aResult->length( nbElements );
3989 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3990 while ( i < nbElements && anIt->more() )
3991 aResult[i++] = anIt->next()->GetID();
3993 aResult->length( i );
3995 return aResult._retn();
3998 //=============================================================================
4000 * Returns ids of all nodes
4002 //=============================================================================
4004 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4005 throw (SALOME::SALOME_Exception)
4007 Unexpect aCatch(SALOME_SalomeException);
4009 _preMeshInfo->FullLoadFromFile();
4011 SMESH::long_array_var aResult = new SMESH::long_array();
4012 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4014 if ( aSMESHDS_Mesh == NULL )
4015 return aResult._retn();
4017 long nbNodes = NbNodes();
4018 aResult->length( nbNodes );
4019 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4020 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4021 aResult[i] = anIt->next()->GetID();
4023 return aResult._retn();
4026 //=============================================================================
4030 //=============================================================================
4032 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4033 throw (SALOME::SALOME_Exception)
4035 SMESH::ElementType type;
4039 _preMeshInfo->FullLoadFromFile();
4041 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4043 SMESH_CATCH( SMESH::throwCorbaException );
4048 //=============================================================================
4052 //=============================================================================
4054 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4055 throw (SALOME::SALOME_Exception)
4058 _preMeshInfo->FullLoadFromFile();
4060 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4062 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4064 return ( SMESH::EntityType ) e->GetEntityType();
4067 //=============================================================================
4071 //=============================================================================
4073 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4074 throw (SALOME::SALOME_Exception)
4077 _preMeshInfo->FullLoadFromFile();
4079 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4081 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4083 return ( SMESH::GeometryType ) e->GetGeomType();
4086 //=============================================================================
4088 * Returns ID of elements for given submesh
4090 //=============================================================================
4091 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4092 throw (SALOME::SALOME_Exception)
4094 SMESH::long_array_var aResult = new SMESH::long_array();
4098 _preMeshInfo->FullLoadFromFile();
4100 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4101 if(!SM) return aResult._retn();
4103 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4104 if(!SDSM) return aResult._retn();
4106 aResult->length(SDSM->NbElements());
4108 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4110 while ( eIt->more() ) {
4111 aResult[i++] = eIt->next()->GetID();
4114 SMESH_CATCH( SMESH::throwCorbaException );
4116 return aResult._retn();
4119 //=============================================================================
4121 * Returns ID of nodes for given submesh
4122 * If param all==true - returns all nodes, else -
4123 * returns only nodes on shapes.
4125 //=============================================================================
4127 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4129 throw (SALOME::SALOME_Exception)
4131 SMESH::long_array_var aResult = new SMESH::long_array();
4135 _preMeshInfo->FullLoadFromFile();
4137 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4138 if(!SM) return aResult._retn();
4140 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4141 if(!SDSM) return aResult._retn();
4144 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4145 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4146 while ( nIt->more() ) {
4147 const SMDS_MeshNode* elem = nIt->next();
4148 theElems.insert( elem->GetID() );
4151 else { // all nodes of submesh elements
4152 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4153 while ( eIt->more() ) {
4154 const SMDS_MeshElement* anElem = eIt->next();
4155 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4156 while ( nIt->more() ) {
4157 const SMDS_MeshElement* elem = nIt->next();
4158 theElems.insert( elem->GetID() );
4163 aResult->length(theElems.size());
4164 set<int>::iterator itElem;
4166 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4167 aResult[i++] = *itElem;
4169 SMESH_CATCH( SMESH::throwCorbaException );
4171 return aResult._retn();
4174 //=============================================================================
4176 * Returns type of elements for given submesh
4178 //=============================================================================
4180 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4181 throw (SALOME::SALOME_Exception)
4183 SMESH::ElementType type;
4187 _preMeshInfo->FullLoadFromFile();
4189 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4190 if(!SM) return SMESH::ALL;
4192 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4193 if(!SDSM) return SMESH::ALL;
4195 if(SDSM->NbElements()==0)
4196 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4198 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4199 const SMDS_MeshElement* anElem = eIt->next();
4201 type = ( SMESH::ElementType ) anElem->GetType();
4203 SMESH_CATCH( SMESH::throwCorbaException );
4209 //=============================================================================
4211 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4213 //=============================================================================
4215 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4218 _preMeshInfo->FullLoadFromFile();
4220 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4222 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4227 //=============================================================================
4229 * Get XYZ coordinates of node as list of double
4230 * If there is not node for given ID - returns empty list
4232 //=============================================================================
4234 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4237 _preMeshInfo->FullLoadFromFile();
4239 SMESH::double_array_var aResult = new SMESH::double_array();
4240 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4241 if ( aSMESHDS_Mesh == NULL )
4242 return aResult._retn();
4245 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4247 return aResult._retn();
4251 aResult[0] = aNode->X();
4252 aResult[1] = aNode->Y();
4253 aResult[2] = aNode->Z();
4254 return aResult._retn();
4258 //=============================================================================
4260 * For given node returns list of IDs of inverse elements
4261 * If there is not node for given ID - returns empty list
4263 //=============================================================================
4265 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4268 _preMeshInfo->FullLoadFromFile();
4270 SMESH::long_array_var aResult = new SMESH::long_array();
4271 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4272 if ( aSMESHDS_Mesh == NULL )
4273 return aResult._retn();
4276 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4278 return aResult._retn();
4280 // find inverse elements
4281 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4282 aResult->length( aNode->NbInverseElements() );
4283 for( int i = 0; eIt->more(); ++i )
4285 const SMDS_MeshElement* elem = eIt->next();
4286 aResult[ i ] = elem->GetID();
4288 return aResult._retn();
4291 //=============================================================================
4293 * \brief Return position of a node on shape
4295 //=============================================================================
4297 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4300 _preMeshInfo->FullLoadFromFile();
4302 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4303 aNodePosition->shapeID = 0;
4304 aNodePosition->shapeType = GEOM::SHAPE;
4306 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4307 if ( !mesh ) return aNodePosition;
4309 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4311 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4313 aNodePosition->shapeID = aNode->getshapeId();
4314 switch ( pos->GetTypeOfPosition() ) {
4316 aNodePosition->shapeType = GEOM::EDGE;
4317 aNodePosition->params.length(1);
4318 aNodePosition->params[0] =
4319 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4322 aNodePosition->shapeType = GEOM::FACE;
4323 aNodePosition->params.length(2);
4324 aNodePosition->params[0] =
4325 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4326 aNodePosition->params[1] =
4327 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4329 case SMDS_TOP_VERTEX:
4330 aNodePosition->shapeType = GEOM::VERTEX;
4332 case SMDS_TOP_3DSPACE:
4333 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4334 aNodePosition->shapeType = GEOM::SOLID;
4335 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4336 aNodePosition->shapeType = GEOM::SHELL;
4342 return aNodePosition;
4345 //=============================================================================
4347 * \brief Return position of an element on shape
4349 //=============================================================================
4351 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4354 _preMeshInfo->FullLoadFromFile();
4356 SMESH::ElementPosition anElementPosition;
4357 anElementPosition.shapeID = 0;
4358 anElementPosition.shapeType = GEOM::SHAPE;
4360 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4361 if ( !mesh ) return anElementPosition;
4363 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4365 anElementPosition.shapeID = anElem->getshapeId();
4366 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4367 if ( !aSp.IsNull() ) {
4368 switch ( aSp.ShapeType() ) {
4370 anElementPosition.shapeType = GEOM::EDGE;
4373 anElementPosition.shapeType = GEOM::FACE;
4376 anElementPosition.shapeType = GEOM::VERTEX;
4379 anElementPosition.shapeType = GEOM::SOLID;
4382 anElementPosition.shapeType = GEOM::SHELL;
4388 return anElementPosition;
4391 //=============================================================================
4393 * If given element is node returns IDs of shape from position
4394 * If there is not node for given ID - returns -1
4396 //=============================================================================
4398 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4401 _preMeshInfo->FullLoadFromFile();
4403 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4404 if ( aSMESHDS_Mesh == NULL )
4408 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4410 return aNode->getshapeId();
4417 //=============================================================================
4419 * For given element returns ID of result shape after
4420 * ::FindShape() from SMESH_MeshEditor
4421 * If there is not element for given ID - returns -1
4423 //=============================================================================
4425 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4428 _preMeshInfo->FullLoadFromFile();
4430 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4431 if ( aSMESHDS_Mesh == NULL )
4434 // try to find element
4435 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4439 ::SMESH_MeshEditor aMeshEditor(_impl);
4440 int index = aMeshEditor.FindShape( elem );
4448 //=============================================================================
4450 * Returns number of nodes for given element
4451 * If there is not element for given ID - returns -1
4453 //=============================================================================
4455 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4458 _preMeshInfo->FullLoadFromFile();
4460 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4461 if ( aSMESHDS_Mesh == NULL ) return -1;
4462 // try to find element
4463 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4464 if(!elem) return -1;
4465 return elem->NbNodes();
4469 //=============================================================================
4471 * Returns ID of node by given index for given element
4472 * If there is not element for given ID - returns -1
4473 * If there is not node for given index - returns -2
4475 //=============================================================================
4477 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4480 _preMeshInfo->FullLoadFromFile();
4482 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4483 if ( aSMESHDS_Mesh == NULL ) return -1;
4484 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4485 if(!elem) return -1;
4486 if( index>=elem->NbNodes() || index<0 ) return -1;
4487 return elem->GetNode(index)->GetID();
4490 //=============================================================================
4492 * Returns IDs of nodes of given element
4494 //=============================================================================
4496 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4499 _preMeshInfo->FullLoadFromFile();
4501 SMESH::long_array_var aResult = new SMESH::long_array();
4502 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4504 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4506 aResult->length( elem->NbNodes() );
4507 for ( int i = 0; i < elem->NbNodes(); ++i )
4508 aResult[ i ] = elem->GetNode( i )->GetID();
4511 return aResult._retn();
4514 //=============================================================================
4516 * Returns true if given node is medium node
4517 * in given quadratic element
4519 //=============================================================================
4521 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4524 _preMeshInfo->FullLoadFromFile();
4526 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4527 if ( aSMESHDS_Mesh == NULL ) return false;
4529 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4530 if(!aNode) return false;
4531 // try to find element
4532 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4533 if(!elem) return false;
4535 return elem->IsMediumNode(aNode);
4539 //=============================================================================
4541 * Returns true if given node is medium node
4542 * in one of quadratic elements
4544 //=============================================================================
4546 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4547 SMESH::ElementType theElemType)
4550 _preMeshInfo->FullLoadFromFile();
4552 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4553 if ( aSMESHDS_Mesh == NULL ) return false;
4556 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4557 if(!aNode) return false;
4559 SMESH_MesherHelper aHelper( *(_impl) );
4561 SMDSAbs_ElementType aType;
4562 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4563 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4564 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4565 else aType = SMDSAbs_All;
4567 return aHelper.IsMedium(aNode,aType);
4571 //=============================================================================
4573 * Returns number of edges for given element
4575 //=============================================================================
4577 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4580 _preMeshInfo->FullLoadFromFile();
4582 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4583 if ( aSMESHDS_Mesh == NULL ) return -1;
4584 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4585 if(!elem) return -1;
4586 return elem->NbEdges();
4590 //=============================================================================
4592 * Returns number of faces for given element
4594 //=============================================================================
4596 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4599 _preMeshInfo->FullLoadFromFile();
4601 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4602 if ( aSMESHDS_Mesh == NULL ) return -1;
4603 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4604 if(!elem) return -1;
4605 return elem->NbFaces();
4608 //=======================================================================
4609 //function : GetElemFaceNodes
4610 //purpose : Returns nodes of given face (counted from zero) for given element.
4611 //=======================================================================
4613 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4614 CORBA::Short faceIndex)
4617 _preMeshInfo->FullLoadFromFile();
4619 SMESH::long_array_var aResult = new SMESH::long_array();
4620 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4622 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4624 SMDS_VolumeTool vtool( elem );
4625 if ( faceIndex < vtool.NbFaces() )
4627 aResult->length( vtool.NbFaceNodes( faceIndex ));
4628 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4629 for ( int i = 0; i < aResult->length(); ++i )
4630 aResult[ i ] = nn[ i ]->GetID();
4634 return aResult._retn();
4637 //=======================================================================
4638 //function : GetElemFaceNodes
4639 //purpose : Returns three components of normal of given mesh face.
4640 //=======================================================================
4642 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4643 CORBA::Boolean normalized)
4646 _preMeshInfo->FullLoadFromFile();
4648 SMESH::double_array_var aResult = new SMESH::double_array();
4650 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4653 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4655 aResult->length( 3 );
4656 aResult[ 0 ] = normal.X();
4657 aResult[ 1 ] = normal.Y();
4658 aResult[ 2 ] = normal.Z();
4661 return aResult._retn();
4664 //=======================================================================
4665 //function : FindElementByNodes
4666 //purpose : Returns an element based on all given nodes.
4667 //=======================================================================
4669 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4672 _preMeshInfo->FullLoadFromFile();
4674 CORBA::Long elemID(0);
4675 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4677 vector< const SMDS_MeshNode * > nn( nodes.length() );
4678 for ( int i = 0; i < nodes.length(); ++i )
4679 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4682 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4683 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4684 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4685 _impl->NbVolumes( ORDER_QUADRATIC )))
4686 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4688 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4693 //=============================================================================
4695 * Returns true if given element is polygon
4697 //=============================================================================
4699 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4702 _preMeshInfo->FullLoadFromFile();
4704 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4705 if ( aSMESHDS_Mesh == NULL ) return false;
4706 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4707 if(!elem) return false;
4708 return elem->IsPoly();
4712 //=============================================================================
4714 * Returns true if given element is quadratic
4716 //=============================================================================
4718 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4721 _preMeshInfo->FullLoadFromFile();
4723 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4724 if ( aSMESHDS_Mesh == NULL ) return false;
4725 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4726 if(!elem) return false;
4727 return elem->IsQuadratic();
4730 //=============================================================================
4732 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4734 //=============================================================================
4736 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4739 _preMeshInfo->FullLoadFromFile();
4741 if ( const SMDS_BallElement* ball =
4742 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4743 return ball->GetDiameter();
4748 //=============================================================================
4750 * Returns bary center for given element
4752 //=============================================================================
4754 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4757 _preMeshInfo->FullLoadFromFile();
4759 SMESH::double_array_var aResult = new SMESH::double_array();
4760 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4761 if ( aSMESHDS_Mesh == NULL )
4762 return aResult._retn();
4764 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4766 return aResult._retn();
4768 if(elem->GetType()==SMDSAbs_Volume) {
4769 SMDS_VolumeTool aTool;
4770 if(aTool.Set(elem)) {
4772 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4777 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4779 double x=0., y=0., z=0.;
4780 for(; anIt->more(); ) {
4782 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4796 return aResult._retn();
4799 //================================================================================
4801 * \brief Create a group of elements preventing computation of a sub-shape
4803 //================================================================================
4805 SMESH::ListOfGroups*
4806 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4807 const char* theGroupName )
4808 throw ( SALOME::SALOME_Exception )
4810 Unexpect aCatch(SALOME_SalomeException);
4812 if ( !theGroupName || strlen( theGroupName) == 0 )
4813 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4815 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4817 // submesh by subshape id
4818 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4819 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4822 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4823 if ( error && !error->myBadElements.empty())
4825 // sort bad elements by type
4826 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4827 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4828 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4829 for ( ; elemIt != elemEnd; ++elemIt )
4831 const SMDS_MeshElement* elem = *elemIt;
4832 if ( !elem ) continue;
4834 if ( elem->GetID() < 1 )
4836 // elem is a temporary element, make a real element
4837 vector< const SMDS_MeshNode* > nodes;
4838 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4839 while ( nIt->more() && elem )
4841 nodes.push_back( nIt->next() );
4842 if ( nodes.back()->GetID() < 1 )
4843 elem = 0; // a temporary element on temporary nodes
4847 ::SMESH_MeshEditor editor( _impl );
4848 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4852 elemsByType[ elem->GetType() ].push_back( elem );
4855 // how many groups to create?
4857 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4858 nbTypes += int( !elemsByType[ i ].empty() );
4859 groups->length( nbTypes );
4862 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4864 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4865 if ( elems.empty() ) continue;
4867 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4868 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4870 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4871 SMESH::SMESH_Mesh_var mesh = _this();
4872 SALOMEDS::SObject_wrap aSO =
4873 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4874 GEOM::GEOM_Object::_nil(), theGroupName);
4876 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4877 if ( !grp_i ) continue;
4879 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4880 for ( size_t iE = 0; iE < elems.size(); ++iE )
4881 grpDS->SMDSGroup().Add( elems[ iE ]);
4886 return groups._retn();
4889 //=============================================================================
4891 * Create and publish group servants if any groups were imported or created anyhow
4893 //=============================================================================
4895 void SMESH_Mesh_i::CreateGroupServants()
4897 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4898 SMESH::SMESH_Mesh_var aMesh = _this();
4901 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4902 while ( groupIt->more() )
4904 ::SMESH_Group* group = groupIt->next();
4905 int anId = group->GetGroupDS()->GetID();
4907 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4908 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4910 addedIDs.insert( anId );
4912 SMESH_GroupBase_i* aGroupImpl;
4914 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4915 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4917 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4918 shape = groupOnGeom->GetShape();
4921 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4924 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4925 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4926 aGroupImpl->Register();
4928 // register CORBA object for persistence
4929 int nextId = _gen_i->RegisterObject( groupVar );
4930 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4931 else { nextId = 0; } // avoid "unused variable" warning in release mode
4933 // publishing the groups in the study
4934 if ( !aStudy->_is_nil() ) {
4935 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4936 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4939 if ( !addedIDs.empty() )
4942 set<int>::iterator id = addedIDs.begin();
4943 for ( ; id != addedIDs.end(); ++id )
4945 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4946 int i = std::distance( _mapGroups.begin(), it );
4947 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4952 //=============================================================================
4954 * \brief Return groups cantained in _mapGroups by their IDs
4956 //=============================================================================
4958 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4960 int nbGroups = groupIDs.size();
4961 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4962 aList->length( nbGroups );
4964 list<int>::const_iterator ids = groupIDs.begin();
4965 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4967 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4968 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4969 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4971 aList->length( nbGroups );
4972 return aList._retn();
4975 //=============================================================================
4977 * \brief Return information about imported file
4979 //=============================================================================
4981 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4983 SMESH::MedFileInfo_var res( _medFileInfo );
4984 if ( !res.operator->() ) {
4985 res = new SMESH::MedFileInfo;
4987 res->fileSize = res->major = res->minor = res->release = -1;
4992 //=============================================================================
4994 * \brief Pass names of mesh groups from study to mesh DS
4996 //=============================================================================
4998 void SMESH_Mesh_i::checkGroupNames()
5000 int nbGrp = NbGroups();
5004 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5005 if ( aStudy->_is_nil() )
5006 return; // nothing to do
5008 SMESH::ListOfGroups* grpList = 0;
5009 // avoid dump of "GetGroups"
5011 // store python dump into a local variable inside local scope
5012 SMESH::TPythonDump pDump; // do not delete this line of code
5013 grpList = GetGroups();
5016 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5017 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5020 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5021 if ( aGrpSO->_is_nil() )
5023 // correct name of the mesh group if necessary
5024 const char* guiName = aGrpSO->GetName();
5025 if ( strcmp(guiName, aGrp->GetName()) )
5026 aGrp->SetName( guiName );
5030 //=============================================================================
5032 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5034 //=============================================================================
5035 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5037 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5041 //=============================================================================
5043 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5045 //=============================================================================
5047 char* SMESH_Mesh_i::GetParameters()
5049 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5052 //=============================================================================
5054 * \brief Returns list of notebook variables used for last Mesh operation
5056 //=============================================================================
5057 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5059 SMESH::string_array_var aResult = new SMESH::string_array();
5060 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5062 CORBA::String_var aParameters = GetParameters();
5063 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5064 if ( !aStudy->_is_nil()) {
5065 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5066 if(aSections->length() > 0) {
5067 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
5068 aResult->length(aVars.length());
5069 for(int i = 0;i < aVars.length();i++)
5070 aResult[i] = CORBA::string_dup( aVars[i]);
5074 return aResult._retn();
5077 //=======================================================================
5078 //function : GetTypes
5079 //purpose : Returns types of elements it contains
5080 //=======================================================================
5082 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5085 return _preMeshInfo->GetTypes();
5087 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5091 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5092 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5093 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5094 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5095 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5096 types->length( nbTypes );
5098 return types._retn();
5101 //=======================================================================
5102 //function : GetMesh
5103 //purpose : Returns self
5104 //=======================================================================
5106 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5108 return SMESH::SMESH_Mesh::_duplicate( _this() );
5111 //=======================================================================
5112 //function : IsMeshInfoCorrect
5113 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5114 // * happen if mesh data is not yet fully loaded from the file of study.
5115 //=======================================================================
5117 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5119 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5122 //=============================================================================
5124 * \brief Returns number of mesh elements per each \a EntityType
5126 //=============================================================================
5128 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5131 return _preMeshInfo->GetMeshInfo();
5133 SMESH::long_array_var aRes = new SMESH::long_array();
5134 aRes->length(SMESH::Entity_Last);
5135 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5137 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5139 return aRes._retn();
5140 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5141 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5142 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5143 return aRes._retn();
5146 //=============================================================================
5148 * \brief Returns number of mesh elements per each \a ElementType
5150 //=============================================================================
5152 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5154 SMESH::long_array_var aRes = new SMESH::long_array();
5155 aRes->length(SMESH::NB_ELEMENT_TYPES);
5156 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5159 const SMDS_MeshInfo* meshInfo = 0;
5161 meshInfo = _preMeshInfo;
5162 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5163 meshInfo = & meshDS->GetMeshInfo();
5166 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5167 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5169 return aRes._retn();
5172 //=============================================================================
5174 * Collect statistic of mesh elements given by iterator
5176 //=============================================================================
5178 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5179 SMESH::long_array& theInfo)
5181 if (!theItr) return;
5182 while (theItr->more())
5183 theInfo[ theItr->next()->GetEntityType() ]++;
5185 //=============================================================================
5187 * Returns mesh unstructed grid information.
5189 //=============================================================================
5191 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5193 SALOMEDS::TMPFile_var SeqFile;
5194 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5195 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5197 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5198 aWriter->WriteToOutputStringOn();
5199 aWriter->SetInputData(aGrid);
5200 aWriter->SetFileTypeToBinary();
5202 char* str = aWriter->GetOutputString();
5203 int size = aWriter->GetOutputStringLength();
5205 //Allocate octect buffer of required size
5206 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5207 //Copy ostrstream content to the octect buffer
5208 memcpy(OctetBuf, str, size);
5209 //Create and return TMPFile
5210 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5214 return SeqFile._retn();
5217 //=============================================================================
5218 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5219 * SMESH::ElementType type) */
5221 using namespace SMESH::Controls;
5222 //-----------------------------------------------------------------------------
5223 struct PredicateIterator : public SMDS_ElemIterator
5225 SMDS_ElemIteratorPtr _elemIter;
5226 PredicatePtr _predicate;
5227 const SMDS_MeshElement* _elem;
5229 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5230 PredicatePtr predicate):
5231 _elemIter(iterator), _predicate(predicate)
5239 virtual const SMDS_MeshElement* next()
5241 const SMDS_MeshElement* res = _elem;
5243 while ( _elemIter->more() && !_elem )
5245 _elem = _elemIter->next();
5246 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5253 //-----------------------------------------------------------------------------
5254 struct IDSourceIterator : public SMDS_ElemIterator
5256 const CORBA::Long* _idPtr;
5257 const CORBA::Long* _idEndPtr;
5258 SMESH::long_array_var _idArray;
5259 const SMDS_Mesh* _mesh;
5260 const SMDSAbs_ElementType _type;
5261 const SMDS_MeshElement* _elem;
5263 IDSourceIterator( const SMDS_Mesh* mesh,
5264 const CORBA::Long* ids,
5266 SMDSAbs_ElementType type):
5267 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5269 if ( _idPtr && nbIds && _mesh )
5272 IDSourceIterator( const SMDS_Mesh* mesh,
5273 SMESH::long_array* idArray,
5274 SMDSAbs_ElementType type):
5275 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5277 if ( idArray && _mesh )
5279 _idPtr = &_idArray[0];
5280 _idEndPtr = _idPtr + _idArray->length();
5288 virtual const SMDS_MeshElement* next()
5290 const SMDS_MeshElement* res = _elem;
5292 while ( _idPtr < _idEndPtr && !_elem )
5294 if ( _type == SMDSAbs_Node )
5296 _elem = _mesh->FindNode( *_idPtr++ );
5298 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5299 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5307 //-----------------------------------------------------------------------------
5309 struct NodeOfElemIterator : public SMDS_ElemIterator
5311 TColStd_MapOfInteger _checkedNodeIDs;
5312 SMDS_ElemIteratorPtr _elemIter;
5313 SMDS_ElemIteratorPtr _nodeIter;
5314 const SMDS_MeshElement* _node;
5316 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5318 if ( _elemIter && _elemIter->more() )
5320 _nodeIter = _elemIter->next()->nodesIterator();
5328 virtual const SMDS_MeshElement* next()
5330 const SMDS_MeshElement* res = _node;
5332 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5334 if ( _nodeIter->more() )
5336 _node = _nodeIter->next();
5337 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5342 _nodeIter = _elemIter->next()->nodesIterator();
5350 //=============================================================================
5352 * Return iterator on elements of given type in given object
5354 //=============================================================================
5356 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5357 SMESH::ElementType theType)
5359 SMDS_ElemIteratorPtr elemIt;
5360 bool typeOK = false;
5361 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5363 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5364 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5365 if ( !mesh_i ) return elemIt;
5366 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5368 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5370 elemIt = meshDS->elementsIterator( elemType );
5373 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5375 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5378 elemIt = sm->GetElements();
5379 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5381 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5382 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5386 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5388 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5389 if ( groupDS && ( elemType == groupDS->GetType() ||
5390 elemType == SMDSAbs_Node ||
5391 elemType == SMDSAbs_All ))
5393 elemIt = groupDS->GetElements();
5394 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5397 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5399 if ( filter_i->GetElementType() == theType ||
5400 elemType == SMDSAbs_Node ||
5401 elemType == SMDSAbs_All)
5403 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5404 if ( pred_i && pred_i->GetPredicate() )
5406 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5407 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5408 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5409 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5415 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5416 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5417 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5419 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5422 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5423 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5427 SMESH::long_array_var ids = theObject->GetIDs();
5428 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5430 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5433 if ( elemIt && elemIt->more() && !typeOK )
5435 if ( elemType == SMDSAbs_Node )
5437 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5441 elemIt = SMDS_ElemIteratorPtr();
5447 //=============================================================================
5448 namespace // Finding concurrent hypotheses
5449 //=============================================================================
5453 * \brief mapping of mesh dimension into shape type
5455 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5457 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5459 case 0: aType = TopAbs_VERTEX; break;
5460 case 1: aType = TopAbs_EDGE; break;
5461 case 2: aType = TopAbs_FACE; break;
5463 default:aType = TopAbs_SOLID; break;
5468 //-----------------------------------------------------------------------------
5470 * \brief Internal structure used to find concurent submeshes
5472 * It represents a pair < submesh, concurent dimension >, where
5473 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5474 * with another submesh. In other words, it is dimension of a hypothesis assigned
5481 int _dim; //!< a dimension the algo can build (concurrent dimension)
5482 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5483 TopTools_MapOfShape _shapeMap;
5484 SMESH_subMesh* _subMesh;
5485 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5487 //-----------------------------------------------------------------------------
5488 // Return the algorithm
5489 const SMESH_Algo* GetAlgo() const
5490 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5492 //-----------------------------------------------------------------------------
5494 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5496 const TopoDS_Shape& theShape)
5498 _subMesh = (SMESH_subMesh*)theSubMesh;
5499 SetShape( theDim, theShape );
5502 //-----------------------------------------------------------------------------
5504 void SetShape(const int theDim,
5505 const TopoDS_Shape& theShape)
5508 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5509 if (_dim >= _ownDim)
5510 _shapeMap.Add( theShape );
5512 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5513 for( ; anExp.More(); anExp.Next() )
5514 _shapeMap.Add( anExp.Current() );
5518 //-----------------------------------------------------------------------------
5519 //! Check sharing of sub-shapes
5520 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5521 const TopTools_MapOfShape& theToFind,
5522 const TopAbs_ShapeEnum theType)
5524 bool isShared = false;
5525 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5526 for (; !isShared && anItr.More(); anItr.Next() )
5528 const TopoDS_Shape aSubSh = anItr.Key();
5529 // check for case when concurrent dimensions are same
5530 isShared = theToFind.Contains( aSubSh );
5531 // check for sub-shape with concurrent dimension
5532 TopExp_Explorer anExp( aSubSh, theType );
5533 for ( ; !isShared && anExp.More(); anExp.Next() )
5534 isShared = theToFind.Contains( anExp.Current() );
5539 //-----------------------------------------------------------------------------
5540 //! check algorithms
5541 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5542 const SMESHDS_Hypothesis* theA2)
5544 if ( !theA1 || !theA2 ||
5545 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5546 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5547 return false; // one of the hypothesis is not algorithm
5548 // check algorithm names (should be equal)
5549 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5553 //-----------------------------------------------------------------------------
5554 //! Check if sub-shape hypotheses are concurrent
5555 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5557 if ( _subMesh == theOther->_subMesh )
5558 return false; // same sub-shape - should not be
5560 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5561 // any of the two submeshes is not on COMPOUND shape )
5562 // -> no concurrency
5563 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5564 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5565 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5566 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5567 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5570 // bool checkSubShape = ( _dim >= theOther->_dim )
5571 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5572 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5573 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5574 if ( !checkSubShape )
5577 // check algorithms to be same
5578 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5579 return true; // different algorithms -> concurrency !
5581 // check hypothesises for concurrence (skip first as algorithm)
5583 // pointers should be same, because it is referened from mesh hypothesis partition
5584 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5585 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5586 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5587 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5589 // the submeshes are concurrent if their algorithms has different parameters
5590 return nbSame != theOther->_hypotheses.size() - 1;
5593 // Return true if algorithm of this SMESH_DimHyp is used if no
5594 // sub-mesh order is imposed by the user
5595 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5597 // NeedDiscreteBoundary() algo has a higher priority
5598 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5599 theOther->GetAlgo()->NeedDiscreteBoundary() )
5600 return !this->GetAlgo()->NeedDiscreteBoundary();
5602 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5605 }; // end of SMESH_DimHyp
5606 //-----------------------------------------------------------------------------
5608 typedef list<const SMESH_DimHyp*> TDimHypList;
5610 //-----------------------------------------------------------------------------
5612 void addDimHypInstance(const int theDim,
5613 const TopoDS_Shape& theShape,
5614 const SMESH_Algo* theAlgo,
5615 const SMESH_subMesh* theSubMesh,
5616 const list <const SMESHDS_Hypothesis*>& theHypList,
5617 TDimHypList* theDimHypListArr )
5619 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5620 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5621 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5622 dimHyp->_hypotheses.push_front(theAlgo);
5623 listOfdimHyp.push_back( dimHyp );
5626 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5627 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5628 theHypList.begin(), theHypList.end() );
5631 //-----------------------------------------------------------------------------
5632 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5633 TDimHypList& theListOfConcurr)
5635 if ( theListOfConcurr.empty() )
5637 theListOfConcurr.push_back( theDimHyp );
5641 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5642 while ( hypIt != theListOfConcurr.end() &&
5643 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5645 theListOfConcurr.insert( hypIt, theDimHyp );
5649 //-----------------------------------------------------------------------------
5650 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5651 const TDimHypList& theListOfDimHyp,
5652 TDimHypList& theListOfConcurrHyp,
5653 set<int>& theSetOfConcurrId )
5655 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5656 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5658 const SMESH_DimHyp* curDimHyp = *rIt;
5659 if ( curDimHyp == theDimHyp )
5660 break; // meet own dimHyp pointer in same dimension
5662 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5663 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5665 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5670 //-----------------------------------------------------------------------------
5671 void unionLists(TListOfInt& theListOfId,
5672 TListOfListOfInt& theListOfListOfId,
5675 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5676 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5678 continue; //skip already treated lists
5679 // check if other list has any same submesh object
5680 TListOfInt& otherListOfId = *it;
5681 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5682 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5685 // union two lists (from source into target)
5686 TListOfInt::iterator it2 = otherListOfId.begin();
5687 for ( ; it2 != otherListOfId.end(); it2++ ) {
5688 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5689 theListOfId.push_back(*it2);
5691 // clear source list
5692 otherListOfId.clear();
5695 //-----------------------------------------------------------------------------
5697 //! free memory allocated for dimension-hypothesis objects
5698 void removeDimHyps( TDimHypList* theArrOfList )
5700 for (int i = 0; i < 4; i++ ) {
5701 TDimHypList& listOfdimHyp = theArrOfList[i];
5702 TDimHypList::const_iterator it = listOfdimHyp.begin();
5703 for ( ; it != listOfdimHyp.end(); it++ )
5708 //-----------------------------------------------------------------------------
5710 * \brief find common submeshes with given submesh
5711 * \param theSubMeshList list of already collected submesh to check
5712 * \param theSubMesh given submesh to intersect with other
5713 * \param theCommonSubMeshes collected common submeshes
5715 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5716 const SMESH_subMesh* theSubMesh,
5717 set<const SMESH_subMesh*>& theCommon )
5721 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5722 for ( ; it != theSubMeshList.end(); it++ )
5723 theSubMesh->FindIntersection( *it, theCommon );
5724 theSubMeshList.push_back( theSubMesh );
5725 //theCommon.insert( theSubMesh );
5728 //-----------------------------------------------------------------------------
5729 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5731 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5732 for ( ; listsIt != smLists.end(); ++listsIt )
5734 const TListOfInt& smIDs = *listsIt;
5735 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5743 //=============================================================================
5745 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5747 //=============================================================================
5749 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5751 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5752 if ( isSubMeshInList( submeshID, anOrder ))
5755 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5756 return isSubMeshInList( submeshID, allConurrent );
5759 //=============================================================================
5761 * \brief Return submesh objects list in meshing order
5763 //=============================================================================
5765 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5767 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5769 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5771 return aResult._retn();
5773 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5774 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5775 anOrder.splice( anOrder.end(), allConurrent );
5778 TListOfListOfInt::iterator listIt = anOrder.begin();
5779 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5780 unionLists( *listIt, anOrder, listIndx + 1 );
5782 // convert submesh ids into interface instances
5783 // and dump command into python
5784 convertMeshOrder( anOrder, aResult, false );
5786 return aResult._retn();
5789 //=============================================================================
5791 * \brief Finds concurrent sub-meshes
5793 //=============================================================================
5795 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5797 TListOfListOfInt anOrder;
5798 ::SMESH_Mesh& mesh = GetImpl();
5800 // collect submeshes and detect concurrent algorithms and hypothesises
5801 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5803 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5804 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5805 ::SMESH_subMesh* sm = (*i_sm).second;
5807 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5809 // list of assigned hypothesises
5810 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5811 // Find out dimensions where the submesh can be concurrent.
5812 // We define the dimensions by algo of each of hypotheses in hypList
5813 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5814 for( ; hypIt != hypList.end(); hypIt++ ) {
5815 SMESH_Algo* anAlgo = 0;
5816 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5817 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5818 // hyp it-self is algo
5819 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5821 // try to find algorithm with help of sub-shapes
5822 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5823 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5824 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5827 continue; // no algorithm assigned to a current submesh
5829 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5830 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5832 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5833 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5834 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5836 } // end iterations on submesh
5838 // iterate on created dimension-hypotheses and check for concurrents
5839 for ( int i = 0; i < 4; i++ ) {
5840 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5841 // check for concurrents in own and other dimensions (step-by-step)
5842 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5843 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5844 const SMESH_DimHyp* dimHyp = *dhIt;
5845 TDimHypList listOfConcurr;
5846 set<int> setOfConcurrIds;
5847 // looking for concurrents and collect into own list
5848 for ( int j = i; j < 4; j++ )
5849 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5850 // check if any concurrents found
5851 if ( listOfConcurr.size() > 0 ) {
5852 // add own submesh to list of concurrent
5853 addInOrderOfPriority( dimHyp, listOfConcurr );
5854 list<int> listOfConcurrIds;
5855 TDimHypList::iterator hypIt = listOfConcurr.begin();
5856 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5857 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5858 anOrder.push_back( listOfConcurrIds );
5863 removeDimHyps(dimHypListArr);
5865 // now, minimise the number of concurrent groups
5866 // Here we assume that lists of submeshes can have same submesh
5867 // in case of multi-dimension algorithms, as result
5868 // list with common submesh has to be united into one list
5870 TListOfListOfInt::iterator listIt = anOrder.begin();
5871 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5872 unionLists( *listIt, anOrder, listIndx + 1 );
5878 //=============================================================================
5880 * \brief Set submesh object order
5881 * \param theSubMeshArray submesh array order
5883 //=============================================================================
5885 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5888 _preMeshInfo->ForgetOrLoad();
5891 ::SMESH_Mesh& mesh = GetImpl();
5893 TPythonDump aPythonDump; // prevent dump of called methods
5894 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5896 TListOfListOfInt subMeshOrder;
5897 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5899 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5900 TListOfInt subMeshIds;
5902 aPythonDump << ", ";
5903 aPythonDump << "[ ";
5904 // Collect subMeshes which should be clear
5905 // do it list-by-list, because modification of submesh order
5906 // take effect between concurrent submeshes only
5907 set<const SMESH_subMesh*> subMeshToClear;
5908 list<const SMESH_subMesh*> subMeshList;
5909 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5911 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5913 aPythonDump << ", ";
5914 aPythonDump << subMesh;
5915 subMeshIds.push_back( subMesh->GetId() );
5916 // detect common parts of submeshes
5917 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5918 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5920 aPythonDump << " ]";
5921 subMeshOrder.push_back( subMeshIds );
5923 // clear collected submeshes
5924 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5925 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5926 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5927 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5929 aPythonDump << " ])";
5931 mesh.SetMeshOrder( subMeshOrder );
5937 //=============================================================================
5939 * \brief Convert submesh ids into submesh interfaces
5941 //=============================================================================
5943 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5944 SMESH::submesh_array_array& theResOrder,
5945 const bool theIsDump)
5947 int nbSet = theIdsOrder.size();
5948 TPythonDump aPythonDump; // prevent dump of called methods
5950 aPythonDump << "[ ";
5951 theResOrder.length(nbSet);
5952 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5954 for( ; it != theIdsOrder.end(); it++ ) {
5955 // translate submesh identificators into submesh objects
5956 // takeing into account real number of concurrent lists
5957 const TListOfInt& aSubOrder = (*it);
5958 if (!aSubOrder.size())
5961 aPythonDump << "[ ";
5962 // convert shape indeces into interfaces
5963 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5964 aResSubSet->length(aSubOrder.size());
5965 TListOfInt::const_iterator subIt = aSubOrder.begin();
5967 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5968 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5970 SMESH::SMESH_subMesh_var subMesh =
5971 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5974 aPythonDump << ", ";
5975 aPythonDump << subMesh;
5977 aResSubSet[ j++ ] = subMesh;
5980 aPythonDump << " ]";
5982 theResOrder[ listIndx++ ] = aResSubSet;
5984 // correct number of lists
5985 theResOrder.length( listIndx );
5988 // finilise python dump
5989 aPythonDump << " ]";
5990 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5994 //================================================================================
5996 // Implementation of SMESH_MeshPartDS
5998 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5999 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6001 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6002 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6004 _meshDS = mesh_i->GetImpl().GetMeshDS();
6006 SetPersistentId( _meshDS->GetPersistentId() );
6008 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6010 // <meshPart> is the whole mesh
6011 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6013 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6014 myGroupSet = _meshDS->GetGroups();
6019 SMESH::long_array_var anIDs = meshPart->GetIDs();
6020 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6021 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6023 for (int i=0; i < anIDs->length(); i++)
6024 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
6025 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6030 for (int i=0; i < anIDs->length(); i++)
6031 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6032 if ( _elements[ e->GetType() ].insert( e ).second )
6035 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6036 while ( nIt->more() )
6038 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6039 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6046 ShapeToMesh( _meshDS->ShapeToMesh() );
6048 _meshDS = 0; // to enforce iteration on _elements and _nodes
6051 // -------------------------------------------------------------------------------------
6052 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6053 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6056 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6057 for ( ; partIt != meshPart.end(); ++partIt )
6058 if ( const SMDS_MeshElement * e = *partIt )
6059 if ( _elements[ e->GetType() ].insert( e ).second )
6062 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6063 while ( nIt->more() )
6065 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6066 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6072 // -------------------------------------------------------------------------------------
6073 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6075 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6077 typedef SMDS_SetIterator
6078 <const SMDS_MeshElement*,
6079 TIDSortedElemSet::const_iterator,
6080 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6081 SMDS_MeshElement::GeomFilter
6084 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6086 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6087 _elements[type].end(),
6088 SMDS_MeshElement::GeomFilter( geomType )));
6090 // -------------------------------------------------------------------------------------
6091 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6093 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6095 typedef SMDS_SetIterator
6096 <const SMDS_MeshElement*,
6097 TIDSortedElemSet::const_iterator,
6098 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6099 SMDS_MeshElement::EntityFilter
6102 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6104 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6105 _elements[type].end(),
6106 SMDS_MeshElement::EntityFilter( entity )));
6108 // -------------------------------------------------------------------------------------
6109 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6111 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6112 if ( type == SMDSAbs_All && !_meshDS )
6114 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6116 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6117 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6119 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6121 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6122 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6124 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6125 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6127 // -------------------------------------------------------------------------------------
6128 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6129 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6131 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6132 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6133 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6135 // -------------------------------------------------------------------------------------
6136 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6137 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6138 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6139 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6140 #undef _GET_ITER_DEFINE
6142 // END Implementation of SMESH_MeshPartDS
6144 //================================================================================