1 // Copyright (C) 2007-2016 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 : SALOME::GenericObj_i( thePOA )
112 _id = _idGenerator++;
114 _previewEditor = NULL;
119 //=============================================================================
123 //=============================================================================
125 SMESH_Mesh_i::~SMESH_Mesh_i()
128 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
129 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
130 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
132 aGroup->UnRegister();
133 SMESH::SMESH_GroupBase_var( itGr->second );
138 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
139 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
140 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
142 aSubMesh->UnRegister();
143 SMESH::SMESH_subMesh_var( itSM->second );
145 _mapSubMeshIor.clear();
147 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
148 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
149 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
150 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
151 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
152 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
155 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
159 // clear cashed shapes if no more meshes remain; (the cash is blame,
160 // together with publishing, of spent time increasing in issue 22874)
161 if ( _impl->NbMeshes() == 1 )
162 _gen_i->GetShapeReader()->ClearClientBuffer();
164 delete _editor; _editor = NULL;
165 delete _previewEditor; _previewEditor = NULL;
166 delete _impl; _impl = NULL;
167 delete _preMeshInfo; _preMeshInfo = NULL;
170 //=============================================================================
174 * Associates <this> mesh with <theShape> and puts a reference
175 * to <theShape> into the current study;
176 * the previous shape is substituted by the new one.
178 //=============================================================================
180 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
181 throw (SALOME::SALOME_Exception)
183 Unexpect aCatch(SALOME_SalomeException);
185 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
187 catch(SALOME_Exception & S_ex) {
188 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
190 // to track changes of GEOM groups
191 SMESH::SMESH_Mesh_var mesh = _this();
192 addGeomGroupData( theShapeObject, mesh );
193 if ( !CORBA::is_nil( theShapeObject ))
194 _mainShapeTick = theShapeObject->GetTick();
197 //================================================================================
199 * \brief return true if mesh has a shape to build a shape on
201 //================================================================================
203 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
204 throw (SALOME::SALOME_Exception)
206 Unexpect aCatch(SALOME_SalomeException);
209 res = _impl->HasShapeToMesh();
211 catch(SALOME_Exception & S_ex) {
212 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
217 //=======================================================================
218 //function : GetShapeToMesh
220 //=======================================================================
222 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
223 throw (SALOME::SALOME_Exception)
225 Unexpect aCatch(SALOME_SalomeException);
226 GEOM::GEOM_Object_var aShapeObj;
228 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
231 aShapeObj = _gen_i->ShapeToGeomObject( S );
232 if ( aShapeObj->_is_nil() )
234 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
235 // find GEOM_Object by entry (IPAL52735)
236 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
237 for ( ; data != _geomGroupData.end(); ++data )
238 if ( data->_smeshObject->_is_equivalent( _this() ))
240 SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
241 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
242 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
248 catch(SALOME_Exception & S_ex) {
249 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
251 return aShapeObj._retn();
254 //================================================================================
256 * \brief Return false if the mesh is not yet fully loaded from the study file
258 //================================================================================
260 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
262 Unexpect aCatch(SALOME_SalomeException);
263 return !_preMeshInfo;
266 //================================================================================
268 * \brief Load full mesh data from the study file
270 //================================================================================
272 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
274 Unexpect aCatch(SALOME_SalomeException);
276 _preMeshInfo->FullLoadFromFile();
279 //================================================================================
281 * \brief Remove all nodes and elements
283 //================================================================================
285 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
287 Unexpect aCatch(SALOME_SalomeException);
289 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
293 //CheckGeomGroupModif(); // issue 20145
295 catch(SALOME_Exception & S_ex) {
296 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
299 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
302 //================================================================================
304 * \brief Remove all nodes and elements for indicated shape
306 //================================================================================
308 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
309 throw (SALOME::SALOME_Exception)
311 Unexpect aCatch(SALOME_SalomeException);
313 _preMeshInfo->FullLoadFromFile();
316 _impl->ClearSubMesh( ShapeID );
318 catch(SALOME_Exception & S_ex) {
319 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
321 _impl->GetMeshDS()->Modified();
323 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
326 //=============================================================================
328 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
330 //=============================================================================
332 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
334 SMESH::DriverMED_ReadStatus res;
337 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
338 res = SMESH::DRS_OK; break;
339 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
340 res = SMESH::DRS_EMPTY; break;
341 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
342 res = SMESH::DRS_WARN_RENUMBER; break;
343 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
344 res = SMESH::DRS_WARN_SKIP_ELEM; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
346 res = SMESH::DRS_WARN_DESCENDING; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
349 res = SMESH::DRS_FAIL; break;
354 //=============================================================================
356 * Convert ::SMESH_ComputeError to SMESH::ComputeError
358 //=============================================================================
360 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
362 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
363 errVar->subShapeID = -1;
364 errVar->hasBadMesh = false;
366 if ( !errorPtr || errorPtr->IsOK() )
368 errVar->code = SMESH::COMPERR_OK;
372 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
373 errVar->comment = errorPtr->myComment.c_str();
375 return errVar._retn();
378 //=============================================================================
382 * Imports mesh data from MED file
384 //=============================================================================
386 SMESH::DriverMED_ReadStatus
387 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
388 throw ( SALOME::SALOME_Exception )
390 Unexpect aCatch(SALOME_SalomeException);
393 status = _impl->MEDToMesh( theFileName, theMeshName );
395 catch( SALOME_Exception& S_ex ) {
396 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
399 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
402 CreateGroupServants();
404 int major, minor, release;
405 major = minor = release = 0;
406 MED::GetMEDVersion(theFileName, major, minor, release);
407 _medFileInfo = new SMESH::MedFileInfo();
408 _medFileInfo->fileName = theFileName;
409 _medFileInfo->fileSize = 0;
410 _medFileInfo->major = major;
411 _medFileInfo->minor = minor;
412 _medFileInfo->release = release;
413 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
415 return ConvertDriverMEDReadStatus(status);
418 //================================================================================
420 * \brief Imports mesh data from the CGNS file
422 //================================================================================
424 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
425 const int theMeshIndex,
426 std::string& theMeshName )
427 throw ( SALOME::SALOME_Exception )
429 Unexpect aCatch(SALOME_SalomeException);
432 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
434 catch( SALOME_Exception& S_ex ) {
435 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
438 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
441 CreateGroupServants();
443 return ConvertDriverMEDReadStatus(status);
446 //=============================================================================
450 * Imports mesh data from MED file
452 //=============================================================================
454 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
455 throw ( SALOME::SALOME_Exception )
459 // Read mesh with name = <theMeshName> into SMESH_Mesh
460 _impl->UNVToMesh( theFileName );
462 CreateGroupServants();
464 SMESH_CATCH( SMESH::throwCorbaException );
469 //=============================================================================
473 * Imports mesh data from STL file
475 //=============================================================================
476 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
477 throw ( SALOME::SALOME_Exception )
481 // Read mesh with name = <theMeshName> into SMESH_Mesh
482 std::string name = _impl->STLToMesh( theFileName );
485 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
486 _gen_i->SetName( meshSO, name.c_str() );
489 SMESH_CATCH( SMESH::throwCorbaException );
494 //================================================================================
496 * \brief Function used in SMESH_CATCH by ImportGMFFile()
498 //================================================================================
502 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
504 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
508 //================================================================================
510 * \brief Imports data from a GMF file and returns an error description
512 //================================================================================
514 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
515 bool theMakeRequiredGroups )
516 throw (SALOME::SALOME_Exception)
518 SMESH_ComputeErrorPtr error;
521 #define SMESH_CAUGHT error =
524 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
526 SMESH_CATCH( exceptionToComputeError );
530 CreateGroupServants();
532 return ConvertComputeError( error );
535 //=============================================================================
539 //=============================================================================
541 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
543 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
544 (SMESH_Hypothesis::Hypothesis_Status theStatus)
547 RETURNCASE( HYP_OK );
548 RETURNCASE( HYP_MISSING );
549 RETURNCASE( HYP_CONCURENT );
550 RETURNCASE( HYP_BAD_PARAMETER );
551 RETURNCASE( HYP_HIDDEN_ALGO );
552 RETURNCASE( HYP_HIDING_ALGO );
553 RETURNCASE( HYP_UNKNOWN_FATAL );
554 RETURNCASE( HYP_INCOMPATIBLE );
555 RETURNCASE( HYP_NOTCONFORM );
556 RETURNCASE( HYP_ALREADY_EXIST );
557 RETURNCASE( HYP_BAD_DIM );
558 RETURNCASE( HYP_BAD_SUBSHAPE );
559 RETURNCASE( HYP_BAD_GEOMETRY );
560 RETURNCASE( HYP_NEED_SHAPE );
561 RETURNCASE( HYP_INCOMPAT_HYPS );
564 return SMESH::HYP_UNKNOWN_FATAL;
567 //=============================================================================
571 * calls internal addHypothesis() and then adds a reference to <anHyp> under
572 * the SObject actually having a reference to <aSubShape>.
573 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
575 //=============================================================================
577 SMESH::Hypothesis_Status
578 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
579 SMESH::SMESH_Hypothesis_ptr anHyp,
580 CORBA::String_out anErrorText)
581 throw(SALOME::SALOME_Exception)
583 Unexpect aCatch(SALOME_SalomeException);
585 _preMeshInfo->ForgetOrLoad();
588 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
589 anErrorText = error.c_str();
591 SMESH::SMESH_Mesh_var mesh( _this() );
592 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
594 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
596 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
598 // Update Python script
599 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
600 << aSubShape << ", " << anHyp << " )";
602 return ConvertHypothesisStatus(status);
605 //=============================================================================
609 //=============================================================================
611 SMESH_Hypothesis::Hypothesis_Status
612 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
613 SMESH::SMESH_Hypothesis_ptr anHyp,
614 std::string* anErrorText)
616 if(MYDEBUG) MESSAGE("addHypothesis");
618 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
619 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
621 if (CORBA::is_nil( anHyp ))
622 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
624 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
627 TopoDS_Shape myLocSubShape;
628 //use PseudoShape in case if mesh has no shape
630 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
632 myLocSubShape = _impl->GetShapeToMesh();
634 const int hypId = anHyp->GetId();
636 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
637 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
639 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
641 // assure there is a corresponding submesh
642 if ( !_impl->IsMainShape( myLocSubShape )) {
643 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
644 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
645 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
648 else if ( anErrorText )
650 *anErrorText = error;
653 catch(SALOME_Exception & S_ex)
655 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
660 //=============================================================================
664 //=============================================================================
666 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
667 SMESH::SMESH_Hypothesis_ptr anHyp)
668 throw(SALOME::SALOME_Exception)
670 Unexpect aCatch(SALOME_SalomeException);
672 _preMeshInfo->ForgetOrLoad();
674 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
675 SMESH::SMESH_Mesh_var mesh = _this();
677 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
679 _gen_i->RemoveHypothesisFromShape( 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::SObject_wrap aSO =
850 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
851 if ( !aSO->_is_nil()) {
852 // Update Python script
853 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
854 << aSubShape << ", '" << theName << "' )";
858 catch(SALOME_Exception & S_ex) {
859 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
861 return subMesh._retn();
864 //=============================================================================
868 //=============================================================================
870 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
871 throw (SALOME::SALOME_Exception)
875 if ( theSubMesh->_is_nil() )
878 GEOM::GEOM_Object_var aSubShape;
879 // Remove submesh's SObject
880 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
881 if ( !anSO->_is_nil() ) {
882 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
883 SALOMEDS::SObject_wrap anObj, aRef;
884 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
885 anObj->ReferencedObject( aRef.inout() ))
887 CORBA::Object_var obj = aRef->GetObject();
888 aSubShape = GEOM::GEOM_Object::_narrow( obj );
890 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
891 // aSubShape = theSubMesh->GetSubShape();
893 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
894 builder->RemoveObjectWithChildren( anSO );
896 // Update Python script
897 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
900 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
902 _preMeshInfo->ForgetOrLoad();
904 SMESH_CATCH( SMESH::throwCorbaException );
907 //=============================================================================
911 //=============================================================================
913 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
914 const char* theName )
915 throw(SALOME::SALOME_Exception)
917 Unexpect aCatch(SALOME_SalomeException);
919 _preMeshInfo->FullLoadFromFile();
921 SMESH::SMESH_Group_var aNewGroup =
922 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
924 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
926 SMESH::SMESH_Mesh_var mesh = _this();
927 SALOMEDS::SObject_wrap aSO =
928 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
929 if ( !aSO->_is_nil())
930 // Update Python script
931 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
932 << theElemType << ", '" << theName << "' )";
934 return aNewGroup._retn();
937 //=============================================================================
941 //=============================================================================
942 SMESH::SMESH_GroupOnGeom_ptr
943 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
945 GEOM::GEOM_Object_ptr theGeomObj)
946 throw(SALOME::SALOME_Exception)
948 Unexpect aCatch(SALOME_SalomeException);
950 _preMeshInfo->FullLoadFromFile();
952 SMESH::SMESH_GroupOnGeom_var aNewGroup;
954 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
955 if ( !aShape.IsNull() )
958 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
960 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
962 SMESH::SMESH_Mesh_var mesh = _this();
963 SALOMEDS::SObject_wrap aSO =
964 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
965 if ( !aSO->_is_nil())
966 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
967 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
971 return aNewGroup._retn();
974 //================================================================================
976 * \brief Creates a group whose contents is defined by filter
977 * \param theElemType - group type
978 * \param theName - group name
979 * \param theFilter - the filter
980 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
982 //================================================================================
984 SMESH::SMESH_GroupOnFilter_ptr
985 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
987 SMESH::Filter_ptr theFilter )
988 throw (SALOME::SALOME_Exception)
990 Unexpect aCatch(SALOME_SalomeException);
992 _preMeshInfo->FullLoadFromFile();
994 if ( CORBA::is_nil( theFilter ))
995 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
997 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
999 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1001 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1002 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1005 if ( !aNewGroup->_is_nil() )
1006 aNewGroup->SetFilter( theFilter );
1008 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1010 SMESH::SMESH_Mesh_var mesh = _this();
1011 SALOMEDS::SObject_wrap aSO =
1012 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1014 if ( !aSO->_is_nil())
1015 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1016 << theElemType << ", '" << theName << "', " << theFilter << " )";
1018 return aNewGroup._retn();
1021 //=============================================================================
1025 //=============================================================================
1027 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1028 throw (SALOME::SALOME_Exception)
1030 if ( theGroup->_is_nil() )
1035 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1039 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1040 if ( !aGroupSO->_is_nil() )
1042 // Update Python script
1043 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1045 // Remove group's SObject
1046 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1047 builder->RemoveObjectWithChildren( aGroupSO );
1049 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1051 // Remove the group from SMESH data structures
1052 removeGroup( aGroup->GetLocalID() );
1054 SMESH_CATCH( SMESH::throwCorbaException );
1057 //=============================================================================
1059 * Remove group with its contents
1061 //=============================================================================
1063 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1064 throw (SALOME::SALOME_Exception)
1068 _preMeshInfo->FullLoadFromFile();
1070 if ( theGroup->_is_nil() )
1073 vector<int> nodeIds; // to remove nodes becoming free
1074 if ( !theGroup->IsEmpty() )
1076 CORBA::Long elemID = theGroup->GetID( 1 );
1077 int nbElemNodes = GetElemNbNodes( elemID );
1078 if ( nbElemNodes > 0 )
1079 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1083 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1084 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1085 while ( elemIt->more() )
1087 const SMDS_MeshElement* e = elemIt->next();
1089 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1090 while ( nIt->more() )
1091 nodeIds.push_back( nIt->next()->GetID() );
1093 _impl->GetMeshDS()->RemoveElement( e );
1096 // Remove free nodes
1097 if ( theGroup->GetType() != SMESH::NODE )
1098 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1099 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1100 if ( n->NbInverseElements() == 0 )
1101 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1103 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1105 // Update Python script (theGroup must be alive for this)
1106 pyDump << SMESH::SMESH_Mesh_var(_this())
1107 << ".RemoveGroupWithContents( " << theGroup << " )";
1110 RemoveGroup( theGroup );
1112 SMESH_CATCH( SMESH::throwCorbaException );
1115 //================================================================================
1117 * \brief Get the list of groups existing in the mesh
1118 * \retval SMESH::ListOfGroups * - list of groups
1120 //================================================================================
1122 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1124 Unexpect aCatch(SALOME_SalomeException);
1125 if (MYDEBUG) MESSAGE("GetGroups");
1127 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1130 TPythonDump aPythonDump;
1131 if ( !_mapGroups.empty() )
1133 aPythonDump << "[ ";
1135 aList->length( _mapGroups.size() );
1137 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1138 for ( ; it != _mapGroups.end(); it++ ) {
1139 if ( CORBA::is_nil( it->second )) continue;
1140 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1142 if (i > 1) aPythonDump << ", ";
1143 aPythonDump << it->second;
1147 catch(SALOME_Exception & S_ex) {
1148 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1150 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1152 return aList._retn();
1155 //=============================================================================
1157 * Get number of groups existing in the mesh
1159 //=============================================================================
1161 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1163 Unexpect aCatch(SALOME_SalomeException);
1164 return _mapGroups.size();
1167 //=============================================================================
1169 * New group including all mesh elements present in initial groups is created.
1171 //=============================================================================
1173 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1174 SMESH::SMESH_GroupBase_ptr theGroup2,
1175 const char* theName )
1176 throw (SALOME::SALOME_Exception)
1178 SMESH::SMESH_Group_var aResGrp;
1182 _preMeshInfo->FullLoadFromFile();
1184 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1185 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1187 if ( theGroup1->GetType() != theGroup2->GetType() )
1188 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1193 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1194 if ( aResGrp->_is_nil() )
1195 return SMESH::SMESH_Group::_nil();
1197 aResGrp->AddFrom( theGroup1 );
1198 aResGrp->AddFrom( theGroup2 );
1200 // Update Python script
1201 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1202 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1204 SMESH_CATCH( SMESH::throwCorbaException );
1206 return aResGrp._retn();
1209 //=============================================================================
1211 * \brief New group including all mesh elements present in initial groups is created.
1212 * \param theGroups list of groups
1213 * \param theName name of group to be created
1214 * \return pointer to the new group
1216 //=============================================================================
1218 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1219 const char* theName )
1220 throw (SALOME::SALOME_Exception)
1222 SMESH::SMESH_Group_var aResGrp;
1225 _preMeshInfo->FullLoadFromFile();
1228 return SMESH::SMESH_Group::_nil();
1233 SMESH::ElementType aType = SMESH::ALL;
1234 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1236 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1237 if ( CORBA::is_nil( aGrp ) )
1239 if ( aType == SMESH::ALL )
1240 aType = aGrp->GetType();
1241 else if ( aType != aGrp->GetType() )
1242 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1245 if ( aType == SMESH::ALL )
1246 return SMESH::SMESH_Group::_nil();
1251 aResGrp = CreateGroup( aType, theName );
1252 if ( aResGrp->_is_nil() )
1253 return SMESH::SMESH_Group::_nil();
1255 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1256 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1258 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1259 if ( !CORBA::is_nil( aGrp ) )
1261 aResGrp->AddFrom( aGrp );
1262 if ( g > 0 ) pyDump << ", ";
1266 pyDump << " ], '" << theName << "' )";
1268 SMESH_CATCH( SMESH::throwCorbaException );
1270 return aResGrp._retn();
1273 //=============================================================================
1275 * New group is created. All mesh elements that are
1276 * present in both initial groups are added to the new one.
1278 //=============================================================================
1280 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1281 SMESH::SMESH_GroupBase_ptr theGroup2,
1282 const char* theName )
1283 throw (SALOME::SALOME_Exception)
1285 SMESH::SMESH_Group_var aResGrp;
1290 _preMeshInfo->FullLoadFromFile();
1292 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1293 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1295 if ( theGroup1->GetType() != theGroup2->GetType() )
1296 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1300 // Create Intersection
1301 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1302 if ( aResGrp->_is_nil() )
1303 return aResGrp._retn();
1305 SMESHDS_GroupBase* groupDS1 = 0;
1306 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1307 groupDS1 = grp_i->GetGroupDS();
1309 SMESHDS_GroupBase* groupDS2 = 0;
1310 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1311 groupDS2 = grp_i->GetGroupDS();
1313 SMESHDS_Group* resGroupDS = 0;
1314 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1315 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1317 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1319 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1320 while ( elemIt1->more() )
1322 const SMDS_MeshElement* e = elemIt1->next();
1323 if ( groupDS2->Contains( e ))
1324 resGroupDS->SMDSGroup().Add( e );
1327 // Update Python script
1328 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1329 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1331 SMESH_CATCH( SMESH::throwCorbaException );
1333 return aResGrp._retn();
1336 //=============================================================================
1338 \brief Intersect list of groups. New group is created. All mesh elements that
1339 are present in all initial groups simultaneously are added to the new one.
1340 \param theGroups list of groups
1341 \param theName name of group to be created
1342 \return pointer on the group
1344 //=============================================================================
1345 SMESH::SMESH_Group_ptr
1346 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1347 const char* theName )
1348 throw (SALOME::SALOME_Exception)
1350 SMESH::SMESH_Group_var aResGrp;
1355 _preMeshInfo->FullLoadFromFile();
1358 return SMESH::SMESH_Group::_nil();
1360 // check types and get SMESHDS_GroupBase's
1361 SMESH::ElementType aType = SMESH::ALL;
1362 vector< SMESHDS_GroupBase* > groupVec;
1363 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1365 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1366 if ( CORBA::is_nil( aGrp ) )
1368 if ( aType == SMESH::ALL )
1369 aType = aGrp->GetType();
1370 else if ( aType != aGrp->GetType() )
1371 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1374 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1375 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1377 if ( grpDS->IsEmpty() )
1382 groupVec.push_back( grpDS );
1385 if ( aType == SMESH::ALL ) // all groups are nil
1386 return SMESH::SMESH_Group::_nil();
1391 aResGrp = CreateGroup( aType, theName );
1393 SMESHDS_Group* resGroupDS = 0;
1394 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1395 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1396 if ( !resGroupDS || groupVec.empty() )
1397 return aResGrp._retn();
1400 size_t i, nb = groupVec.size();
1401 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1402 while ( elemIt1->more() )
1404 const SMDS_MeshElement* e = elemIt1->next();
1406 for ( i = 1; ( i < nb && inAll ); ++i )
1407 inAll = groupVec[i]->Contains( e );
1410 resGroupDS->SMDSGroup().Add( e );
1413 // Update Python script
1414 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1415 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1417 SMESH_CATCH( SMESH::throwCorbaException );
1419 return aResGrp._retn();
1422 //=============================================================================
1424 * New group is created. All mesh elements that are present in
1425 * a main group but is not present in a tool group are added to the new one
1427 //=============================================================================
1429 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1430 SMESH::SMESH_GroupBase_ptr theGroup2,
1431 const char* theName )
1432 throw (SALOME::SALOME_Exception)
1434 SMESH::SMESH_Group_var aResGrp;
1439 _preMeshInfo->FullLoadFromFile();
1441 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1442 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1444 if ( theGroup1->GetType() != theGroup2->GetType() )
1445 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1449 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1450 if ( aResGrp->_is_nil() )
1451 return aResGrp._retn();
1453 SMESHDS_GroupBase* groupDS1 = 0;
1454 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1455 groupDS1 = grp_i->GetGroupDS();
1457 SMESHDS_GroupBase* groupDS2 = 0;
1458 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1459 groupDS2 = grp_i->GetGroupDS();
1461 SMESHDS_Group* resGroupDS = 0;
1462 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1463 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1465 if ( groupDS1 && groupDS2 && resGroupDS )
1467 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1468 while ( elemIt1->more() )
1470 const SMDS_MeshElement* e = elemIt1->next();
1471 if ( !groupDS2->Contains( e ))
1472 resGroupDS->SMDSGroup().Add( e );
1475 // Update Python script
1476 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1477 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1479 SMESH_CATCH( SMESH::throwCorbaException );
1481 return aResGrp._retn();
1484 //=============================================================================
1486 \brief Cut lists of groups. New group is created. All mesh elements that are
1487 present in main groups but do not present in tool groups are added to the new one
1488 \param theMainGroups list of main groups
1489 \param theToolGroups list of tool groups
1490 \param theName name of group to be created
1491 \return pointer on the group
1493 //=============================================================================
1494 SMESH::SMESH_Group_ptr
1495 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1496 const SMESH::ListOfGroups& theToolGroups,
1497 const char* theName )
1498 throw (SALOME::SALOME_Exception)
1500 SMESH::SMESH_Group_var aResGrp;
1505 _preMeshInfo->FullLoadFromFile();
1508 return SMESH::SMESH_Group::_nil();
1510 // check types and get SMESHDS_GroupBase's
1511 SMESH::ElementType aType = SMESH::ALL;
1512 vector< SMESHDS_GroupBase* > toolGroupVec;
1513 vector< SMDS_ElemIteratorPtr > mainIterVec;
1515 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1517 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1518 if ( CORBA::is_nil( aGrp ) )
1520 if ( aType == SMESH::ALL )
1521 aType = aGrp->GetType();
1522 else if ( aType != aGrp->GetType() )
1523 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1525 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1526 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1527 if ( !grpDS->IsEmpty() )
1528 mainIterVec.push_back( grpDS->GetElements() );
1530 if ( aType == SMESH::ALL ) // all main groups are nil
1531 return SMESH::SMESH_Group::_nil();
1532 if ( mainIterVec.empty() ) // all main groups are empty
1533 return aResGrp._retn();
1535 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1537 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1538 if ( CORBA::is_nil( aGrp ) )
1540 if ( aType != aGrp->GetType() )
1541 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1543 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1544 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1545 toolGroupVec.push_back( grpDS );
1551 aResGrp = CreateGroup( aType, theName );
1553 SMESHDS_Group* resGroupDS = 0;
1554 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1555 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1557 return aResGrp._retn();
1560 size_t i, nb = toolGroupVec.size();
1561 SMDS_ElemIteratorPtr mainElemIt
1562 ( new SMDS_IteratorOnIterators
1563 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1564 while ( mainElemIt->more() )
1566 const SMDS_MeshElement* e = mainElemIt->next();
1568 for ( i = 0; ( i < nb && !isIn ); ++i )
1569 isIn = toolGroupVec[i]->Contains( e );
1572 resGroupDS->SMDSGroup().Add( e );
1575 // Update Python script
1576 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1577 << ".CutListOfGroups( " << theMainGroups << ", "
1578 << theToolGroups << ", '" << theName << "' )";
1580 SMESH_CATCH( SMESH::throwCorbaException );
1582 return aResGrp._retn();
1585 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1587 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1588 bool & toStopChecking )
1590 toStopChecking = ( nbCommon < nbChecked );
1591 return nbCommon == nbNodes;
1593 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1594 bool & toStopChecking )
1596 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1597 return nbCommon == nbCorners;
1599 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1600 bool & toStopChecking )
1602 return nbCommon > 0;
1604 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1605 bool & toStopChecking )
1607 return nbCommon >= (nbNodes+1) / 2;
1611 //=============================================================================
1613 * Create a group of entities basing on nodes of other groups.
1614 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1615 * \param [in] anElemType - a type of elements to include to the new group.
1616 * \param [in] theName - a name of the new group.
1617 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1618 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1619 * new group provided that it is based on nodes of an element of \a aListOfGroups
1620 * \return SMESH_Group - the created group
1622 // IMP 19939, bug 22010, IMP 22635
1623 //=============================================================================
1625 SMESH::SMESH_Group_ptr
1626 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1627 SMESH::ElementType theElemType,
1628 const char* theName,
1629 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1630 CORBA::Boolean theUnderlyingOnly)
1631 throw (SALOME::SALOME_Exception)
1633 SMESH::SMESH_Group_var aResGrp;
1637 _preMeshInfo->FullLoadFromFile();
1639 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1641 if ( !theName || !aMeshDS )
1642 return SMESH::SMESH_Group::_nil();
1644 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1646 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1647 SMESH_Comment nbCoNoStr( "SMESH.");
1648 switch ( theNbCommonNodes ) {
1649 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1650 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1651 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1652 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1653 default: return aResGrp._retn();
1655 int nbChecked, nbCommon, nbNodes, nbCorners;
1661 aResGrp = CreateGroup( theElemType, theName );
1662 if ( aResGrp->_is_nil() )
1663 return SMESH::SMESH_Group::_nil();
1665 SMESHDS_GroupBase* groupBaseDS =
1666 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1667 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1669 vector<bool> isNodeInGroups;
1671 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1673 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1674 if ( CORBA::is_nil( aGrp ) )
1676 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1677 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1680 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1681 if ( !elIt ) continue;
1683 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1685 while ( elIt->more() ) {
1686 const SMDS_MeshElement* el = elIt->next();
1687 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1688 while ( nIt->more() )
1689 resGroupCore.Add( nIt->next() );
1692 // get elements of theElemType based on nodes of every element of group
1693 else if ( theUnderlyingOnly )
1695 while ( elIt->more() )
1697 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1698 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1699 TIDSortedElemSet checkedElems;
1700 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1701 while ( nIt->more() )
1703 const SMDS_MeshNode* n = nIt->next();
1704 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1705 // check nodes of elements of theElemType around el
1706 while ( elOfTypeIt->more() )
1708 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1709 if ( !checkedElems.insert( elOfType ).second ) continue;
1710 nbNodes = elOfType->NbNodes();
1711 nbCorners = elOfType->NbCornerNodes();
1713 bool toStopChecking = false;
1714 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1715 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1716 if ( elNodes.count( nIt2->next() ) &&
1717 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1719 resGroupCore.Add( elOfType );
1726 // get all nodes of elements of groups
1729 while ( elIt->more() )
1731 const SMDS_MeshElement* el = elIt->next(); // an element of group
1732 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1733 while ( nIt->more() )
1735 const SMDS_MeshNode* n = nIt->next();
1736 if ( n->GetID() >= (int) isNodeInGroups.size() )
1737 isNodeInGroups.resize( n->GetID() + 1, false );
1738 isNodeInGroups[ n->GetID() ] = true;
1744 // Get elements of theElemType based on a certain number of nodes of elements of groups
1745 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1747 const SMDS_MeshNode* n;
1748 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1749 const int isNodeInGroupsSize = isNodeInGroups.size();
1750 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1752 if ( !isNodeInGroups[ iN ] ||
1753 !( n = aMeshDS->FindNode( iN )))
1756 // check nodes of elements of theElemType around n
1757 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1758 while ( elOfTypeIt->more() )
1760 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1761 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1766 nbNodes = elOfType->NbNodes();
1767 nbCorners = elOfType->NbCornerNodes();
1769 bool toStopChecking = false;
1770 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1771 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1773 const int nID = nIt->next()->GetID();
1774 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1775 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1777 resGroupCore.Add( elOfType );
1785 // Update Python script
1786 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1787 << ".CreateDimGroup( "
1788 << theGroups << ", " << theElemType << ", '" << theName << "', "
1789 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1791 SMESH_CATCH( SMESH::throwCorbaException );
1793 return aResGrp._retn();
1796 //================================================================================
1798 * \brief Remember GEOM group data
1800 //================================================================================
1802 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1803 CORBA::Object_ptr theSmeshObj)
1805 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1808 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1809 if ( groupSO->_is_nil() )
1812 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1813 GEOM::GEOM_IGroupOperations_wrap groupOp =
1814 geomGen->GetIGroupOperations();
1815 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1818 _geomGroupData.push_back( TGeomGroupData() );
1819 TGeomGroupData & groupData = _geomGroupData.back();
1821 CORBA::String_var entry = groupSO->GetID();
1822 groupData._groupEntry = entry.in();
1824 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1825 groupData._indices.insert( ids[i] );
1827 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1828 // shape index in SMESHDS
1829 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1830 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1833 //================================================================================
1835 * Remove GEOM group data relating to removed smesh object
1837 //================================================================================
1839 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1841 list<TGeomGroupData>::iterator
1842 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1843 for ( ; data != dataEnd; ++data ) {
1844 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1845 _geomGroupData.erase( data );
1851 //================================================================================
1853 * \brief Return new group contents if it has been changed and update group data
1855 //================================================================================
1857 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1859 TopoDS_Shape newShape;
1862 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
1863 if ( !groupSO->_is_nil() )
1865 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1866 if ( CORBA::is_nil( groupObj )) return newShape;
1867 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1869 // get indices of group items
1870 set<int> curIndices;
1871 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1872 GEOM::GEOM_IGroupOperations_wrap groupOp =
1873 geomGen->GetIGroupOperations();
1874 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1875 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1876 curIndices.insert( ids[i] );
1878 if ( groupData._indices == curIndices )
1879 return newShape; // group not changed
1882 groupData._indices = curIndices;
1884 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1885 if ( !geomClient ) return newShape;
1886 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1887 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1888 newShape = _gen_i->GeomObjectToShape( geomGroup );
1891 if ( newShape.IsNull() ) {
1892 // geom group becomes empty - return empty compound
1893 TopoDS_Compound compound;
1894 BRep_Builder().MakeCompound(compound);
1895 newShape = compound;
1902 //-----------------------------------------------------------------------------
1904 * \brief Storage of shape and index used in CheckGeomGroupModif()
1906 struct TIndexedShape
1909 TopoDS_Shape _shape;
1910 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1912 //-----------------------------------------------------------------------------
1914 * \brief Data to re-create a group on geometry
1916 struct TGroupOnGeomData
1920 SMDSAbs_ElementType _type;
1922 Quantity_Color _color;
1926 //=============================================================================
1928 * \brief Update data if geometry changes
1932 //=============================================================================
1934 void SMESH_Mesh_i::CheckGeomModif()
1936 if ( !_impl->HasShapeToMesh() ) return;
1938 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1939 //if ( mainGO->_is_nil() ) return;
1941 // Update after group modification
1943 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1944 called by other mesh (IPAL52735) */
1945 mainGO->GetType() == GEOM_GROUP ||
1946 mainGO->GetTick() == _mainShapeTick )
1948 CheckGeomGroupModif();
1952 // Update after shape transformation like Translate
1954 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1955 if ( !geomClient ) return;
1956 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1957 if ( geomGen->_is_nil() ) return;
1959 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1960 geomClient->RemoveShapeFromBuffer( ior.in() );
1962 // Update data taking into account that
1963 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1966 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1967 if ( newShape.IsNull() )
1970 _mainShapeTick = mainGO->GetTick();
1972 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1974 // store data of groups on geometry
1975 vector< TGroupOnGeomData > groupsData;
1976 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1977 groupsData.reserve( groups.size() );
1978 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1979 for ( ; g != groups.end(); ++g )
1980 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1982 TGroupOnGeomData data;
1983 data._oldID = group->GetID();
1984 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1985 data._type = group->GetType();
1986 data._name = group->GetStoreName();
1987 data._color = group->GetColor();
1988 groupsData.push_back( data );
1990 // store assigned hypotheses
1991 vector< pair< int, THypList > > ids2Hyps;
1992 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
1993 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
1995 const TopoDS_Shape& s = s2hyps.Key();
1996 const THypList& hyps = s2hyps.ChangeValue();
1997 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2000 // change shape to mesh
2001 int oldNbSubShapes = meshDS->MaxShapeIndex();
2002 _impl->ShapeToMesh( TopoDS_Shape() );
2003 _impl->ShapeToMesh( newShape );
2005 // re-add shapes of geom groups
2006 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2007 for ( ; data != _geomGroupData.end(); ++data )
2009 TopoDS_Shape newShape = newGroupShape( *data );
2010 if ( !newShape.IsNull() )
2012 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2014 TopoDS_Compound compound;
2015 BRep_Builder().MakeCompound( compound );
2016 BRep_Builder().Add( compound, newShape );
2017 newShape = compound;
2019 _impl->GetSubMesh( newShape );
2022 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2023 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2024 SALOME::INTERNAL_ERROR );
2026 // re-assign hypotheses
2027 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2029 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2030 const THypList& hyps = ids2Hyps[i].second;
2031 THypList::const_iterator h = hyps.begin();
2032 for ( ; h != hyps.end(); ++h )
2033 _impl->AddHypothesis( s, (*h)->GetID() );
2037 for ( size_t i = 0; i < groupsData.size(); ++i )
2039 const TGroupOnGeomData& data = groupsData[i];
2041 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2042 if ( i2g == _mapGroups.end() ) continue;
2044 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2045 if ( !gr_i ) continue;
2048 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2049 meshDS->IndexToShape( data._shapeID ));
2052 _mapGroups.erase( i2g );
2056 g->GetGroupDS()->SetColor( data._color );
2057 gr_i->changeLocalId( id );
2058 _mapGroups[ id ] = i2g->second;
2059 if ( data._oldID != id )
2060 _mapGroups.erase( i2g );
2064 // update _mapSubMesh
2065 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2066 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2067 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2071 //=============================================================================
2073 * \brief Update objects depending on changed geom groups
2075 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2076 * issue 0020210: Update of a smesh group after modification of the associated geom group
2078 //=============================================================================
2080 void SMESH_Mesh_i::CheckGeomGroupModif()
2082 if ( !_impl->HasShapeToMesh() ) return;
2084 CORBA::Long nbEntities = NbNodes() + NbElements();
2086 // Check if group contents changed
2088 typedef map< string, TopoDS_Shape > TEntry2Geom;
2089 TEntry2Geom newGroupContents;
2091 list<TGeomGroupData>::iterator
2092 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2093 for ( ; data != dataEnd; ++data )
2095 pair< TEntry2Geom::iterator, bool > it_new =
2096 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2097 bool processedGroup = !it_new.second;
2098 TopoDS_Shape& newShape = it_new.first->second;
2099 if ( !processedGroup )
2100 newShape = newGroupShape( *data );
2101 if ( newShape.IsNull() )
2102 continue; // no changes
2105 _preMeshInfo->ForgetOrLoad();
2107 if ( processedGroup ) { // update group indices
2108 list<TGeomGroupData>::iterator data2 = data;
2109 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2110 data->_indices = data2->_indices;
2113 // Update SMESH objects according to new GEOM group contents
2115 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2116 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2118 int oldID = submesh->GetId();
2119 if ( !_mapSubMeshIor.count( oldID ))
2121 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2123 // update hypotheses
2124 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2125 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2126 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2128 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2129 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2131 // care of submeshes
2132 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2133 int newID = newSubmesh->GetId();
2134 if ( newID != oldID ) {
2135 _mapSubMesh [ newID ] = newSubmesh;
2136 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2137 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2138 _mapSubMesh. erase(oldID);
2139 _mapSubMesh_i. erase(oldID);
2140 _mapSubMeshIor.erase(oldID);
2141 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2146 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2147 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2148 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2150 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2152 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2153 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2154 ds->SetShape( newShape );
2159 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2160 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2162 // Remove groups and submeshes basing on removed sub-shapes
2164 TopTools_MapOfShape newShapeMap;
2165 TopoDS_Iterator shapeIt( newShape );
2166 for ( ; shapeIt.More(); shapeIt.Next() )
2167 newShapeMap.Add( shapeIt.Value() );
2169 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2170 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2172 if ( newShapeMap.Contains( shapeIt.Value() ))
2174 TopTools_IndexedMapOfShape oldShapeMap;
2175 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2176 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2178 const TopoDS_Shape& oldShape = oldShapeMap(i);
2179 int oldInd = meshDS->ShapeToIndex( oldShape );
2181 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2182 if ( i_smIor != _mapSubMeshIor.end() ) {
2183 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2186 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2187 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2189 // check if a group bases on oldInd shape
2190 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2191 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2192 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2193 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2195 RemoveGroup( i_grp->second ); // several groups can base on same shape
2196 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2201 // Reassign hypotheses and update groups after setting the new shape to mesh
2203 // collect anassigned hypotheses
2204 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2205 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2206 TShapeHypList assignedHyps;
2207 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2209 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2210 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2211 if ( !hyps.empty() ) {
2212 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2213 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2214 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2217 // collect shapes supporting groups
2218 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2219 TShapeTypeList groupData;
2220 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2221 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2222 for ( ; grIt != groups.end(); ++grIt )
2224 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2226 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2228 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2230 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2231 _impl->ShapeToMesh( newShape );
2233 // reassign hypotheses
2234 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2235 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2237 TIndexedShape& geom = indS_hyps->first;
2238 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2239 int oldID = geom._index;
2240 int newID = meshDS->ShapeToIndex( geom._shape );
2241 if ( oldID == 1 ) { // main shape
2243 geom._shape = newShape;
2247 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2248 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2249 // care of sub-meshes
2250 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2251 if ( newID != oldID ) {
2252 _mapSubMesh [ newID ] = newSubmesh;
2253 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2254 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2255 _mapSubMesh. erase(oldID);
2256 _mapSubMesh_i. erase(oldID);
2257 _mapSubMeshIor.erase(oldID);
2258 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2262 TShapeTypeList::iterator geomType = groupData.begin();
2263 for ( ; geomType != groupData.end(); ++geomType )
2265 const TIndexedShape& geom = geomType->first;
2266 int oldID = geom._index;
2267 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2270 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2271 CORBA::String_var name = groupSO->GetName();
2273 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2275 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2276 group_i->changeLocalId( newID );
2279 break; // everything has been updated
2282 } // loop on group data
2286 CORBA::Long newNbEntities = NbNodes() + NbElements();
2287 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2288 if ( newNbEntities != nbEntities )
2290 // Add all SObjects with icons to soToUpdateIcons
2291 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2293 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2294 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2295 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2297 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2298 i_gr != _mapGroups.end(); ++i_gr ) // groups
2299 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2302 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2303 for ( ; so != soToUpdateIcons.end(); ++so )
2304 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2307 //=============================================================================
2309 * \brief Create standalone group from a group on geometry or filter
2311 //=============================================================================
2313 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2314 throw (SALOME::SALOME_Exception)
2316 SMESH::SMESH_Group_var aGroup;
2321 _preMeshInfo->FullLoadFromFile();
2323 if ( theGroup->_is_nil() )
2324 return aGroup._retn();
2326 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2328 return aGroup._retn();
2330 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2332 const int anId = aGroupToRem->GetLocalID();
2333 if ( !_impl->ConvertToStandalone( anId ) )
2334 return aGroup._retn();
2335 removeGeomGroupData( theGroup );
2337 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2339 // remove old instance of group from own map
2340 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2341 _mapGroups.erase( anId );
2343 SALOMEDS::StudyBuilder_var builder;
2344 SALOMEDS::SObject_wrap aGroupSO;
2345 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2346 if ( !aStudy->_is_nil() ) {
2347 builder = aStudy->NewBuilder();
2348 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2349 if ( !aGroupSO->_is_nil() )
2351 // remove reference to geometry
2352 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2353 for ( ; chItr->More(); chItr->Next() )
2354 // Remove group's child SObject
2355 builder->RemoveObject( chItr->Value() );
2357 // Update Python script
2358 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2359 << ".ConvertToStandalone( " << aGroupSO << " )";
2361 // change icon of Group on Filter
2364 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2365 const int isEmpty = ( elemTypes->length() == 0 );
2368 SALOMEDS::GenericAttribute_wrap anAttr =
2369 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2370 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2371 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2377 // remember new group in own map
2378 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2379 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2381 // register CORBA object for persistence
2382 _gen_i->RegisterObject( aGroup );
2384 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2385 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2386 //aGroup->Register();
2387 aGroupToRem->UnRegister();
2389 SMESH_CATCH( SMESH::throwCorbaException );
2391 return aGroup._retn();
2394 //=============================================================================
2398 //=============================================================================
2400 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2402 if(MYDEBUG) MESSAGE( "createSubMesh" );
2403 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2404 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2405 const int subMeshId = mySubMesh->GetId();
2407 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2408 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2410 _mapSubMesh [subMeshId] = mySubMesh;
2411 _mapSubMesh_i [subMeshId] = subMeshServant;
2412 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2414 subMeshServant->Register();
2416 // register CORBA object for persistence
2417 int nextId = _gen_i->RegisterObject( subMesh );
2418 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2419 else { nextId = 0; } // avoid "unused variable" warning
2421 // to track changes of GEOM groups
2422 addGeomGroupData( theSubShapeObject, subMesh );
2424 return subMesh._retn();
2427 //=======================================================================
2428 //function : getSubMesh
2430 //=======================================================================
2432 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2434 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2435 if ( it == _mapSubMeshIor.end() )
2436 return SMESH::SMESH_subMesh::_nil();
2438 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2441 //=============================================================================
2445 //=============================================================================
2447 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2448 GEOM::GEOM_Object_ptr theSubShapeObject )
2450 bool isHypChanged = false;
2451 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2452 return isHypChanged;
2454 const int subMeshId = theSubMesh->GetId();
2456 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2458 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2460 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2463 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2464 isHypChanged = !hyps.empty();
2465 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2466 for ( ; hyp != hyps.end(); ++hyp )
2467 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2474 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2475 isHypChanged = ( aHypList->length() > 0 );
2476 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2477 removeHypothesis( theSubShapeObject, aHypList[i] );
2480 catch( const SALOME::SALOME_Exception& ) {
2481 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2483 removeGeomGroupData( theSubShapeObject );
2487 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2488 if ( id_smi != _mapSubMesh_i.end() )
2489 id_smi->second->UnRegister();
2491 // remove a CORBA object
2492 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2493 if ( id_smptr != _mapSubMeshIor.end() )
2494 SMESH::SMESH_subMesh_var( id_smptr->second );
2496 _mapSubMesh.erase(subMeshId);
2497 _mapSubMesh_i.erase(subMeshId);
2498 _mapSubMeshIor.erase(subMeshId);
2500 return isHypChanged;
2503 //=============================================================================
2507 //=============================================================================
2509 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2510 const char* theName,
2511 const TopoDS_Shape& theShape,
2512 const SMESH_PredicatePtr& thePredicate )
2514 std::string newName;
2515 if ( !theName || strlen( theName ) == 0 )
2517 std::set< std::string > presentNames;
2518 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2519 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2521 CORBA::String_var name = i_gr->second->GetName();
2522 presentNames.insert( name.in() );
2525 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2526 } while ( !presentNames.insert( newName ).second );
2527 theName = newName.c_str();
2530 SMESH::SMESH_GroupBase_var aGroup;
2531 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2533 SMESH_GroupBase_i* aGroupImpl;
2534 if ( !theShape.IsNull() )
2535 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2536 else if ( thePredicate )
2537 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2539 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2541 aGroup = aGroupImpl->_this();
2542 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2543 aGroupImpl->Register();
2545 // register CORBA object for persistence
2546 int nextId = _gen_i->RegisterObject( aGroup );
2547 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2548 else { nextId = 0; } // avoid "unused variable" warning in release mode
2550 // to track changes of GEOM groups
2551 if ( !theShape.IsNull() ) {
2552 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2553 addGeomGroupData( geom, aGroup );
2556 return aGroup._retn();
2559 //=============================================================================
2561 * SMESH_Mesh_i::removeGroup
2563 * Should be called by ~SMESH_Group_i()
2565 //=============================================================================
2567 void SMESH_Mesh_i::removeGroup( const int theId )
2569 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2570 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2571 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2572 _mapGroups.erase( theId );
2573 removeGeomGroupData( group );
2574 if ( !_impl->RemoveGroup( theId ))
2576 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2577 RemoveGroup( group );
2579 group->UnRegister();
2583 //=============================================================================
2587 //=============================================================================
2589 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2590 throw(SALOME::SALOME_Exception)
2592 SMESH::log_array_var aLog;
2596 _preMeshInfo->FullLoadFromFile();
2598 list < SMESHDS_Command * >logDS = _impl->GetLog();
2599 aLog = new SMESH::log_array;
2601 int lg = logDS.size();
2604 list < SMESHDS_Command * >::iterator its = logDS.begin();
2605 while(its != logDS.end()){
2606 SMESHDS_Command *com = *its;
2607 int comType = com->GetType();
2609 int lgcom = com->GetNumber();
2611 const list < int >&intList = com->GetIndexes();
2612 int inum = intList.size();
2614 list < int >::const_iterator ii = intList.begin();
2615 const list < double >&coordList = com->GetCoords();
2616 int rnum = coordList.size();
2618 list < double >::const_iterator ir = coordList.begin();
2619 aLog[indexLog].commandType = comType;
2620 aLog[indexLog].number = lgcom;
2621 aLog[indexLog].coords.length(rnum);
2622 aLog[indexLog].indexes.length(inum);
2623 for(int i = 0; i < rnum; i++){
2624 aLog[indexLog].coords[i] = *ir;
2625 //MESSAGE(" "<<i<<" "<<ir.Value());
2628 for(int i = 0; i < inum; i++){
2629 aLog[indexLog].indexes[i] = *ii;
2630 //MESSAGE(" "<<i<<" "<<ii.Value());
2639 SMESH_CATCH( SMESH::throwCorbaException );
2641 return aLog._retn();
2645 //=============================================================================
2649 //=============================================================================
2651 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2655 SMESH_CATCH( SMESH::throwCorbaException );
2658 //=============================================================================
2662 //=============================================================================
2664 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2669 //=============================================================================
2672 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2673 // issue 0020918: groups removal is caused by hyp modification
2674 // issue 0021208: to forget not loaded mesh data at hyp modification
2675 struct TCallUp_i : public SMESH_Mesh::TCallUp
2677 SMESH_Mesh_i* _mesh;
2678 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2679 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2680 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2681 virtual void Load () { _mesh->Load(); }
2685 //================================================================================
2687 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2689 //================================================================================
2691 void SMESH_Mesh_i::onHypothesisModified()
2694 _preMeshInfo->ForgetOrLoad();
2697 //=============================================================================
2701 //=============================================================================
2703 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2705 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2708 _impl->SetCallUp( new TCallUp_i(this));
2711 //=============================================================================
2715 //=============================================================================
2717 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2719 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2723 //=============================================================================
2725 * Return mesh editor
2727 //=============================================================================
2729 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2730 throw (SALOME::SALOME_Exception)
2732 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2736 _preMeshInfo->FullLoadFromFile();
2738 // Create MeshEditor
2740 _editor = new SMESH_MeshEditor_i( this, false );
2741 aMeshEdVar = _editor->_this();
2743 // Update Python script
2744 TPythonDump() << _editor << " = "
2745 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2747 SMESH_CATCH( SMESH::throwCorbaException );
2749 return aMeshEdVar._retn();
2752 //=============================================================================
2754 * Return mesh edition previewer
2756 //=============================================================================
2758 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2759 throw (SALOME::SALOME_Exception)
2761 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2765 _preMeshInfo->FullLoadFromFile();
2767 if ( !_previewEditor )
2768 _previewEditor = new SMESH_MeshEditor_i( this, true );
2769 aMeshEdVar = _previewEditor->_this();
2771 SMESH_CATCH( SMESH::throwCorbaException );
2773 return aMeshEdVar._retn();
2776 //================================================================================
2778 * \brief Return true if the mesh has been edited since a last total re-compute
2779 * and those modifications may prevent successful partial re-compute
2781 //================================================================================
2783 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2785 Unexpect aCatch(SALOME_SalomeException);
2786 return _impl->HasModificationsToDiscard();
2789 //================================================================================
2791 * \brief Returns a random unique color
2793 //================================================================================
2795 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2797 const int MAX_ATTEMPTS = 100;
2799 double tolerance = 0.5;
2800 SALOMEDS::Color col;
2804 // generate random color
2805 double red = (double)rand() / RAND_MAX;
2806 double green = (double)rand() / RAND_MAX;
2807 double blue = (double)rand() / RAND_MAX;
2808 // check existence in the list of the existing colors
2809 bool matched = false;
2810 std::list<SALOMEDS::Color>::const_iterator it;
2811 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2812 SALOMEDS::Color color = *it;
2813 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2814 matched = tol < tolerance;
2816 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2817 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2825 //=============================================================================
2827 * Sets auto-color mode. If it is on, groups get unique random colors
2829 //=============================================================================
2831 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2833 Unexpect aCatch(SALOME_SalomeException);
2834 _impl->SetAutoColor(theAutoColor);
2836 TPythonDump pyDump; // not to dump group->SetColor() from below code
2837 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2839 std::list<SALOMEDS::Color> aReservedColors;
2840 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2841 for ( ; it != _mapGroups.end(); it++ ) {
2842 if ( CORBA::is_nil( it->second )) continue;
2843 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2844 it->second->SetColor( aColor );
2845 aReservedColors.push_back( aColor );
2849 //=============================================================================
2851 * Returns true if auto-color mode is on
2853 //=============================================================================
2855 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2857 Unexpect aCatch(SALOME_SalomeException);
2858 return _impl->GetAutoColor();
2861 //=============================================================================
2863 * Checks if there are groups with equal names
2865 //=============================================================================
2867 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2869 return _impl->HasDuplicatedGroupNamesMED();
2872 //================================================================================
2874 * \brief Care of a file before exporting mesh into it
2876 //================================================================================
2878 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2880 SMESH_File aFile( file );
2882 if (aFile.exists()) {
2883 // existing filesystem node
2884 if ( !aFile.isDirectory() ) {
2885 if ( aFile.openForWriting() ) {
2886 if ( overwrite && ! aFile.remove()) {
2887 msg << "Can't replace " << aFile.getName();
2890 msg << "Can't write into " << aFile.getName();
2893 msg << "Location " << aFile.getName() << " is not a file";
2897 // nonexisting file; check if it can be created
2898 if ( !aFile.openForWriting() ) {
2899 msg << "You cannot create the file "
2901 << ". Check the directory existence and access rights";
2909 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2913 //================================================================================
2915 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2916 * \param file - file name
2917 * \param overwrite - to erase the file or not
2918 * \retval string - mesh name
2920 //================================================================================
2922 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2923 CORBA::Boolean overwrite)
2926 PrepareForWriting(file, overwrite);
2927 string aMeshName = "Mesh";
2928 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2929 if ( !aStudy->_is_nil() ) {
2930 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
2931 if ( !aMeshSO->_is_nil() ) {
2932 CORBA::String_var name = aMeshSO->GetName();
2934 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2935 if ( !aStudy->GetProperties()->IsLocked() )
2937 SALOMEDS::GenericAttribute_wrap anAttr;
2938 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2939 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2940 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2941 ASSERT(!aFileName->_is_nil());
2942 aFileName->SetValue(file);
2943 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2944 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2945 ASSERT(!aFileType->_is_nil());
2946 aFileType->SetValue("FICHIERMED");
2950 // Update Python script
2951 // set name of mesh before export
2952 TPythonDump() << _gen_i << ".SetName("
2953 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2955 // check names of groups
2961 //================================================================================
2963 * \brief Export to MED file
2965 //================================================================================
2967 void SMESH_Mesh_i::ExportMED(const char* file,
2968 CORBA::Boolean auto_groups,
2969 CORBA::Boolean overwrite,
2970 CORBA::Boolean autoDimension)
2971 throw(SALOME::SALOME_Exception)
2973 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
2976 _preMeshInfo->FullLoadFromFile();
2978 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2979 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, 0, autoDimension );
2981 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
2982 << file << "', " << auto_groups << ", "
2983 << overwrite << ", "
2984 << autoDimension << " )";
2986 SMESH_CATCH( SMESH::throwCorbaException );
2989 //================================================================================
2991 * \brief Export a mesh to a SAUV file
2993 //================================================================================
2995 void SMESH_Mesh_i::ExportSAUV (const char* file,
2996 CORBA::Boolean auto_groups)
2997 throw(SALOME::SALOME_Exception)
2999 Unexpect aCatch(SALOME_SalomeException);
3001 _preMeshInfo->FullLoadFromFile();
3003 string aMeshName = prepareMeshNameAndGroups(file, true);
3004 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3005 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3006 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3010 //================================================================================
3012 * \brief Export a mesh to a DAT file
3014 //================================================================================
3016 void SMESH_Mesh_i::ExportDAT (const char *file)
3017 throw(SALOME::SALOME_Exception)
3019 Unexpect aCatch(SALOME_SalomeException);
3021 _preMeshInfo->FullLoadFromFile();
3023 // Update Python script
3024 // check names of groups
3026 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3029 PrepareForWriting(file);
3030 _impl->ExportDAT(file);
3033 //================================================================================
3035 * \brief Export a mesh to an UNV file
3037 //================================================================================
3039 void SMESH_Mesh_i::ExportUNV (const char *file)
3040 throw(SALOME::SALOME_Exception)
3042 Unexpect aCatch(SALOME_SalomeException);
3044 _preMeshInfo->FullLoadFromFile();
3046 // Update Python script
3047 // check names of groups
3049 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3052 PrepareForWriting(file);
3053 _impl->ExportUNV(file);
3056 //================================================================================
3058 * \brief Export a mesh to an STL file
3060 //================================================================================
3062 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
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())
3073 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3075 CORBA::String_var name;
3076 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3077 if ( !so->_is_nil() )
3078 name = so->GetName();
3081 PrepareForWriting( file );
3082 _impl->ExportSTL( file, isascii, name.in() );
3085 //================================================================================
3087 * \brief Export a part of mesh to a med file
3089 //================================================================================
3091 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3093 CORBA::Boolean auto_groups,
3094 CORBA::Boolean overwrite,
3095 CORBA::Boolean autoDimension,
3096 const GEOM::ListOfFields& fields,
3097 const char* geomAssocFields)
3098 throw (SALOME::SALOME_Exception)
3102 _preMeshInfo->FullLoadFromFile();
3105 bool have0dField = false;
3106 if ( fields.length() > 0 )
3108 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3109 if ( shapeToMesh->_is_nil() )
3110 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3112 for ( size_t i = 0; i < fields.length(); ++i )
3114 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3115 THROW_SALOME_CORBA_EXCEPTION
3116 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3117 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3118 if ( fieldShape->_is_nil() )
3119 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3120 if ( !fieldShape->IsSame( shapeToMesh ) )
3121 THROW_SALOME_CORBA_EXCEPTION
3122 ( "Field defined not on shape", SALOME::BAD_PARAM);
3123 if ( fields[i]->GetDimension() == 0 )
3126 if ( geomAssocFields )
3127 for ( int i = 0; geomAssocFields[i]; ++i )
3128 switch ( geomAssocFields[i] ) {
3129 case 'v':case 'e':case 'f':case 's': break;
3130 case 'V':case 'E':case 'F':case 'S': break;
3131 default: THROW_SALOME_CORBA_EXCEPTION
3132 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3136 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3140 string aMeshName = "Mesh";
3141 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3142 if ( CORBA::is_nil( meshPart ) ||
3143 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3145 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3146 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3147 0, autoDimension, /*addODOnVertices=*/have0dField);
3148 meshDS = _impl->GetMeshDS();
3153 _preMeshInfo->FullLoadFromFile();
3155 PrepareForWriting(file, overwrite);
3157 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3158 if ( !SO->_is_nil() ) {
3159 CORBA::String_var name = SO->GetName();
3163 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3164 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3165 partDS, autoDimension, /*addODOnVertices=*/have0dField);
3166 meshDS = tmpDSDeleter._obj = partDS;
3171 if ( _impl->HasShapeToMesh() )
3173 DriverMED_W_Field fieldWriter;
3174 fieldWriter.SetFile( file );
3175 fieldWriter.SetMeshName( aMeshName );
3176 fieldWriter.AddODOnVertices( have0dField );
3178 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3182 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3183 goList->length( fields.length() );
3184 for ( size_t i = 0; i < fields.length(); ++i )
3186 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3189 TPythonDump() << _this() << ".ExportPartToMED( "
3190 << meshPart << ", r'" << file << "', "
3191 << auto_groups << ", " << overwrite << ", "
3192 << autoDimension << ", " << goList
3193 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3195 SMESH_CATCH( SMESH::throwCorbaException );
3198 //================================================================================
3200 * Write GEOM fields to MED file
3202 //================================================================================
3204 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3205 SMESHDS_Mesh* meshDS,
3206 const GEOM::ListOfFields& fields,
3207 const char* geomAssocFields)
3209 #define METH "SMESH_Mesh_i::exportMEDFields() "
3211 if (( fields.length() < 1 ) &&
3212 ( !geomAssocFields || !geomAssocFields[0] ))
3215 std::vector< std::vector< double > > dblVals;
3216 std::vector< std::vector< int > > intVals;
3217 std::vector< int > subIdsByDim[ 4 ];
3218 const double noneDblValue = 0.;
3219 const double noneIntValue = 0;
3221 for ( size_t iF = 0; iF < fields.length(); ++iF )
3225 int dim = fields[ iF ]->GetDimension();
3226 SMDSAbs_ElementType elemType;
3227 TopAbs_ShapeEnum shapeType;
3229 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3230 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3231 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3232 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3234 continue; // skip fields on whole shape
3236 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3237 if ( dataType == GEOM::FDT_String )
3239 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3240 if ( stepIDs->length() < 1 )
3242 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3243 if ( comps->length() < 1 )
3245 CORBA::String_var name = fields[ iF ]->GetName();
3247 if ( !fieldWriter.Set( meshDS,
3251 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3254 for ( size_t iC = 0; iC < comps->length(); ++iC )
3255 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3257 dblVals.resize( comps->length() );
3258 intVals.resize( comps->length() );
3260 // find sub-shape IDs
3262 std::vector< int >& subIds = subIdsByDim[ dim ];
3263 if ( subIds.empty() )
3264 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3265 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3266 subIds.push_back( id );
3270 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3274 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3276 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3277 if ( step->_is_nil() )
3280 CORBA::Long stamp = step->GetStamp();
3281 CORBA::Long id = step->GetID();
3282 fieldWriter.SetDtIt( int( stamp ), int( id ));
3284 // fill dblVals or intVals
3285 for ( size_t iC = 0; iC < comps->length(); ++iC )
3286 if ( dataType == GEOM::FDT_Double )
3288 dblVals[ iC ].clear();
3289 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3293 intVals[ iC ].clear();
3294 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3298 case GEOM::FDT_Double:
3300 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3301 if ( dblStep->_is_nil() ) continue;
3302 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3303 if ( vv->length() != subIds.size() * comps->length() )
3304 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3305 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3306 for ( size_t iC = 0; iC < comps->length(); ++iC )
3307 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3312 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3313 if ( intStep->_is_nil() ) continue;
3314 GEOM::ListOfLong_var vv = intStep->GetValues();
3315 if ( vv->length() != subIds.size() * comps->length() )
3316 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3317 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3318 for ( size_t iC = 0; iC < comps->length(); ++iC )
3319 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3322 case GEOM::FDT_Bool:
3324 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3325 if ( boolStep->_is_nil() ) continue;
3326 GEOM::short_array_var vv = boolStep->GetValues();
3327 if ( vv->length() != subIds.size() * comps->length() )
3328 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3329 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3330 for ( size_t iC = 0; iC < comps->length(); ++iC )
3331 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3337 // pass values to fieldWriter
3338 elemIt = fieldWriter.GetOrderedElems();
3339 if ( dataType == GEOM::FDT_Double )
3340 while ( elemIt->more() )
3342 const SMDS_MeshElement* e = elemIt->next();
3343 const int shapeID = e->getshapeId();
3344 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3345 for ( size_t iC = 0; iC < comps->length(); ++iC )
3346 fieldWriter.AddValue( noneDblValue );
3348 for ( size_t iC = 0; iC < comps->length(); ++iC )
3349 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3352 while ( elemIt->more() )
3354 const SMDS_MeshElement* e = elemIt->next();
3355 const int shapeID = e->getshapeId();
3356 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3357 for ( size_t iC = 0; iC < comps->length(); ++iC )
3358 fieldWriter.AddValue( (double) noneIntValue );
3360 for ( size_t iC = 0; iC < comps->length(); ++iC )
3361 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3365 fieldWriter.Perform();
3366 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3367 if ( res && res->IsKO() )
3369 if ( res->myComment.empty() )
3370 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3372 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3378 if ( !geomAssocFields || !geomAssocFields[0] )
3381 // write geomAssocFields
3383 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3384 shapeDim[ TopAbs_COMPOUND ] = 3;
3385 shapeDim[ TopAbs_COMPSOLID ] = 3;
3386 shapeDim[ TopAbs_SOLID ] = 3;
3387 shapeDim[ TopAbs_SHELL ] = 2;
3388 shapeDim[ TopAbs_FACE ] = 2;
3389 shapeDim[ TopAbs_WIRE ] = 1;
3390 shapeDim[ TopAbs_EDGE ] = 1;
3391 shapeDim[ TopAbs_VERTEX ] = 0;
3392 shapeDim[ TopAbs_SHAPE ] = 3;
3394 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3396 std::vector< std::string > compNames;
3397 switch ( geomAssocFields[ iF ]) {
3399 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3400 compNames.push_back( "dim" );
3403 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3406 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3409 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3413 compNames.push_back( "id" );
3414 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3415 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3417 fieldWriter.SetDtIt( -1, -1 );
3419 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3423 if ( compNames.size() == 2 ) // _vertices_
3424 while ( elemIt->more() )
3426 const SMDS_MeshElement* e = elemIt->next();
3427 const int shapeID = e->getshapeId();
3430 fieldWriter.AddValue( (double) -1 );
3431 fieldWriter.AddValue( (double) -1 );
3435 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3436 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3437 fieldWriter.AddValue( (double) shapeID );
3441 while ( elemIt->more() )
3443 const SMDS_MeshElement* e = elemIt->next();
3444 const int shapeID = e->getshapeId();
3446 fieldWriter.AddValue( (double) -1 );
3448 fieldWriter.AddValue( (double) shapeID );
3452 fieldWriter.Perform();
3453 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3454 if ( res && res->IsKO() )
3456 if ( res->myComment.empty() )
3457 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3459 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3462 } // loop on geomAssocFields
3467 //================================================================================
3469 * \brief Export a part of mesh to a DAT file
3471 //================================================================================
3473 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3475 throw (SALOME::SALOME_Exception)
3477 Unexpect aCatch(SALOME_SalomeException);
3479 _preMeshInfo->FullLoadFromFile();
3481 PrepareForWriting(file);
3483 SMESH_MeshPartDS partDS( meshPart );
3484 _impl->ExportDAT(file,&partDS);
3486 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3487 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3489 //================================================================================
3491 * \brief Export a part of mesh to an UNV file
3493 //================================================================================
3495 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3497 throw (SALOME::SALOME_Exception)
3499 Unexpect aCatch(SALOME_SalomeException);
3501 _preMeshInfo->FullLoadFromFile();
3503 PrepareForWriting(file);
3505 SMESH_MeshPartDS partDS( meshPart );
3506 _impl->ExportUNV(file, &partDS);
3508 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3509 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3511 //================================================================================
3513 * \brief Export a part of mesh to an STL file
3515 //================================================================================
3517 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3519 ::CORBA::Boolean isascii)
3520 throw (SALOME::SALOME_Exception)
3522 Unexpect aCatch(SALOME_SalomeException);
3524 _preMeshInfo->FullLoadFromFile();
3526 PrepareForWriting(file);
3528 CORBA::String_var name;
3529 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3530 if ( !so->_is_nil() )
3531 name = so->GetName();
3533 SMESH_MeshPartDS partDS( meshPart );
3534 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3536 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3537 << meshPart<< ", r'" << file << "', " << isascii << ")";
3540 //================================================================================
3542 * \brief Export a part of mesh to an STL file
3544 //================================================================================
3546 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3548 CORBA::Boolean overwrite,
3549 CORBA::Boolean groupElemsByType)
3550 throw (SALOME::SALOME_Exception)
3553 Unexpect aCatch(SALOME_SalomeException);
3555 _preMeshInfo->FullLoadFromFile();
3557 PrepareForWriting(file,overwrite);
3559 std::string meshName("");
3560 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3561 if ( !so->_is_nil() )
3563 CORBA::String_var name = so->GetName();
3564 meshName = name.in();
3568 SMESH_MeshPartDS partDS( meshPart );
3569 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3571 SMESH_CATCH( SMESH::throwCorbaException );
3573 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3574 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3576 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3580 //================================================================================
3582 * \brief Export a part of mesh to a GMF file
3584 //================================================================================
3586 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3588 bool withRequiredGroups)
3589 throw (SALOME::SALOME_Exception)
3591 Unexpect aCatch(SALOME_SalomeException);
3593 _preMeshInfo->FullLoadFromFile();
3595 PrepareForWriting(file,/*overwrite=*/true);
3597 SMESH_MeshPartDS partDS( meshPart );
3598 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3600 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3601 << meshPart<< ", r'"
3603 << withRequiredGroups << ")";
3606 //=============================================================================
3608 * Return computation progress [0.,1]
3610 //=============================================================================
3612 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3616 return _impl->GetComputeProgress();
3618 SMESH_CATCH( SMESH::doNothing );
3622 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3624 Unexpect aCatch(SALOME_SalomeException);
3626 return _preMeshInfo->NbNodes();
3628 return _impl->NbNodes();
3631 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3633 Unexpect aCatch(SALOME_SalomeException);
3635 return _preMeshInfo->NbElements();
3637 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3640 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3642 Unexpect aCatch(SALOME_SalomeException);
3644 return _preMeshInfo->Nb0DElements();
3646 return _impl->Nb0DElements();
3649 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3651 Unexpect aCatch(SALOME_SalomeException);
3653 return _preMeshInfo->NbBalls();
3655 return _impl->NbBalls();
3658 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3660 Unexpect aCatch(SALOME_SalomeException);
3662 return _preMeshInfo->NbEdges();
3664 return _impl->NbEdges();
3667 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3668 throw(SALOME::SALOME_Exception)
3670 Unexpect aCatch(SALOME_SalomeException);
3672 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3674 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3677 //=============================================================================
3679 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3681 Unexpect aCatch(SALOME_SalomeException);
3683 return _preMeshInfo->NbFaces();
3685 return _impl->NbFaces();
3688 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3690 Unexpect aCatch(SALOME_SalomeException);
3692 return _preMeshInfo->NbTriangles();
3694 return _impl->NbTriangles();
3697 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3699 Unexpect aCatch(SALOME_SalomeException);
3701 return _preMeshInfo->NbBiQuadTriangles();
3703 return _impl->NbBiQuadTriangles();
3706 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3708 Unexpect aCatch(SALOME_SalomeException);
3710 return _preMeshInfo->NbQuadrangles();
3712 return _impl->NbQuadrangles();
3715 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3717 Unexpect aCatch(SALOME_SalomeException);
3719 return _preMeshInfo->NbBiQuadQuadrangles();
3721 return _impl->NbBiQuadQuadrangles();
3724 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3726 Unexpect aCatch(SALOME_SalomeException);
3728 return _preMeshInfo->NbPolygons();
3730 return _impl->NbPolygons();
3733 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3735 Unexpect aCatch(SALOME_SalomeException);
3737 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3739 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3742 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3743 throw(SALOME::SALOME_Exception)
3745 Unexpect aCatch(SALOME_SalomeException);
3747 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3749 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3752 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3753 throw(SALOME::SALOME_Exception)
3755 Unexpect aCatch(SALOME_SalomeException);
3757 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3759 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3762 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3763 throw(SALOME::SALOME_Exception)
3765 Unexpect aCatch(SALOME_SalomeException);
3767 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3769 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3772 //=============================================================================
3774 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3776 Unexpect aCatch(SALOME_SalomeException);
3778 return _preMeshInfo->NbVolumes();
3780 return _impl->NbVolumes();
3783 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3785 Unexpect aCatch(SALOME_SalomeException);
3787 return _preMeshInfo->NbTetras();
3789 return _impl->NbTetras();
3792 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3794 Unexpect aCatch(SALOME_SalomeException);
3796 return _preMeshInfo->NbHexas();
3798 return _impl->NbHexas();
3801 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3803 Unexpect aCatch(SALOME_SalomeException);
3805 return _preMeshInfo->NbTriQuadHexas();
3807 return _impl->NbTriQuadraticHexas();
3810 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3812 Unexpect aCatch(SALOME_SalomeException);
3814 return _preMeshInfo->NbPyramids();
3816 return _impl->NbPyramids();
3819 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3821 Unexpect aCatch(SALOME_SalomeException);
3823 return _preMeshInfo->NbPrisms();
3825 return _impl->NbPrisms();
3828 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3830 Unexpect aCatch(SALOME_SalomeException);
3832 return _preMeshInfo->NbHexPrisms();
3834 return _impl->NbHexagonalPrisms();
3837 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3839 Unexpect aCatch(SALOME_SalomeException);
3841 return _preMeshInfo->NbPolyhedrons();
3843 return _impl->NbPolyhedrons();
3846 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3847 throw(SALOME::SALOME_Exception)
3849 Unexpect aCatch(SALOME_SalomeException);
3851 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3853 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3856 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3857 throw(SALOME::SALOME_Exception)
3859 Unexpect aCatch(SALOME_SalomeException);
3861 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3863 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3866 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3867 throw(SALOME::SALOME_Exception)
3869 Unexpect aCatch(SALOME_SalomeException);
3871 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3873 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3876 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3877 throw(SALOME::SALOME_Exception)
3879 Unexpect aCatch(SALOME_SalomeException);
3881 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3883 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3886 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3887 throw(SALOME::SALOME_Exception)
3889 Unexpect aCatch(SALOME_SalomeException);
3891 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3893 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3896 //=============================================================================
3898 * Returns nb of published sub-meshes
3900 //=============================================================================
3902 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3904 Unexpect aCatch(SALOME_SalomeException);
3905 return _mapSubMesh_i.size();
3908 //=============================================================================
3910 * Dumps mesh into a string
3912 //=============================================================================
3914 char* SMESH_Mesh_i::Dump()
3918 return CORBA::string_dup( os.str().c_str() );
3921 //=============================================================================
3923 * Method of SMESH_IDSource interface
3925 //=============================================================================
3927 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3929 return GetElementsId();
3932 //=============================================================================
3934 * Returns ids of all elements
3936 //=============================================================================
3938 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3939 throw (SALOME::SALOME_Exception)
3941 Unexpect aCatch(SALOME_SalomeException);
3943 _preMeshInfo->FullLoadFromFile();
3945 SMESH::long_array_var aResult = new SMESH::long_array();
3946 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3948 if ( aSMESHDS_Mesh == NULL )
3949 return aResult._retn();
3951 long nbElements = NbElements();
3952 aResult->length( nbElements );
3953 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3954 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3955 aResult[i] = anIt->next()->GetID();
3957 return aResult._retn();
3961 //=============================================================================
3963 * Returns ids of all elements of given type
3965 //=============================================================================
3967 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3968 throw (SALOME::SALOME_Exception)
3970 Unexpect aCatch(SALOME_SalomeException);
3972 _preMeshInfo->FullLoadFromFile();
3974 SMESH::long_array_var aResult = new SMESH::long_array();
3975 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3977 if ( aSMESHDS_Mesh == NULL )
3978 return aResult._retn();
3980 long nbElements = NbElements();
3982 // No sense in returning ids of elements along with ids of nodes:
3983 // when theElemType == SMESH::ALL, return node ids only if
3984 // there are no elements
3985 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3986 return GetNodesId();
3988 aResult->length( nbElements );
3992 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3993 while ( i < nbElements && anIt->more() )
3994 aResult[i++] = anIt->next()->GetID();
3996 aResult->length( i );
3998 return aResult._retn();
4001 //=============================================================================
4003 * Returns ids of all nodes
4005 //=============================================================================
4007 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4008 throw (SALOME::SALOME_Exception)
4010 Unexpect aCatch(SALOME_SalomeException);
4012 _preMeshInfo->FullLoadFromFile();
4014 SMESH::long_array_var aResult = new SMESH::long_array();
4015 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4017 if ( aSMESHDS_Mesh == NULL )
4018 return aResult._retn();
4020 long nbNodes = NbNodes();
4021 aResult->length( nbNodes );
4022 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4023 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4024 aResult[i] = anIt->next()->GetID();
4026 return aResult._retn();
4029 //=============================================================================
4033 //=============================================================================
4035 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4036 throw (SALOME::SALOME_Exception)
4038 SMESH::ElementType type = SMESH::ALL;
4042 _preMeshInfo->FullLoadFromFile();
4044 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4046 SMESH_CATCH( SMESH::throwCorbaException );
4051 //=============================================================================
4055 //=============================================================================
4057 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4058 throw (SALOME::SALOME_Exception)
4061 _preMeshInfo->FullLoadFromFile();
4063 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4065 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4067 return ( SMESH::EntityType ) e->GetEntityType();
4070 //=============================================================================
4074 //=============================================================================
4076 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4077 throw (SALOME::SALOME_Exception)
4080 _preMeshInfo->FullLoadFromFile();
4082 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4084 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4086 return ( SMESH::GeometryType ) e->GetGeomType();
4089 //=============================================================================
4091 * Returns ID of elements for given submesh
4093 //=============================================================================
4094 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4095 throw (SALOME::SALOME_Exception)
4097 SMESH::long_array_var aResult = new SMESH::long_array();
4101 _preMeshInfo->FullLoadFromFile();
4103 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4104 if(!SM) return aResult._retn();
4106 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4107 if(!SDSM) return aResult._retn();
4109 aResult->length(SDSM->NbElements());
4111 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4113 while ( eIt->more() ) {
4114 aResult[i++] = eIt->next()->GetID();
4117 SMESH_CATCH( SMESH::throwCorbaException );
4119 return aResult._retn();
4122 //=============================================================================
4124 * Returns ID of nodes for given submesh
4125 * If param all==true - returns all nodes, else -
4126 * returns only nodes on shapes.
4128 //=============================================================================
4130 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4132 throw (SALOME::SALOME_Exception)
4134 SMESH::long_array_var aResult = new SMESH::long_array();
4138 _preMeshInfo->FullLoadFromFile();
4140 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4141 if(!SM) return aResult._retn();
4143 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4144 if(!SDSM) return aResult._retn();
4147 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4148 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4149 while ( nIt->more() ) {
4150 const SMDS_MeshNode* elem = nIt->next();
4151 theElems.insert( elem->GetID() );
4154 else { // all nodes of submesh elements
4155 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4156 while ( eIt->more() ) {
4157 const SMDS_MeshElement* anElem = eIt->next();
4158 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4159 while ( nIt->more() ) {
4160 const SMDS_MeshElement* elem = nIt->next();
4161 theElems.insert( elem->GetID() );
4166 aResult->length(theElems.size());
4167 set<int>::iterator itElem;
4169 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4170 aResult[i++] = *itElem;
4172 SMESH_CATCH( SMESH::throwCorbaException );
4174 return aResult._retn();
4177 //=============================================================================
4179 * Returns type of elements for given submesh
4181 //=============================================================================
4183 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4184 throw (SALOME::SALOME_Exception)
4186 SMESH::ElementType type = SMESH::ALL;
4190 _preMeshInfo->FullLoadFromFile();
4192 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4193 if(!SM) return SMESH::ALL;
4195 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4196 if(!SDSM) return SMESH::ALL;
4198 if(SDSM->NbElements()==0)
4199 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4201 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4202 const SMDS_MeshElement* anElem = eIt->next();
4204 type = ( SMESH::ElementType ) anElem->GetType();
4206 SMESH_CATCH( SMESH::throwCorbaException );
4212 //=============================================================================
4214 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4216 //=============================================================================
4218 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4221 _preMeshInfo->FullLoadFromFile();
4223 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4224 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4229 //=============================================================================
4231 * Get XYZ coordinates of node as list of double
4232 * If there is not node for given ID - returns empty list
4234 //=============================================================================
4236 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4239 _preMeshInfo->FullLoadFromFile();
4241 SMESH::double_array_var aResult = new SMESH::double_array();
4242 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4243 if ( aSMESHDS_Mesh == NULL )
4244 return aResult._retn();
4247 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4249 return aResult._retn();
4253 aResult[0] = aNode->X();
4254 aResult[1] = aNode->Y();
4255 aResult[2] = aNode->Z();
4256 return aResult._retn();
4260 //=============================================================================
4262 * For given node returns list of IDs of inverse elements
4263 * If there is not node for given ID - returns empty list
4265 //=============================================================================
4267 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4270 _preMeshInfo->FullLoadFromFile();
4272 SMESH::long_array_var aResult = new SMESH::long_array();
4273 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4274 if ( aSMESHDS_Mesh == NULL )
4275 return aResult._retn();
4278 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4280 return aResult._retn();
4282 // find inverse elements
4283 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4284 aResult->length( aNode->NbInverseElements() );
4285 for( int i = 0; eIt->more(); ++i )
4287 const SMDS_MeshElement* elem = eIt->next();
4288 aResult[ i ] = elem->GetID();
4290 return aResult._retn();
4293 //=============================================================================
4295 * \brief Return position of a node on shape
4297 //=============================================================================
4299 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4302 _preMeshInfo->FullLoadFromFile();
4304 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4305 aNodePosition->shapeID = 0;
4306 aNodePosition->shapeType = GEOM::SHAPE;
4308 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4309 if ( !mesh ) return aNodePosition;
4311 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4313 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4315 aNodePosition->shapeID = aNode->getshapeId();
4316 switch ( pos->GetTypeOfPosition() ) {
4318 aNodePosition->shapeType = GEOM::EDGE;
4319 aNodePosition->params.length(1);
4320 aNodePosition->params[0] =
4321 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4324 aNodePosition->shapeType = GEOM::FACE;
4325 aNodePosition->params.length(2);
4326 aNodePosition->params[0] =
4327 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4328 aNodePosition->params[1] =
4329 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4331 case SMDS_TOP_VERTEX:
4332 aNodePosition->shapeType = GEOM::VERTEX;
4334 case SMDS_TOP_3DSPACE:
4335 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4336 aNodePosition->shapeType = GEOM::SOLID;
4337 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4338 aNodePosition->shapeType = GEOM::SHELL;
4344 return aNodePosition;
4347 //=============================================================================
4349 * \brief Return position of an element on shape
4351 //=============================================================================
4353 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4356 _preMeshInfo->FullLoadFromFile();
4358 SMESH::ElementPosition anElementPosition;
4359 anElementPosition.shapeID = 0;
4360 anElementPosition.shapeType = GEOM::SHAPE;
4362 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4363 if ( !mesh ) return anElementPosition;
4365 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4367 anElementPosition.shapeID = anElem->getshapeId();
4368 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4369 if ( !aSp.IsNull() ) {
4370 switch ( aSp.ShapeType() ) {
4372 anElementPosition.shapeType = GEOM::EDGE;
4375 anElementPosition.shapeType = GEOM::FACE;
4378 anElementPosition.shapeType = GEOM::VERTEX;
4381 anElementPosition.shapeType = GEOM::SOLID;
4384 anElementPosition.shapeType = GEOM::SHELL;
4390 return anElementPosition;
4393 //=============================================================================
4395 * If given element is node returns IDs of shape from position
4396 * If there is not node for given ID - returns -1
4398 //=============================================================================
4400 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4403 _preMeshInfo->FullLoadFromFile();
4405 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4406 if ( aSMESHDS_Mesh == NULL )
4410 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4412 return aNode->getshapeId();
4419 //=============================================================================
4421 * For given element returns ID of result shape after
4422 * ::FindShape() from SMESH_MeshEditor
4423 * If there is not element for given ID - returns -1
4425 //=============================================================================
4427 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4430 _preMeshInfo->FullLoadFromFile();
4432 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4433 if ( aSMESHDS_Mesh == NULL )
4436 // try to find element
4437 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4441 ::SMESH_MeshEditor aMeshEditor(_impl);
4442 int index = aMeshEditor.FindShape( elem );
4450 //=============================================================================
4452 * Returns number of nodes for given element
4453 * If there is not element for given ID - returns -1
4455 //=============================================================================
4457 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4460 _preMeshInfo->FullLoadFromFile();
4462 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4463 if ( aSMESHDS_Mesh == NULL ) return -1;
4464 // try to find element
4465 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4466 if(!elem) return -1;
4467 return elem->NbNodes();
4471 //=============================================================================
4473 * Returns ID of node by given index for given element
4474 * If there is not element for given ID - returns -1
4475 * If there is not node for given index - returns -2
4477 //=============================================================================
4479 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4482 _preMeshInfo->FullLoadFromFile();
4484 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4485 if ( aSMESHDS_Mesh == NULL ) return -1;
4486 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4487 if(!elem) return -1;
4488 if( index>=elem->NbNodes() || index<0 ) return -1;
4489 return elem->GetNode(index)->GetID();
4492 //=============================================================================
4494 * Returns IDs of nodes of given element
4496 //=============================================================================
4498 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4501 _preMeshInfo->FullLoadFromFile();
4503 SMESH::long_array_var aResult = new SMESH::long_array();
4504 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4506 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4508 aResult->length( elem->NbNodes() );
4509 for ( int i = 0; i < elem->NbNodes(); ++i )
4510 aResult[ i ] = elem->GetNode( i )->GetID();
4513 return aResult._retn();
4516 //=============================================================================
4518 * Returns true if given node is medium node
4519 * in given quadratic element
4521 //=============================================================================
4523 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4526 _preMeshInfo->FullLoadFromFile();
4528 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4529 if ( aSMESHDS_Mesh == NULL ) return false;
4531 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4532 if(!aNode) return false;
4533 // try to find element
4534 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4535 if(!elem) return false;
4537 return elem->IsMediumNode(aNode);
4541 //=============================================================================
4543 * Returns true if given node is medium node
4544 * in one of quadratic elements
4546 //=============================================================================
4548 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4549 SMESH::ElementType theElemType)
4552 _preMeshInfo->FullLoadFromFile();
4554 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4555 if ( aSMESHDS_Mesh == NULL ) return false;
4558 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4559 if(!aNode) return false;
4561 SMESH_MesherHelper aHelper( *(_impl) );
4563 SMDSAbs_ElementType aType;
4564 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4565 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4566 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4567 else aType = SMDSAbs_All;
4569 return aHelper.IsMedium(aNode,aType);
4573 //=============================================================================
4575 * Returns number of edges for given element
4577 //=============================================================================
4579 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4582 _preMeshInfo->FullLoadFromFile();
4584 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4585 if ( aSMESHDS_Mesh == NULL ) return -1;
4586 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4587 if(!elem) return -1;
4588 return elem->NbEdges();
4592 //=============================================================================
4594 * Returns number of faces for given element
4596 //=============================================================================
4598 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4601 _preMeshInfo->FullLoadFromFile();
4603 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4604 if ( aSMESHDS_Mesh == NULL ) return -1;
4605 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4606 if(!elem) return -1;
4607 return elem->NbFaces();
4610 //=======================================================================
4611 //function : GetElemFaceNodes
4612 //purpose : Returns nodes of given face (counted from zero) for given element.
4613 //=======================================================================
4615 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4616 CORBA::Short faceIndex)
4619 _preMeshInfo->FullLoadFromFile();
4621 SMESH::long_array_var aResult = new SMESH::long_array();
4622 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4624 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4626 SMDS_VolumeTool vtool( elem );
4627 if ( faceIndex < vtool.NbFaces() )
4629 aResult->length( vtool.NbFaceNodes( faceIndex ));
4630 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4631 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4632 aResult[ i ] = nn[ i ]->GetID();
4636 return aResult._retn();
4639 //=======================================================================
4640 //function : GetElemFaceNodes
4641 //purpose : Returns three components of normal of given mesh face.
4642 //=======================================================================
4644 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4645 CORBA::Boolean normalized)
4648 _preMeshInfo->FullLoadFromFile();
4650 SMESH::double_array_var aResult = new SMESH::double_array();
4652 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4655 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4657 aResult->length( 3 );
4658 aResult[ 0 ] = normal.X();
4659 aResult[ 1 ] = normal.Y();
4660 aResult[ 2 ] = normal.Z();
4663 return aResult._retn();
4666 //=======================================================================
4667 //function : FindElementByNodes
4668 //purpose : Returns an element based on all given nodes.
4669 //=======================================================================
4671 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4674 _preMeshInfo->FullLoadFromFile();
4676 CORBA::Long elemID(0);
4677 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4679 vector< const SMDS_MeshNode * > nn( nodes.length() );
4680 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4681 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4684 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4685 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4686 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4687 _impl->NbVolumes( ORDER_QUADRATIC )))
4688 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4690 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4695 //================================================================================
4697 * \brief Return elements including all given nodes.
4699 //================================================================================
4701 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4702 SMESH::ElementType elemType)
4705 _preMeshInfo->FullLoadFromFile();
4707 SMESH::long_array_var result = new SMESH::long_array();
4709 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4711 vector< const SMDS_MeshNode * > nn( nodes.length() );
4712 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4713 nn[i] = mesh->FindNode( nodes[i] );
4715 std::vector<const SMDS_MeshElement *> elems;
4716 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4717 result->length( elems.size() );
4718 for ( size_t i = 0; i < elems.size(); ++i )
4719 result[i] = elems[i]->GetID();
4721 return result._retn();
4724 //=============================================================================
4726 * Returns true if given element is polygon
4728 //=============================================================================
4730 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4733 _preMeshInfo->FullLoadFromFile();
4735 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4736 if ( aSMESHDS_Mesh == NULL ) return false;
4737 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4738 if(!elem) return false;
4739 return elem->IsPoly();
4743 //=============================================================================
4745 * Returns true if given element is quadratic
4747 //=============================================================================
4749 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4752 _preMeshInfo->FullLoadFromFile();
4754 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4755 if ( aSMESHDS_Mesh == NULL ) return false;
4756 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4757 if(!elem) return false;
4758 return elem->IsQuadratic();
4761 //=============================================================================
4763 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4765 //=============================================================================
4767 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4770 _preMeshInfo->FullLoadFromFile();
4772 if ( const SMDS_BallElement* ball =
4773 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4774 return ball->GetDiameter();
4779 //=============================================================================
4781 * Returns bary center for given element
4783 //=============================================================================
4785 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4788 _preMeshInfo->FullLoadFromFile();
4790 SMESH::double_array_var aResult = new SMESH::double_array();
4791 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4792 if ( aSMESHDS_Mesh == NULL )
4793 return aResult._retn();
4795 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4797 return aResult._retn();
4799 if(elem->GetType()==SMDSAbs_Volume) {
4800 SMDS_VolumeTool aTool;
4801 if(aTool.Set(elem)) {
4803 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4808 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4810 double x=0., y=0., z=0.;
4811 for(; anIt->more(); ) {
4813 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4827 return aResult._retn();
4830 //================================================================================
4832 * \brief Create a group of elements preventing computation of a sub-shape
4834 //================================================================================
4836 SMESH::ListOfGroups*
4837 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4838 const char* theGroupName )
4839 throw ( SALOME::SALOME_Exception )
4841 Unexpect aCatch(SALOME_SalomeException);
4843 if ( !theGroupName || strlen( theGroupName) == 0 )
4844 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4846 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4847 ::SMESH_MeshEditor::ElemFeatures elemType;
4849 // submesh by subshape id
4850 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4851 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4854 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4855 if ( error && !error->myBadElements.empty())
4857 // sort bad elements by type
4858 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4859 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4860 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4861 for ( ; elemIt != elemEnd; ++elemIt )
4863 const SMDS_MeshElement* elem = *elemIt;
4864 if ( !elem ) continue;
4866 if ( elem->GetID() < 1 )
4868 // elem is a temporary element, make a real element
4869 vector< const SMDS_MeshNode* > nodes;
4870 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4871 while ( nIt->more() && elem )
4873 nodes.push_back( nIt->next() );
4874 if ( nodes.back()->GetID() < 1 )
4875 elem = 0; // a temporary element on temporary nodes
4879 ::SMESH_MeshEditor editor( _impl );
4880 elem = editor.AddElement( nodes, elemType.Init( elem ));
4884 elemsByType[ elem->GetType() ].push_back( elem );
4887 // how many groups to create?
4889 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4890 nbTypes += int( !elemsByType[ i ].empty() );
4891 groups->length( nbTypes );
4894 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4896 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4897 if ( elems.empty() ) continue;
4899 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4900 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4902 SMESH::SMESH_Mesh_var mesh = _this();
4903 SALOMEDS::SObject_wrap aSO =
4904 _gen_i->PublishGroup( mesh, groups[ iG ],
4905 GEOM::GEOM_Object::_nil(), theGroupName);
4907 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4908 if ( !grp_i ) continue;
4910 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4911 for ( size_t iE = 0; iE < elems.size(); ++iE )
4912 grpDS->SMDSGroup().Add( elems[ iE ]);
4917 return groups._retn();
4920 //=============================================================================
4922 * Create and publish group servants if any groups were imported or created anyhow
4924 //=============================================================================
4926 void SMESH_Mesh_i::CreateGroupServants()
4928 SMESH::SMESH_Mesh_var aMesh = _this();
4931 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4932 while ( groupIt->more() )
4934 ::SMESH_Group* group = groupIt->next();
4935 int anId = group->GetGroupDS()->GetID();
4937 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4938 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4940 addedIDs.insert( anId );
4942 SMESH_GroupBase_i* aGroupImpl;
4944 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4945 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4947 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4948 shape = groupOnGeom->GetShape();
4951 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4954 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4955 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4956 aGroupImpl->Register();
4958 // register CORBA object for persistence
4959 int nextId = _gen_i->RegisterObject( groupVar );
4960 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4961 else { nextId = 0; } // avoid "unused variable" warning in release mode
4963 // publishing the groups in the study
4964 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4965 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
4967 if ( !addedIDs.empty() )
4970 set<int>::iterator id = addedIDs.begin();
4971 for ( ; id != addedIDs.end(); ++id )
4973 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4974 int i = std::distance( _mapGroups.begin(), it );
4975 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4980 //=============================================================================
4982 * \brief Return groups cantained in _mapGroups by their IDs
4984 //=============================================================================
4986 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4988 int nbGroups = groupIDs.size();
4989 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4990 aList->length( nbGroups );
4992 list<int>::const_iterator ids = groupIDs.begin();
4993 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4995 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4996 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4997 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4999 aList->length( nbGroups );
5000 return aList._retn();
5003 //=============================================================================
5005 * \brief Return information about imported file
5007 //=============================================================================
5009 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5011 SMESH::MedFileInfo_var res( _medFileInfo );
5012 if ( !res.operator->() ) {
5013 res = new SMESH::MedFileInfo;
5015 res->fileSize = res->major = res->minor = res->release = -1;
5020 //=============================================================================
5022 * \brief Pass names of mesh groups from study to mesh DS
5024 //=============================================================================
5026 void SMESH_Mesh_i::checkGroupNames()
5028 int nbGrp = NbGroups();
5032 SMESH::ListOfGroups* grpList = 0;
5033 // avoid dump of "GetGroups"
5035 // store python dump into a local variable inside local scope
5036 SMESH::TPythonDump pDump; // do not delete this line of code
5037 grpList = GetGroups();
5040 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5041 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5044 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5045 if ( aGrpSO->_is_nil() )
5047 // correct name of the mesh group if necessary
5048 const char* guiName = aGrpSO->GetName();
5049 if ( strcmp(guiName, aGrp->GetName()) )
5050 aGrp->SetName( guiName );
5054 //=============================================================================
5056 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5058 //=============================================================================
5059 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5061 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5065 //=============================================================================
5067 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5069 //=============================================================================
5071 char* SMESH_Mesh_i::GetParameters()
5073 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5076 //=============================================================================
5078 * \brief Returns list of notebook variables used for last Mesh operation
5080 //=============================================================================
5081 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5083 SMESH::string_array_var aResult = new SMESH::string_array();
5084 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5086 CORBA::String_var aParameters = GetParameters();
5087 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5088 if ( aSections->length() > 0 ) {
5089 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5090 aResult->length( aVars.length() );
5091 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5092 aResult[i] = CORBA::string_dup( aVars[i] );
5095 return aResult._retn();
5098 //=======================================================================
5099 //function : GetTypes
5100 //purpose : Returns types of elements it contains
5101 //=======================================================================
5103 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5106 return _preMeshInfo->GetTypes();
5108 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5112 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5113 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5114 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5115 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5116 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5117 if (_impl->NbNodes() &&
5118 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5119 types->length( nbTypes );
5121 return types._retn();
5124 //=======================================================================
5125 //function : GetMesh
5126 //purpose : Returns self
5127 //=======================================================================
5129 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5131 return SMESH::SMESH_Mesh::_duplicate( _this() );
5134 //=======================================================================
5135 //function : IsMeshInfoCorrect
5136 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5137 // * happen if mesh data is not yet fully loaded from the file of study.
5138 //=======================================================================
5140 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5142 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5145 //=============================================================================
5147 * \brief Returns number of mesh elements per each \a EntityType
5149 //=============================================================================
5151 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5154 return _preMeshInfo->GetMeshInfo();
5156 SMESH::long_array_var aRes = new SMESH::long_array();
5157 aRes->length(SMESH::Entity_Last);
5158 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5160 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5162 return aRes._retn();
5163 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5164 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5165 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5166 return aRes._retn();
5169 //=============================================================================
5171 * \brief Returns number of mesh elements per each \a ElementType
5173 //=============================================================================
5175 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5177 SMESH::long_array_var aRes = new SMESH::long_array();
5178 aRes->length(SMESH::NB_ELEMENT_TYPES);
5179 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5182 const SMDS_MeshInfo* meshInfo = 0;
5184 meshInfo = _preMeshInfo;
5185 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5186 meshInfo = & meshDS->GetMeshInfo();
5189 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5190 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5192 return aRes._retn();
5195 //=============================================================================
5197 * Collect statistic of mesh elements given by iterator
5199 //=============================================================================
5201 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5202 SMESH::long_array& theInfo)
5204 if (!theItr) return;
5205 while (theItr->more())
5206 theInfo[ theItr->next()->GetEntityType() ]++;
5208 //=============================================================================
5210 * Returns mesh unstructed grid information.
5212 //=============================================================================
5214 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5216 SALOMEDS::TMPFile_var SeqFile;
5217 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5218 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5220 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5221 aWriter->WriteToOutputStringOn();
5222 aWriter->SetInputData(aGrid);
5223 aWriter->SetFileTypeToBinary();
5225 char* str = aWriter->GetOutputString();
5226 int size = aWriter->GetOutputStringLength();
5228 //Allocate octect buffer of required size
5229 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5230 //Copy ostrstream content to the octect buffer
5231 memcpy(OctetBuf, str, size);
5232 //Create and return TMPFile
5233 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5237 return SeqFile._retn();
5240 //=============================================================================
5241 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5242 * SMESH::ElementType type) */
5244 using namespace SMESH::Controls;
5245 //-----------------------------------------------------------------------------
5246 struct PredicateIterator : public SMDS_ElemIterator
5248 SMDS_ElemIteratorPtr _elemIter;
5249 PredicatePtr _predicate;
5250 const SMDS_MeshElement* _elem;
5252 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5253 PredicatePtr predicate):
5254 _elemIter(iterator), _predicate(predicate)
5262 virtual const SMDS_MeshElement* next()
5264 const SMDS_MeshElement* res = _elem;
5266 while ( _elemIter->more() && !_elem )
5268 _elem = _elemIter->next();
5269 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5276 //-----------------------------------------------------------------------------
5277 struct IDSourceIterator : public SMDS_ElemIterator
5279 const CORBA::Long* _idPtr;
5280 const CORBA::Long* _idEndPtr;
5281 SMESH::long_array_var _idArray;
5282 const SMDS_Mesh* _mesh;
5283 const SMDSAbs_ElementType _type;
5284 const SMDS_MeshElement* _elem;
5286 IDSourceIterator( const SMDS_Mesh* mesh,
5287 const CORBA::Long* ids,
5289 SMDSAbs_ElementType type):
5290 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5292 if ( _idPtr && nbIds && _mesh )
5295 IDSourceIterator( const SMDS_Mesh* mesh,
5296 SMESH::long_array* idArray,
5297 SMDSAbs_ElementType type):
5298 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5300 if ( idArray && _mesh )
5302 _idPtr = &_idArray[0];
5303 _idEndPtr = _idPtr + _idArray->length();
5311 virtual const SMDS_MeshElement* next()
5313 const SMDS_MeshElement* res = _elem;
5315 while ( _idPtr < _idEndPtr && !_elem )
5317 if ( _type == SMDSAbs_Node )
5319 _elem = _mesh->FindNode( *_idPtr++ );
5321 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5322 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5330 //-----------------------------------------------------------------------------
5332 struct NodeOfElemIterator : public SMDS_ElemIterator
5334 TColStd_MapOfInteger _checkedNodeIDs;
5335 SMDS_ElemIteratorPtr _elemIter;
5336 SMDS_ElemIteratorPtr _nodeIter;
5337 const SMDS_MeshElement* _node;
5339 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5341 if ( _elemIter && _elemIter->more() )
5343 _nodeIter = _elemIter->next()->nodesIterator();
5351 virtual const SMDS_MeshElement* next()
5353 const SMDS_MeshElement* res = _node;
5355 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5357 if ( _nodeIter->more() )
5359 _node = _nodeIter->next();
5360 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5365 _nodeIter = _elemIter->next()->nodesIterator();
5373 //=============================================================================
5375 * Return iterator on elements of given type in given object
5377 //=============================================================================
5379 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5380 SMESH::ElementType theType)
5382 SMDS_ElemIteratorPtr elemIt;
5383 bool typeOK = ( theType == SMESH::ALL );
5384 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5386 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5387 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5388 if ( !mesh_i ) return elemIt;
5389 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5391 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5393 elemIt = meshDS->elementsIterator( elemType );
5396 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5398 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5401 elemIt = sm->GetElements();
5402 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5404 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5405 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5409 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5411 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5412 if ( groupDS && ( elemType == groupDS->GetType() ||
5413 elemType == SMDSAbs_Node ||
5414 elemType == SMDSAbs_All ))
5416 elemIt = groupDS->GetElements();
5417 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5420 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5422 if ( filter_i->GetElementType() == theType ||
5423 elemType == SMDSAbs_Node ||
5424 elemType == SMDSAbs_All)
5426 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5427 if ( pred_i && pred_i->GetPredicate() )
5429 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5430 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5431 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5432 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5438 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5439 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5440 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5442 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5445 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5446 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5450 SMESH::long_array_var ids = theObject->GetIDs();
5451 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5453 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5456 if ( elemIt && elemIt->more() && !typeOK )
5458 if ( elemType == SMDSAbs_Node )
5460 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5464 elemIt = SMDS_ElemIteratorPtr();
5470 //=============================================================================
5471 namespace // Finding concurrent hypotheses
5472 //=============================================================================
5476 * \brief mapping of mesh dimension into shape type
5478 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5480 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5482 case 0: aType = TopAbs_VERTEX; break;
5483 case 1: aType = TopAbs_EDGE; break;
5484 case 2: aType = TopAbs_FACE; break;
5486 default:aType = TopAbs_SOLID; break;
5491 //-----------------------------------------------------------------------------
5493 * \brief Internal structure used to find concurent submeshes
5495 * It represents a pair < submesh, concurent dimension >, where
5496 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5497 * with another submesh. In other words, it is dimension of a hypothesis assigned
5504 int _dim; //!< a dimension the algo can build (concurrent dimension)
5505 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5506 TopTools_MapOfShape _shapeMap;
5507 SMESH_subMesh* _subMesh;
5508 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5510 //-----------------------------------------------------------------------------
5511 // Return the algorithm
5512 const SMESH_Algo* GetAlgo() const
5513 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5515 //-----------------------------------------------------------------------------
5517 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5519 const TopoDS_Shape& theShape)
5521 _subMesh = (SMESH_subMesh*)theSubMesh;
5522 SetShape( theDim, theShape );
5525 //-----------------------------------------------------------------------------
5527 void SetShape(const int theDim,
5528 const TopoDS_Shape& theShape)
5531 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5532 if (_dim >= _ownDim)
5533 _shapeMap.Add( theShape );
5535 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5536 for( ; anExp.More(); anExp.Next() )
5537 _shapeMap.Add( anExp.Current() );
5541 //-----------------------------------------------------------------------------
5542 //! Check sharing of sub-shapes
5543 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5544 const TopTools_MapOfShape& theToFind,
5545 const TopAbs_ShapeEnum theType)
5547 bool isShared = false;
5548 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5549 for (; !isShared && anItr.More(); anItr.Next() )
5551 const TopoDS_Shape aSubSh = anItr.Key();
5552 // check for case when concurrent dimensions are same
5553 isShared = theToFind.Contains( aSubSh );
5554 // check for sub-shape with concurrent dimension
5555 TopExp_Explorer anExp( aSubSh, theType );
5556 for ( ; !isShared && anExp.More(); anExp.Next() )
5557 isShared = theToFind.Contains( anExp.Current() );
5562 //-----------------------------------------------------------------------------
5563 //! check algorithms
5564 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5565 const SMESHDS_Hypothesis* theA2)
5567 if ( !theA1 || !theA2 ||
5568 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5569 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5570 return false; // one of the hypothesis is not algorithm
5571 // check algorithm names (should be equal)
5572 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5576 //-----------------------------------------------------------------------------
5577 //! Check if sub-shape hypotheses are concurrent
5578 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5580 if ( _subMesh == theOther->_subMesh )
5581 return false; // same sub-shape - should not be
5583 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5584 // any of the two submeshes is not on COMPOUND shape )
5585 // -> no concurrency
5586 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5587 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5588 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5589 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5590 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5593 // bool checkSubShape = ( _dim >= theOther->_dim )
5594 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5595 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5596 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5597 if ( !checkSubShape )
5600 // check algorithms to be same
5601 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5602 return true; // different algorithms -> concurrency !
5604 // check hypothesises for concurrence (skip first as algorithm)
5606 // pointers should be same, because it is referened from mesh hypothesis partition
5607 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5608 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5609 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5610 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5612 // the submeshes are concurrent if their algorithms has different parameters
5613 return nbSame != (int)theOther->_hypotheses.size() - 1;
5616 // Return true if algorithm of this SMESH_DimHyp is used if no
5617 // sub-mesh order is imposed by the user
5618 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5620 // NeedDiscreteBoundary() algo has a higher priority
5621 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5622 theOther->GetAlgo()->NeedDiscreteBoundary() )
5623 return !this->GetAlgo()->NeedDiscreteBoundary();
5625 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5628 }; // end of SMESH_DimHyp
5629 //-----------------------------------------------------------------------------
5631 typedef list<const SMESH_DimHyp*> TDimHypList;
5633 //-----------------------------------------------------------------------------
5635 void addDimHypInstance(const int theDim,
5636 const TopoDS_Shape& theShape,
5637 const SMESH_Algo* theAlgo,
5638 const SMESH_subMesh* theSubMesh,
5639 const list <const SMESHDS_Hypothesis*>& theHypList,
5640 TDimHypList* theDimHypListArr )
5642 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5643 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5644 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5645 dimHyp->_hypotheses.push_front(theAlgo);
5646 listOfdimHyp.push_back( dimHyp );
5649 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5650 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5651 theHypList.begin(), theHypList.end() );
5654 //-----------------------------------------------------------------------------
5655 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5656 TDimHypList& theListOfConcurr)
5658 if ( theListOfConcurr.empty() )
5660 theListOfConcurr.push_back( theDimHyp );
5664 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5665 while ( hypIt != theListOfConcurr.end() &&
5666 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5668 theListOfConcurr.insert( hypIt, theDimHyp );
5672 //-----------------------------------------------------------------------------
5673 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5674 const TDimHypList& theListOfDimHyp,
5675 TDimHypList& theListOfConcurrHyp,
5676 set<int>& theSetOfConcurrId )
5678 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5679 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5681 const SMESH_DimHyp* curDimHyp = *rIt;
5682 if ( curDimHyp == theDimHyp )
5683 break; // meet own dimHyp pointer in same dimension
5685 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5686 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5688 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5693 //-----------------------------------------------------------------------------
5694 void unionLists(TListOfInt& theListOfId,
5695 TListOfListOfInt& theListOfListOfId,
5698 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5699 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5701 continue; //skip already treated lists
5702 // check if other list has any same submesh object
5703 TListOfInt& otherListOfId = *it;
5704 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5705 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5708 // union two lists (from source into target)
5709 TListOfInt::iterator it2 = otherListOfId.begin();
5710 for ( ; it2 != otherListOfId.end(); it2++ ) {
5711 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5712 theListOfId.push_back(*it2);
5714 // clear source list
5715 otherListOfId.clear();
5718 //-----------------------------------------------------------------------------
5720 //! free memory allocated for dimension-hypothesis objects
5721 void removeDimHyps( TDimHypList* theArrOfList )
5723 for (int i = 0; i < 4; i++ ) {
5724 TDimHypList& listOfdimHyp = theArrOfList[i];
5725 TDimHypList::const_iterator it = listOfdimHyp.begin();
5726 for ( ; it != listOfdimHyp.end(); it++ )
5731 //-----------------------------------------------------------------------------
5733 * \brief find common submeshes with given submesh
5734 * \param theSubMeshList list of already collected submesh to check
5735 * \param theSubMesh given submesh to intersect with other
5736 * \param theCommonSubMeshes collected common submeshes
5738 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5739 const SMESH_subMesh* theSubMesh,
5740 set<const SMESH_subMesh*>& theCommon )
5744 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5745 for ( ; it != theSubMeshList.end(); it++ )
5746 theSubMesh->FindIntersection( *it, theCommon );
5747 theSubMeshList.push_back( theSubMesh );
5748 //theCommon.insert( theSubMesh );
5751 //-----------------------------------------------------------------------------
5752 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5754 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5755 for ( ; listsIt != smLists.end(); ++listsIt )
5757 const TListOfInt& smIDs = *listsIt;
5758 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5766 //=============================================================================
5768 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5770 //=============================================================================
5772 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5774 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5775 if ( isSubMeshInList( submeshID, anOrder ))
5778 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5779 return isSubMeshInList( submeshID, allConurrent );
5782 //=============================================================================
5784 * \brief Return submesh objects list in meshing order
5786 //=============================================================================
5788 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5790 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5792 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5794 return aResult._retn();
5796 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5797 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5798 anOrder.splice( anOrder.end(), allConurrent );
5801 TListOfListOfInt::iterator listIt = anOrder.begin();
5802 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5803 unionLists( *listIt, anOrder, listIndx + 1 );
5805 // convert submesh ids into interface instances
5806 // and dump command into python
5807 convertMeshOrder( anOrder, aResult, false );
5809 return aResult._retn();
5812 //=============================================================================
5814 * \brief Finds concurrent sub-meshes
5816 //=============================================================================
5818 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5820 TListOfListOfInt anOrder;
5821 ::SMESH_Mesh& mesh = GetImpl();
5823 // collect submeshes and detect concurrent algorithms and hypothesises
5824 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5826 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5827 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5828 ::SMESH_subMesh* sm = (*i_sm).second;
5830 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5832 // list of assigned hypothesises
5833 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5834 // Find out dimensions where the submesh can be concurrent.
5835 // We define the dimensions by algo of each of hypotheses in hypList
5836 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5837 for( ; hypIt != hypList.end(); hypIt++ ) {
5838 SMESH_Algo* anAlgo = 0;
5839 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5840 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5841 // hyp it-self is algo
5842 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5844 // try to find algorithm with help of sub-shapes
5845 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5846 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5847 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5850 continue; // no algorithm assigned to a current submesh
5852 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5853 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5855 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5856 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5857 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5859 } // end iterations on submesh
5861 // iterate on created dimension-hypotheses and check for concurrents
5862 for ( int i = 0; i < 4; i++ ) {
5863 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5864 // check for concurrents in own and other dimensions (step-by-step)
5865 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5866 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5867 const SMESH_DimHyp* dimHyp = *dhIt;
5868 TDimHypList listOfConcurr;
5869 set<int> setOfConcurrIds;
5870 // looking for concurrents and collect into own list
5871 for ( int j = i; j < 4; j++ )
5872 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5873 // check if any concurrents found
5874 if ( listOfConcurr.size() > 0 ) {
5875 // add own submesh to list of concurrent
5876 addInOrderOfPriority( dimHyp, listOfConcurr );
5877 list<int> listOfConcurrIds;
5878 TDimHypList::iterator hypIt = listOfConcurr.begin();
5879 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5880 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5881 anOrder.push_back( listOfConcurrIds );
5886 removeDimHyps(dimHypListArr);
5888 // now, minimise the number of concurrent groups
5889 // Here we assume that lists of submeshes can have same submesh
5890 // in case of multi-dimension algorithms, as result
5891 // list with common submesh has to be united into one list
5893 TListOfListOfInt::iterator listIt = anOrder.begin();
5894 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5895 unionLists( *listIt, anOrder, listIndx + 1 );
5901 //=============================================================================
5903 * \brief Set submesh object order
5904 * \param theSubMeshArray submesh array order
5906 //=============================================================================
5908 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5911 _preMeshInfo->ForgetOrLoad();
5914 ::SMESH_Mesh& mesh = GetImpl();
5916 TPythonDump aPythonDump; // prevent dump of called methods
5917 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5919 TListOfListOfInt subMeshOrder;
5920 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5922 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5923 TListOfInt subMeshIds;
5925 aPythonDump << ", ";
5926 aPythonDump << "[ ";
5927 // Collect subMeshes which should be clear
5928 // do it list-by-list, because modification of submesh order
5929 // take effect between concurrent submeshes only
5930 set<const SMESH_subMesh*> subMeshToClear;
5931 list<const SMESH_subMesh*> subMeshList;
5932 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5934 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5936 aPythonDump << ", ";
5937 aPythonDump << subMesh;
5938 subMeshIds.push_back( subMesh->GetId() );
5939 // detect common parts of submeshes
5940 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5941 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5943 aPythonDump << " ]";
5944 subMeshOrder.push_back( subMeshIds );
5946 // clear collected submeshes
5947 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5948 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5949 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5950 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5952 aPythonDump << " ])";
5954 mesh.SetMeshOrder( subMeshOrder );
5960 //=============================================================================
5962 * \brief Convert submesh ids into submesh interfaces
5964 //=============================================================================
5966 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5967 SMESH::submesh_array_array& theResOrder,
5968 const bool theIsDump)
5970 int nbSet = theIdsOrder.size();
5971 TPythonDump aPythonDump; // prevent dump of called methods
5973 aPythonDump << "[ ";
5974 theResOrder.length(nbSet);
5975 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5977 for( ; it != theIdsOrder.end(); it++ ) {
5978 // translate submesh identificators into submesh objects
5979 // takeing into account real number of concurrent lists
5980 const TListOfInt& aSubOrder = (*it);
5981 if (!aSubOrder.size())
5984 aPythonDump << "[ ";
5985 // convert shape indeces into interfaces
5986 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5987 aResSubSet->length(aSubOrder.size());
5988 TListOfInt::const_iterator subIt = aSubOrder.begin();
5990 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5991 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5993 SMESH::SMESH_subMesh_var subMesh =
5994 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5997 aPythonDump << ", ";
5998 aPythonDump << subMesh;
6000 aResSubSet[ j++ ] = subMesh;
6003 aPythonDump << " ]";
6005 theResOrder[ listIndx++ ] = aResSubSet;
6007 // correct number of lists
6008 theResOrder.length( listIndx );
6011 // finilise python dump
6012 aPythonDump << " ]";
6013 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6017 //================================================================================
6019 // Implementation of SMESH_MeshPartDS
6021 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6022 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6024 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6025 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6028 _meshDS = mesh_i->GetImpl().GetMeshDS();
6030 SetPersistentId( _meshDS->GetPersistentId() );
6032 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6034 // <meshPart> is the whole mesh
6035 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6037 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6038 myGroupSet = _meshDS->GetGroups();
6043 SMESH::long_array_var anIDs = meshPart->GetIDs();
6044 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6045 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6047 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6048 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6049 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6054 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6055 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6056 if ( _elements[ e->GetType() ].insert( e ).second )
6059 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6060 while ( nIt->more() )
6062 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6063 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6070 ShapeToMesh( _meshDS->ShapeToMesh() );
6072 _meshDS = 0; // to enforce iteration on _elements and _nodes
6075 // -------------------------------------------------------------------------------------
6076 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6077 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6080 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6081 for ( ; partIt != meshPart.end(); ++partIt )
6082 if ( const SMDS_MeshElement * e = *partIt )
6083 if ( _elements[ e->GetType() ].insert( e ).second )
6086 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6087 while ( nIt->more() )
6089 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6090 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6096 // -------------------------------------------------------------------------------------
6097 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6099 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6101 TElemID elem( IDelem );
6102 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6103 if ( !_elements[ iType ].empty() )
6105 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6106 if ( it != _elements[ iType ].end() )
6111 // -------------------------------------------------------------------------------------
6112 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6114 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6116 typedef SMDS_SetIterator
6117 <const SMDS_MeshElement*,
6118 TIDSortedElemSet::const_iterator,
6119 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6120 SMDS_MeshElement::GeomFilter
6123 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6125 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6126 _elements[type].end(),
6127 SMDS_MeshElement::GeomFilter( geomType )));
6129 // -------------------------------------------------------------------------------------
6130 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6132 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6134 typedef SMDS_SetIterator
6135 <const SMDS_MeshElement*,
6136 TIDSortedElemSet::const_iterator,
6137 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6138 SMDS_MeshElement::EntityFilter
6141 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6143 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6144 _elements[type].end(),
6145 SMDS_MeshElement::EntityFilter( entity )));
6147 // -------------------------------------------------------------------------------------
6148 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6150 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6151 if ( type == SMDSAbs_All && !_meshDS )
6153 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6155 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6156 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6158 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6160 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6161 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6163 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6164 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6166 // -------------------------------------------------------------------------------------
6167 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6168 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6170 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6171 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6172 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6174 // -------------------------------------------------------------------------------------
6175 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6176 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6177 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6178 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6179 #undef _GET_ITER_DEFINE
6181 // END Implementation of SMESH_MeshPartDS
6183 //================================================================================