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)
2975 _preMeshInfo->FullLoadFromFile();
2977 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2978 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, 0, autoDimension );
2980 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
2981 << file << "', " << auto_groups << ", "
2982 << overwrite << ", "
2983 << autoDimension << " )";
2985 SMESH_CATCH( SMESH::throwCorbaException );
2988 //================================================================================
2990 * \brief Export a mesh to a SAUV file
2992 //================================================================================
2994 void SMESH_Mesh_i::ExportSAUV (const char* file,
2995 CORBA::Boolean auto_groups)
2996 throw(SALOME::SALOME_Exception)
2998 Unexpect aCatch(SALOME_SalomeException);
3000 _preMeshInfo->FullLoadFromFile();
3002 string aMeshName = prepareMeshNameAndGroups(file, true);
3003 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3004 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3005 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3009 //================================================================================
3011 * \brief Export a mesh to a DAT file
3013 //================================================================================
3015 void SMESH_Mesh_i::ExportDAT (const char *file)
3016 throw(SALOME::SALOME_Exception)
3018 Unexpect aCatch(SALOME_SalomeException);
3020 _preMeshInfo->FullLoadFromFile();
3022 // Update Python script
3023 // check names of groups
3025 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3028 PrepareForWriting(file);
3029 _impl->ExportDAT(file);
3032 //================================================================================
3034 * \brief Export a mesh to an UNV file
3036 //================================================================================
3038 void SMESH_Mesh_i::ExportUNV (const char *file)
3039 throw(SALOME::SALOME_Exception)
3041 Unexpect aCatch(SALOME_SalomeException);
3043 _preMeshInfo->FullLoadFromFile();
3045 // Update Python script
3046 // check names of groups
3048 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3051 PrepareForWriting(file);
3052 _impl->ExportUNV(file);
3055 //================================================================================
3057 * \brief Export a mesh to an STL file
3059 //================================================================================
3061 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3062 throw(SALOME::SALOME_Exception)
3064 Unexpect aCatch(SALOME_SalomeException);
3066 _preMeshInfo->FullLoadFromFile();
3068 // Update Python script
3069 // check names of groups
3071 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3072 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3074 CORBA::String_var name;
3075 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3076 if ( !so->_is_nil() )
3077 name = so->GetName();
3080 PrepareForWriting( file );
3081 _impl->ExportSTL( file, isascii, name.in() );
3084 //================================================================================
3086 * \brief Export a part of mesh to a med file
3088 //================================================================================
3090 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3092 CORBA::Boolean auto_groups,
3093 CORBA::Boolean overwrite,
3094 CORBA::Boolean autoDimension,
3095 const GEOM::ListOfFields& fields,
3096 const char* geomAssocFields)
3097 throw (SALOME::SALOME_Exception)
3101 _preMeshInfo->FullLoadFromFile();
3104 bool have0dField = false;
3105 if ( fields.length() > 0 )
3107 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3108 if ( shapeToMesh->_is_nil() )
3109 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3111 for ( size_t i = 0; i < fields.length(); ++i )
3113 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3114 THROW_SALOME_CORBA_EXCEPTION
3115 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3116 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3117 if ( fieldShape->_is_nil() )
3118 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3119 if ( !fieldShape->IsSame( shapeToMesh ) )
3120 THROW_SALOME_CORBA_EXCEPTION
3121 ( "Field defined not on shape", SALOME::BAD_PARAM);
3122 if ( fields[i]->GetDimension() == 0 )
3125 if ( geomAssocFields )
3126 for ( int i = 0; geomAssocFields[i]; ++i )
3127 switch ( geomAssocFields[i] ) {
3128 case 'v':case 'e':case 'f':case 's': break;
3129 case 'V':case 'E':case 'F':case 'S': break;
3130 default: THROW_SALOME_CORBA_EXCEPTION
3131 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3135 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3139 string aMeshName = "Mesh";
3140 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3141 if ( CORBA::is_nil( meshPart ) ||
3142 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3144 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3145 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3146 0, autoDimension, /*addODOnVertices=*/have0dField);
3147 meshDS = _impl->GetMeshDS();
3152 _preMeshInfo->FullLoadFromFile();
3154 PrepareForWriting(file, overwrite);
3156 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3157 if ( !SO->_is_nil() ) {
3158 CORBA::String_var name = SO->GetName();
3162 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3163 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3164 partDS, autoDimension, /*addODOnVertices=*/have0dField);
3165 meshDS = tmpDSDeleter._obj = partDS;
3170 if ( _impl->HasShapeToMesh() )
3172 DriverMED_W_Field fieldWriter;
3173 fieldWriter.SetFile( file );
3174 fieldWriter.SetMeshName( aMeshName );
3175 fieldWriter.AddODOnVertices( have0dField );
3177 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3181 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3182 goList->length( fields.length() );
3183 for ( size_t i = 0; i < fields.length(); ++i )
3185 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3188 TPythonDump() << _this() << ".ExportPartToMED( "
3189 << meshPart << ", r'" << file << "', "
3190 << auto_groups << ", " << overwrite << ", "
3191 << autoDimension << ", " << goList
3192 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3194 SMESH_CATCH( SMESH::throwCorbaException );
3197 //================================================================================
3199 * Write GEOM fields to MED file
3201 //================================================================================
3203 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3204 SMESHDS_Mesh* meshDS,
3205 const GEOM::ListOfFields& fields,
3206 const char* geomAssocFields)
3208 #define METH "SMESH_Mesh_i::exportMEDFields() "
3210 if (( fields.length() < 1 ) &&
3211 ( !geomAssocFields || !geomAssocFields[0] ))
3214 std::vector< std::vector< double > > dblVals;
3215 std::vector< std::vector< int > > intVals;
3216 std::vector< int > subIdsByDim[ 4 ];
3217 const double noneDblValue = 0.;
3218 const double noneIntValue = 0;
3220 for ( size_t iF = 0; iF < fields.length(); ++iF )
3224 int dim = fields[ iF ]->GetDimension();
3225 SMDSAbs_ElementType elemType;
3226 TopAbs_ShapeEnum shapeType;
3228 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3229 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3230 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3231 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3233 continue; // skip fields on whole shape
3235 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3236 if ( dataType == GEOM::FDT_String )
3238 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3239 if ( stepIDs->length() < 1 )
3241 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3242 if ( comps->length() < 1 )
3244 CORBA::String_var name = fields[ iF ]->GetName();
3246 if ( !fieldWriter.Set( meshDS,
3250 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3253 for ( size_t iC = 0; iC < comps->length(); ++iC )
3254 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3256 dblVals.resize( comps->length() );
3257 intVals.resize( comps->length() );
3259 // find sub-shape IDs
3261 std::vector< int >& subIds = subIdsByDim[ dim ];
3262 if ( subIds.empty() )
3263 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3264 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3265 subIds.push_back( id );
3269 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3273 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3275 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3276 if ( step->_is_nil() )
3279 CORBA::Long stamp = step->GetStamp();
3280 CORBA::Long id = step->GetID();
3281 fieldWriter.SetDtIt( int( stamp ), int( id ));
3283 // fill dblVals or intVals
3284 for ( size_t iC = 0; iC < comps->length(); ++iC )
3285 if ( dataType == GEOM::FDT_Double )
3287 dblVals[ iC ].clear();
3288 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3292 intVals[ iC ].clear();
3293 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3297 case GEOM::FDT_Double:
3299 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3300 if ( dblStep->_is_nil() ) continue;
3301 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3302 if ( vv->length() != subIds.size() * comps->length() )
3303 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3304 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3305 for ( size_t iC = 0; iC < comps->length(); ++iC )
3306 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3311 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3312 if ( intStep->_is_nil() ) continue;
3313 GEOM::ListOfLong_var vv = intStep->GetValues();
3314 if ( vv->length() != subIds.size() * comps->length() )
3315 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3316 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3317 for ( size_t iC = 0; iC < comps->length(); ++iC )
3318 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3321 case GEOM::FDT_Bool:
3323 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3324 if ( boolStep->_is_nil() ) continue;
3325 GEOM::short_array_var vv = boolStep->GetValues();
3326 if ( vv->length() != subIds.size() * comps->length() )
3327 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3328 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3329 for ( size_t iC = 0; iC < comps->length(); ++iC )
3330 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3336 // pass values to fieldWriter
3337 elemIt = fieldWriter.GetOrderedElems();
3338 if ( dataType == GEOM::FDT_Double )
3339 while ( elemIt->more() )
3341 const SMDS_MeshElement* e = elemIt->next();
3342 const int shapeID = e->getshapeId();
3343 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3344 for ( size_t iC = 0; iC < comps->length(); ++iC )
3345 fieldWriter.AddValue( noneDblValue );
3347 for ( size_t iC = 0; iC < comps->length(); ++iC )
3348 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3351 while ( elemIt->more() )
3353 const SMDS_MeshElement* e = elemIt->next();
3354 const int shapeID = e->getshapeId();
3355 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3356 for ( size_t iC = 0; iC < comps->length(); ++iC )
3357 fieldWriter.AddValue( (double) noneIntValue );
3359 for ( size_t iC = 0; iC < comps->length(); ++iC )
3360 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3364 fieldWriter.Perform();
3365 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3366 if ( res && res->IsKO() )
3368 if ( res->myComment.empty() )
3369 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3371 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3377 if ( !geomAssocFields || !geomAssocFields[0] )
3380 // write geomAssocFields
3382 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3383 shapeDim[ TopAbs_COMPOUND ] = 3;
3384 shapeDim[ TopAbs_COMPSOLID ] = 3;
3385 shapeDim[ TopAbs_SOLID ] = 3;
3386 shapeDim[ TopAbs_SHELL ] = 2;
3387 shapeDim[ TopAbs_FACE ] = 2;
3388 shapeDim[ TopAbs_WIRE ] = 1;
3389 shapeDim[ TopAbs_EDGE ] = 1;
3390 shapeDim[ TopAbs_VERTEX ] = 0;
3391 shapeDim[ TopAbs_SHAPE ] = 3;
3393 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3395 std::vector< std::string > compNames;
3396 switch ( geomAssocFields[ iF ]) {
3398 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3399 compNames.push_back( "dim" );
3402 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3405 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3408 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3412 compNames.push_back( "id" );
3413 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3414 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3416 fieldWriter.SetDtIt( -1, -1 );
3418 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3422 if ( compNames.size() == 2 ) // _vertices_
3423 while ( elemIt->more() )
3425 const SMDS_MeshElement* e = elemIt->next();
3426 const int shapeID = e->getshapeId();
3429 fieldWriter.AddValue( (double) -1 );
3430 fieldWriter.AddValue( (double) -1 );
3434 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3435 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3436 fieldWriter.AddValue( (double) shapeID );
3440 while ( elemIt->more() )
3442 const SMDS_MeshElement* e = elemIt->next();
3443 const int shapeID = e->getshapeId();
3445 fieldWriter.AddValue( (double) -1 );
3447 fieldWriter.AddValue( (double) shapeID );
3451 fieldWriter.Perform();
3452 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3453 if ( res && res->IsKO() )
3455 if ( res->myComment.empty() )
3456 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3458 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3461 } // loop on geomAssocFields
3466 //================================================================================
3468 * \brief Export a part of mesh to a DAT file
3470 //================================================================================
3472 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3474 throw (SALOME::SALOME_Exception)
3476 Unexpect aCatch(SALOME_SalomeException);
3478 _preMeshInfo->FullLoadFromFile();
3480 PrepareForWriting(file);
3482 SMESH_MeshPartDS partDS( meshPart );
3483 _impl->ExportDAT(file,&partDS);
3485 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3486 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3488 //================================================================================
3490 * \brief Export a part of mesh to an UNV file
3492 //================================================================================
3494 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3496 throw (SALOME::SALOME_Exception)
3498 Unexpect aCatch(SALOME_SalomeException);
3500 _preMeshInfo->FullLoadFromFile();
3502 PrepareForWriting(file);
3504 SMESH_MeshPartDS partDS( meshPart );
3505 _impl->ExportUNV(file, &partDS);
3507 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3508 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3510 //================================================================================
3512 * \brief Export a part of mesh to an STL file
3514 //================================================================================
3516 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3518 ::CORBA::Boolean isascii)
3519 throw (SALOME::SALOME_Exception)
3521 Unexpect aCatch(SALOME_SalomeException);
3523 _preMeshInfo->FullLoadFromFile();
3525 PrepareForWriting(file);
3527 CORBA::String_var name;
3528 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3529 if ( !so->_is_nil() )
3530 name = so->GetName();
3532 SMESH_MeshPartDS partDS( meshPart );
3533 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3535 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3536 << meshPart<< ", r'" << file << "', " << isascii << ")";
3539 //================================================================================
3541 * \brief Export a part of mesh to an STL file
3543 //================================================================================
3545 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3547 CORBA::Boolean overwrite)
3548 throw (SALOME::SALOME_Exception)
3551 Unexpect aCatch(SALOME_SalomeException);
3553 _preMeshInfo->FullLoadFromFile();
3555 PrepareForWriting(file,overwrite);
3557 std::string meshName("");
3558 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3559 if ( !so->_is_nil() )
3561 CORBA::String_var name = so->GetName();
3562 meshName = name.in();
3564 SMESH_MeshPartDS partDS( meshPart );
3565 _impl->ExportCGNS(file, &partDS, meshName.c_str() );
3567 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3568 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3570 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3574 //================================================================================
3576 * \brief Export a part of mesh to a GMF file
3578 //================================================================================
3580 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3582 bool withRequiredGroups)
3583 throw (SALOME::SALOME_Exception)
3585 Unexpect aCatch(SALOME_SalomeException);
3587 _preMeshInfo->FullLoadFromFile();
3589 PrepareForWriting(file,/*overwrite=*/true);
3591 SMESH_MeshPartDS partDS( meshPart );
3592 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3594 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3595 << meshPart<< ", r'"
3597 << withRequiredGroups << ")";
3600 //=============================================================================
3602 * Return computation progress [0.,1]
3604 //=============================================================================
3606 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3610 return _impl->GetComputeProgress();
3612 SMESH_CATCH( SMESH::doNothing );
3616 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3618 Unexpect aCatch(SALOME_SalomeException);
3620 return _preMeshInfo->NbNodes();
3622 return _impl->NbNodes();
3625 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3627 Unexpect aCatch(SALOME_SalomeException);
3629 return _preMeshInfo->NbElements();
3631 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3634 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3636 Unexpect aCatch(SALOME_SalomeException);
3638 return _preMeshInfo->Nb0DElements();
3640 return _impl->Nb0DElements();
3643 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3645 Unexpect aCatch(SALOME_SalomeException);
3647 return _preMeshInfo->NbBalls();
3649 return _impl->NbBalls();
3652 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3654 Unexpect aCatch(SALOME_SalomeException);
3656 return _preMeshInfo->NbEdges();
3658 return _impl->NbEdges();
3661 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3662 throw(SALOME::SALOME_Exception)
3664 Unexpect aCatch(SALOME_SalomeException);
3666 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3668 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3671 //=============================================================================
3673 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3675 Unexpect aCatch(SALOME_SalomeException);
3677 return _preMeshInfo->NbFaces();
3679 return _impl->NbFaces();
3682 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3684 Unexpect aCatch(SALOME_SalomeException);
3686 return _preMeshInfo->NbTriangles();
3688 return _impl->NbTriangles();
3691 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3693 Unexpect aCatch(SALOME_SalomeException);
3695 return _preMeshInfo->NbBiQuadTriangles();
3697 return _impl->NbBiQuadTriangles();
3700 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3702 Unexpect aCatch(SALOME_SalomeException);
3704 return _preMeshInfo->NbQuadrangles();
3706 return _impl->NbQuadrangles();
3709 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3711 Unexpect aCatch(SALOME_SalomeException);
3713 return _preMeshInfo->NbBiQuadQuadrangles();
3715 return _impl->NbBiQuadQuadrangles();
3718 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3720 Unexpect aCatch(SALOME_SalomeException);
3722 return _preMeshInfo->NbPolygons();
3724 return _impl->NbPolygons();
3727 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3729 Unexpect aCatch(SALOME_SalomeException);
3731 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3733 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3736 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3737 throw(SALOME::SALOME_Exception)
3739 Unexpect aCatch(SALOME_SalomeException);
3741 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3743 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3746 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3747 throw(SALOME::SALOME_Exception)
3749 Unexpect aCatch(SALOME_SalomeException);
3751 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3753 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3756 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3757 throw(SALOME::SALOME_Exception)
3759 Unexpect aCatch(SALOME_SalomeException);
3761 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3763 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3766 //=============================================================================
3768 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3770 Unexpect aCatch(SALOME_SalomeException);
3772 return _preMeshInfo->NbVolumes();
3774 return _impl->NbVolumes();
3777 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3779 Unexpect aCatch(SALOME_SalomeException);
3781 return _preMeshInfo->NbTetras();
3783 return _impl->NbTetras();
3786 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3788 Unexpect aCatch(SALOME_SalomeException);
3790 return _preMeshInfo->NbHexas();
3792 return _impl->NbHexas();
3795 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3797 Unexpect aCatch(SALOME_SalomeException);
3799 return _preMeshInfo->NbTriQuadHexas();
3801 return _impl->NbTriQuadraticHexas();
3804 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3806 Unexpect aCatch(SALOME_SalomeException);
3808 return _preMeshInfo->NbPyramids();
3810 return _impl->NbPyramids();
3813 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3815 Unexpect aCatch(SALOME_SalomeException);
3817 return _preMeshInfo->NbPrisms();
3819 return _impl->NbPrisms();
3822 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3824 Unexpect aCatch(SALOME_SalomeException);
3826 return _preMeshInfo->NbHexPrisms();
3828 return _impl->NbHexagonalPrisms();
3831 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3833 Unexpect aCatch(SALOME_SalomeException);
3835 return _preMeshInfo->NbPolyhedrons();
3837 return _impl->NbPolyhedrons();
3840 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3841 throw(SALOME::SALOME_Exception)
3843 Unexpect aCatch(SALOME_SalomeException);
3845 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3847 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3850 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3851 throw(SALOME::SALOME_Exception)
3853 Unexpect aCatch(SALOME_SalomeException);
3855 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3857 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3860 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3861 throw(SALOME::SALOME_Exception)
3863 Unexpect aCatch(SALOME_SalomeException);
3865 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3867 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3870 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3871 throw(SALOME::SALOME_Exception)
3873 Unexpect aCatch(SALOME_SalomeException);
3875 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3877 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3880 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3881 throw(SALOME::SALOME_Exception)
3883 Unexpect aCatch(SALOME_SalomeException);
3885 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3887 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3890 //=============================================================================
3892 * Returns nb of published sub-meshes
3894 //=============================================================================
3896 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3898 Unexpect aCatch(SALOME_SalomeException);
3899 return _mapSubMesh_i.size();
3902 //=============================================================================
3904 * Dumps mesh into a string
3906 //=============================================================================
3908 char* SMESH_Mesh_i::Dump()
3912 return CORBA::string_dup( os.str().c_str() );
3915 //=============================================================================
3917 * Method of SMESH_IDSource interface
3919 //=============================================================================
3921 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3923 return GetElementsId();
3926 //=============================================================================
3928 * Returns ids of all elements
3930 //=============================================================================
3932 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3933 throw (SALOME::SALOME_Exception)
3935 Unexpect aCatch(SALOME_SalomeException);
3937 _preMeshInfo->FullLoadFromFile();
3939 SMESH::long_array_var aResult = new SMESH::long_array();
3940 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3942 if ( aSMESHDS_Mesh == NULL )
3943 return aResult._retn();
3945 long nbElements = NbElements();
3946 aResult->length( nbElements );
3947 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3948 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3949 aResult[i] = anIt->next()->GetID();
3951 return aResult._retn();
3955 //=============================================================================
3957 * Returns ids of all elements of given type
3959 //=============================================================================
3961 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3962 throw (SALOME::SALOME_Exception)
3964 Unexpect aCatch(SALOME_SalomeException);
3966 _preMeshInfo->FullLoadFromFile();
3968 SMESH::long_array_var aResult = new SMESH::long_array();
3969 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3971 if ( aSMESHDS_Mesh == NULL )
3972 return aResult._retn();
3974 long nbElements = NbElements();
3976 // No sense in returning ids of elements along with ids of nodes:
3977 // when theElemType == SMESH::ALL, return node ids only if
3978 // there are no elements
3979 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3980 return GetNodesId();
3982 aResult->length( nbElements );
3986 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3987 while ( i < nbElements && anIt->more() )
3988 aResult[i++] = anIt->next()->GetID();
3990 aResult->length( i );
3992 return aResult._retn();
3995 //=============================================================================
3997 * Returns ids of all nodes
3999 //=============================================================================
4001 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4002 throw (SALOME::SALOME_Exception)
4004 Unexpect aCatch(SALOME_SalomeException);
4006 _preMeshInfo->FullLoadFromFile();
4008 SMESH::long_array_var aResult = new SMESH::long_array();
4009 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4011 if ( aSMESHDS_Mesh == NULL )
4012 return aResult._retn();
4014 long nbNodes = NbNodes();
4015 aResult->length( nbNodes );
4016 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4017 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4018 aResult[i] = anIt->next()->GetID();
4020 return aResult._retn();
4023 //=============================================================================
4027 //=============================================================================
4029 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4030 throw (SALOME::SALOME_Exception)
4032 SMESH::ElementType type = SMESH::ALL;
4036 _preMeshInfo->FullLoadFromFile();
4038 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4040 SMESH_CATCH( SMESH::throwCorbaException );
4045 //=============================================================================
4049 //=============================================================================
4051 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4052 throw (SALOME::SALOME_Exception)
4055 _preMeshInfo->FullLoadFromFile();
4057 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4059 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4061 return ( SMESH::EntityType ) e->GetEntityType();
4064 //=============================================================================
4068 //=============================================================================
4070 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4071 throw (SALOME::SALOME_Exception)
4074 _preMeshInfo->FullLoadFromFile();
4076 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4078 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4080 return ( SMESH::GeometryType ) e->GetGeomType();
4083 //=============================================================================
4085 * Returns ID of elements for given submesh
4087 //=============================================================================
4088 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4089 throw (SALOME::SALOME_Exception)
4091 SMESH::long_array_var aResult = new SMESH::long_array();
4095 _preMeshInfo->FullLoadFromFile();
4097 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4098 if(!SM) return aResult._retn();
4100 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4101 if(!SDSM) return aResult._retn();
4103 aResult->length(SDSM->NbElements());
4105 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4107 while ( eIt->more() ) {
4108 aResult[i++] = eIt->next()->GetID();
4111 SMESH_CATCH( SMESH::throwCorbaException );
4113 return aResult._retn();
4116 //=============================================================================
4118 * Returns ID of nodes for given submesh
4119 * If param all==true - returns all nodes, else -
4120 * returns only nodes on shapes.
4122 //=============================================================================
4124 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4126 throw (SALOME::SALOME_Exception)
4128 SMESH::long_array_var aResult = new SMESH::long_array();
4132 _preMeshInfo->FullLoadFromFile();
4134 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4135 if(!SM) return aResult._retn();
4137 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4138 if(!SDSM) return aResult._retn();
4141 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4142 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4143 while ( nIt->more() ) {
4144 const SMDS_MeshNode* elem = nIt->next();
4145 theElems.insert( elem->GetID() );
4148 else { // all nodes of submesh elements
4149 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4150 while ( eIt->more() ) {
4151 const SMDS_MeshElement* anElem = eIt->next();
4152 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4153 while ( nIt->more() ) {
4154 const SMDS_MeshElement* elem = nIt->next();
4155 theElems.insert( elem->GetID() );
4160 aResult->length(theElems.size());
4161 set<int>::iterator itElem;
4163 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4164 aResult[i++] = *itElem;
4166 SMESH_CATCH( SMESH::throwCorbaException );
4168 return aResult._retn();
4171 //=============================================================================
4173 * Returns type of elements for given submesh
4175 //=============================================================================
4177 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4178 throw (SALOME::SALOME_Exception)
4180 SMESH::ElementType type = SMESH::ALL;
4184 _preMeshInfo->FullLoadFromFile();
4186 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4187 if(!SM) return SMESH::ALL;
4189 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4190 if(!SDSM) return SMESH::ALL;
4192 if(SDSM->NbElements()==0)
4193 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4195 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4196 const SMDS_MeshElement* anElem = eIt->next();
4198 type = ( SMESH::ElementType ) anElem->GetType();
4200 SMESH_CATCH( SMESH::throwCorbaException );
4206 //=============================================================================
4208 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4210 //=============================================================================
4212 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4215 _preMeshInfo->FullLoadFromFile();
4217 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4218 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4223 //=============================================================================
4225 * Get XYZ coordinates of node as list of double
4226 * If there is not node for given ID - returns empty list
4228 //=============================================================================
4230 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4233 _preMeshInfo->FullLoadFromFile();
4235 SMESH::double_array_var aResult = new SMESH::double_array();
4236 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4237 if ( aSMESHDS_Mesh == NULL )
4238 return aResult._retn();
4241 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4243 return aResult._retn();
4247 aResult[0] = aNode->X();
4248 aResult[1] = aNode->Y();
4249 aResult[2] = aNode->Z();
4250 return aResult._retn();
4254 //=============================================================================
4256 * For given node returns list of IDs of inverse elements
4257 * If there is not node for given ID - returns empty list
4259 //=============================================================================
4261 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4264 _preMeshInfo->FullLoadFromFile();
4266 SMESH::long_array_var aResult = new SMESH::long_array();
4267 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4268 if ( aSMESHDS_Mesh == NULL )
4269 return aResult._retn();
4272 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4274 return aResult._retn();
4276 // find inverse elements
4277 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4278 aResult->length( aNode->NbInverseElements() );
4279 for( int i = 0; eIt->more(); ++i )
4281 const SMDS_MeshElement* elem = eIt->next();
4282 aResult[ i ] = elem->GetID();
4284 return aResult._retn();
4287 //=============================================================================
4289 * \brief Return position of a node on shape
4291 //=============================================================================
4293 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4296 _preMeshInfo->FullLoadFromFile();
4298 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4299 aNodePosition->shapeID = 0;
4300 aNodePosition->shapeType = GEOM::SHAPE;
4302 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4303 if ( !mesh ) return aNodePosition;
4305 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4307 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4309 aNodePosition->shapeID = aNode->getshapeId();
4310 switch ( pos->GetTypeOfPosition() ) {
4312 aNodePosition->shapeType = GEOM::EDGE;
4313 aNodePosition->params.length(1);
4314 aNodePosition->params[0] =
4315 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4318 aNodePosition->shapeType = GEOM::FACE;
4319 aNodePosition->params.length(2);
4320 aNodePosition->params[0] =
4321 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4322 aNodePosition->params[1] =
4323 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4325 case SMDS_TOP_VERTEX:
4326 aNodePosition->shapeType = GEOM::VERTEX;
4328 case SMDS_TOP_3DSPACE:
4329 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4330 aNodePosition->shapeType = GEOM::SOLID;
4331 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4332 aNodePosition->shapeType = GEOM::SHELL;
4338 return aNodePosition;
4341 //=============================================================================
4343 * \brief Return position of an element on shape
4345 //=============================================================================
4347 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4350 _preMeshInfo->FullLoadFromFile();
4352 SMESH::ElementPosition anElementPosition;
4353 anElementPosition.shapeID = 0;
4354 anElementPosition.shapeType = GEOM::SHAPE;
4356 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4357 if ( !mesh ) return anElementPosition;
4359 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4361 anElementPosition.shapeID = anElem->getshapeId();
4362 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4363 if ( !aSp.IsNull() ) {
4364 switch ( aSp.ShapeType() ) {
4366 anElementPosition.shapeType = GEOM::EDGE;
4369 anElementPosition.shapeType = GEOM::FACE;
4372 anElementPosition.shapeType = GEOM::VERTEX;
4375 anElementPosition.shapeType = GEOM::SOLID;
4378 anElementPosition.shapeType = GEOM::SHELL;
4384 return anElementPosition;
4387 //=============================================================================
4389 * If given element is node returns IDs of shape from position
4390 * If there is not node for given ID - returns -1
4392 //=============================================================================
4394 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4397 _preMeshInfo->FullLoadFromFile();
4399 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4400 if ( aSMESHDS_Mesh == NULL )
4404 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4406 return aNode->getshapeId();
4413 //=============================================================================
4415 * For given element returns ID of result shape after
4416 * ::FindShape() from SMESH_MeshEditor
4417 * If there is not element for given ID - returns -1
4419 //=============================================================================
4421 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4424 _preMeshInfo->FullLoadFromFile();
4426 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4427 if ( aSMESHDS_Mesh == NULL )
4430 // try to find element
4431 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4435 ::SMESH_MeshEditor aMeshEditor(_impl);
4436 int index = aMeshEditor.FindShape( elem );
4444 //=============================================================================
4446 * Returns number of nodes for given element
4447 * If there is not element for given ID - returns -1
4449 //=============================================================================
4451 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4454 _preMeshInfo->FullLoadFromFile();
4456 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4457 if ( aSMESHDS_Mesh == NULL ) return -1;
4458 // try to find element
4459 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4460 if(!elem) return -1;
4461 return elem->NbNodes();
4465 //=============================================================================
4467 * Returns ID of node by given index for given element
4468 * If there is not element for given ID - returns -1
4469 * If there is not node for given index - returns -2
4471 //=============================================================================
4473 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4476 _preMeshInfo->FullLoadFromFile();
4478 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4479 if ( aSMESHDS_Mesh == NULL ) return -1;
4480 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4481 if(!elem) return -1;
4482 if( index>=elem->NbNodes() || index<0 ) return -1;
4483 return elem->GetNode(index)->GetID();
4486 //=============================================================================
4488 * Returns IDs of nodes of given element
4490 //=============================================================================
4492 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4495 _preMeshInfo->FullLoadFromFile();
4497 SMESH::long_array_var aResult = new SMESH::long_array();
4498 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4500 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4502 aResult->length( elem->NbNodes() );
4503 for ( int i = 0; i < elem->NbNodes(); ++i )
4504 aResult[ i ] = elem->GetNode( i )->GetID();
4507 return aResult._retn();
4510 //=============================================================================
4512 * Returns true if given node is medium node
4513 * in given quadratic element
4515 //=============================================================================
4517 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4520 _preMeshInfo->FullLoadFromFile();
4522 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4523 if ( aSMESHDS_Mesh == NULL ) return false;
4525 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4526 if(!aNode) return false;
4527 // try to find element
4528 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4529 if(!elem) return false;
4531 return elem->IsMediumNode(aNode);
4535 //=============================================================================
4537 * Returns true if given node is medium node
4538 * in one of quadratic elements
4540 //=============================================================================
4542 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4543 SMESH::ElementType theElemType)
4546 _preMeshInfo->FullLoadFromFile();
4548 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4549 if ( aSMESHDS_Mesh == NULL ) return false;
4552 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4553 if(!aNode) return false;
4555 SMESH_MesherHelper aHelper( *(_impl) );
4557 SMDSAbs_ElementType aType;
4558 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4559 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4560 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4561 else aType = SMDSAbs_All;
4563 return aHelper.IsMedium(aNode,aType);
4567 //=============================================================================
4569 * Returns number of edges for given element
4571 //=============================================================================
4573 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4576 _preMeshInfo->FullLoadFromFile();
4578 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4579 if ( aSMESHDS_Mesh == NULL ) return -1;
4580 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4581 if(!elem) return -1;
4582 return elem->NbEdges();
4586 //=============================================================================
4588 * Returns number of faces for given element
4590 //=============================================================================
4592 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4595 _preMeshInfo->FullLoadFromFile();
4597 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4598 if ( aSMESHDS_Mesh == NULL ) return -1;
4599 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4600 if(!elem) return -1;
4601 return elem->NbFaces();
4604 //=======================================================================
4605 //function : GetElemFaceNodes
4606 //purpose : Returns nodes of given face (counted from zero) for given element.
4607 //=======================================================================
4609 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4610 CORBA::Short faceIndex)
4613 _preMeshInfo->FullLoadFromFile();
4615 SMESH::long_array_var aResult = new SMESH::long_array();
4616 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4618 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4620 SMDS_VolumeTool vtool( elem );
4621 if ( faceIndex < vtool.NbFaces() )
4623 aResult->length( vtool.NbFaceNodes( faceIndex ));
4624 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4625 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4626 aResult[ i ] = nn[ i ]->GetID();
4630 return aResult._retn();
4633 //=======================================================================
4634 //function : GetElemFaceNodes
4635 //purpose : Returns three components of normal of given mesh face.
4636 //=======================================================================
4638 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4639 CORBA::Boolean normalized)
4642 _preMeshInfo->FullLoadFromFile();
4644 SMESH::double_array_var aResult = new SMESH::double_array();
4646 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4649 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4651 aResult->length( 3 );
4652 aResult[ 0 ] = normal.X();
4653 aResult[ 1 ] = normal.Y();
4654 aResult[ 2 ] = normal.Z();
4657 return aResult._retn();
4660 //=======================================================================
4661 //function : FindElementByNodes
4662 //purpose : Returns an element based on all given nodes.
4663 //=======================================================================
4665 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4668 _preMeshInfo->FullLoadFromFile();
4670 CORBA::Long elemID(0);
4671 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4673 vector< const SMDS_MeshNode * > nn( nodes.length() );
4674 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4675 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4678 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4679 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4680 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4681 _impl->NbVolumes( ORDER_QUADRATIC )))
4682 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4684 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4689 //================================================================================
4691 * \brief Return elements including all given nodes.
4693 //================================================================================
4695 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4696 SMESH::ElementType elemType)
4699 _preMeshInfo->FullLoadFromFile();
4701 SMESH::long_array_var result = new SMESH::long_array();
4703 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4705 vector< const SMDS_MeshNode * > nn( nodes.length() );
4706 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4707 nn[i] = mesh->FindNode( nodes[i] );
4709 std::vector<const SMDS_MeshElement *> elems;
4710 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4711 result->length( elems.size() );
4712 for ( size_t i = 0; i < elems.size(); ++i )
4713 result[i] = elems[i]->GetID();
4715 return result._retn();
4718 //=============================================================================
4720 * Returns true if given element is polygon
4722 //=============================================================================
4724 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4727 _preMeshInfo->FullLoadFromFile();
4729 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4730 if ( aSMESHDS_Mesh == NULL ) return false;
4731 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4732 if(!elem) return false;
4733 return elem->IsPoly();
4737 //=============================================================================
4739 * Returns true if given element is quadratic
4741 //=============================================================================
4743 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4746 _preMeshInfo->FullLoadFromFile();
4748 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4749 if ( aSMESHDS_Mesh == NULL ) return false;
4750 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4751 if(!elem) return false;
4752 return elem->IsQuadratic();
4755 //=============================================================================
4757 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4759 //=============================================================================
4761 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4764 _preMeshInfo->FullLoadFromFile();
4766 if ( const SMDS_BallElement* ball =
4767 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4768 return ball->GetDiameter();
4773 //=============================================================================
4775 * Returns bary center for given element
4777 //=============================================================================
4779 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4782 _preMeshInfo->FullLoadFromFile();
4784 SMESH::double_array_var aResult = new SMESH::double_array();
4785 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4786 if ( aSMESHDS_Mesh == NULL )
4787 return aResult._retn();
4789 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4791 return aResult._retn();
4793 if(elem->GetType()==SMDSAbs_Volume) {
4794 SMDS_VolumeTool aTool;
4795 if(aTool.Set(elem)) {
4797 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4802 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4804 double x=0., y=0., z=0.;
4805 for(; anIt->more(); ) {
4807 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4821 return aResult._retn();
4824 //================================================================================
4826 * \brief Create a group of elements preventing computation of a sub-shape
4828 //================================================================================
4830 SMESH::ListOfGroups*
4831 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4832 const char* theGroupName )
4833 throw ( SALOME::SALOME_Exception )
4835 Unexpect aCatch(SALOME_SalomeException);
4837 if ( !theGroupName || strlen( theGroupName) == 0 )
4838 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4840 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4841 ::SMESH_MeshEditor::ElemFeatures elemType;
4843 // submesh by subshape id
4844 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4845 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4848 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4849 if ( error && !error->myBadElements.empty())
4851 // sort bad elements by type
4852 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4853 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4854 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4855 for ( ; elemIt != elemEnd; ++elemIt )
4857 const SMDS_MeshElement* elem = *elemIt;
4858 if ( !elem ) continue;
4860 if ( elem->GetID() < 1 )
4862 // elem is a temporary element, make a real element
4863 vector< const SMDS_MeshNode* > nodes;
4864 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4865 while ( nIt->more() && elem )
4867 nodes.push_back( nIt->next() );
4868 if ( nodes.back()->GetID() < 1 )
4869 elem = 0; // a temporary element on temporary nodes
4873 ::SMESH_MeshEditor editor( _impl );
4874 elem = editor.AddElement( nodes, elemType.Init( elem ));
4878 elemsByType[ elem->GetType() ].push_back( elem );
4881 // how many groups to create?
4883 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4884 nbTypes += int( !elemsByType[ i ].empty() );
4885 groups->length( nbTypes );
4888 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4890 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4891 if ( elems.empty() ) continue;
4893 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4894 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4896 SMESH::SMESH_Mesh_var mesh = _this();
4897 SALOMEDS::SObject_wrap aSO =
4898 _gen_i->PublishGroup( mesh, groups[ iG ],
4899 GEOM::GEOM_Object::_nil(), theGroupName);
4901 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4902 if ( !grp_i ) continue;
4904 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4905 for ( size_t iE = 0; iE < elems.size(); ++iE )
4906 grpDS->SMDSGroup().Add( elems[ iE ]);
4911 return groups._retn();
4914 //=============================================================================
4916 * Create and publish group servants if any groups were imported or created anyhow
4918 //=============================================================================
4920 void SMESH_Mesh_i::CreateGroupServants()
4922 SMESH::SMESH_Mesh_var aMesh = _this();
4925 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4926 while ( groupIt->more() )
4928 ::SMESH_Group* group = groupIt->next();
4929 int anId = group->GetGroupDS()->GetID();
4931 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4932 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4934 addedIDs.insert( anId );
4936 SMESH_GroupBase_i* aGroupImpl;
4938 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4939 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4941 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4942 shape = groupOnGeom->GetShape();
4945 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4948 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4949 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4950 aGroupImpl->Register();
4952 // register CORBA object for persistence
4953 int nextId = _gen_i->RegisterObject( groupVar );
4954 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4955 else { nextId = 0; } // avoid "unused variable" warning in release mode
4957 // publishing the groups in the study
4958 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4959 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
4961 if ( !addedIDs.empty() )
4964 set<int>::iterator id = addedIDs.begin();
4965 for ( ; id != addedIDs.end(); ++id )
4967 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4968 int i = std::distance( _mapGroups.begin(), it );
4969 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4974 //=============================================================================
4976 * \brief Return groups cantained in _mapGroups by their IDs
4978 //=============================================================================
4980 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4982 int nbGroups = groupIDs.size();
4983 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4984 aList->length( nbGroups );
4986 list<int>::const_iterator ids = groupIDs.begin();
4987 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4989 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4990 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4991 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4993 aList->length( nbGroups );
4994 return aList._retn();
4997 //=============================================================================
4999 * \brief Return information about imported file
5001 //=============================================================================
5003 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5005 SMESH::MedFileInfo_var res( _medFileInfo );
5006 if ( !res.operator->() ) {
5007 res = new SMESH::MedFileInfo;
5009 res->fileSize = res->major = res->minor = res->release = -1;
5014 //=============================================================================
5016 * \brief Pass names of mesh groups from study to mesh DS
5018 //=============================================================================
5020 void SMESH_Mesh_i::checkGroupNames()
5022 int nbGrp = NbGroups();
5026 SMESH::ListOfGroups* grpList = 0;
5027 // avoid dump of "GetGroups"
5029 // store python dump into a local variable inside local scope
5030 SMESH::TPythonDump pDump; // do not delete this line of code
5031 grpList = GetGroups();
5034 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5035 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5038 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5039 if ( aGrpSO->_is_nil() )
5041 // correct name of the mesh group if necessary
5042 const char* guiName = aGrpSO->GetName();
5043 if ( strcmp(guiName, aGrp->GetName()) )
5044 aGrp->SetName( guiName );
5048 //=============================================================================
5050 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5052 //=============================================================================
5053 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5055 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5059 //=============================================================================
5061 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5063 //=============================================================================
5065 char* SMESH_Mesh_i::GetParameters()
5067 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5070 //=============================================================================
5072 * \brief Returns list of notebook variables used for last Mesh operation
5074 //=============================================================================
5075 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5077 SMESH::string_array_var aResult = new SMESH::string_array();
5078 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5080 CORBA::String_var aParameters = GetParameters();
5081 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5082 if ( aSections->length() > 0 ) {
5083 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5084 aResult->length( aVars.length() );
5085 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5086 aResult[i] = CORBA::string_dup( aVars[i] );
5089 return aResult._retn();
5092 //=======================================================================
5093 //function : GetTypes
5094 //purpose : Returns types of elements it contains
5095 //=======================================================================
5097 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5100 return _preMeshInfo->GetTypes();
5102 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5106 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5107 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5108 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5109 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5110 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5111 if (_impl->NbNodes() &&
5112 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5113 types->length( nbTypes );
5115 return types._retn();
5118 //=======================================================================
5119 //function : GetMesh
5120 //purpose : Returns self
5121 //=======================================================================
5123 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5125 return SMESH::SMESH_Mesh::_duplicate( _this() );
5128 //=======================================================================
5129 //function : IsMeshInfoCorrect
5130 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5131 // * happen if mesh data is not yet fully loaded from the file of study.
5132 //=======================================================================
5134 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5136 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5139 //=============================================================================
5141 * \brief Returns number of mesh elements per each \a EntityType
5143 //=============================================================================
5145 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5148 return _preMeshInfo->GetMeshInfo();
5150 SMESH::long_array_var aRes = new SMESH::long_array();
5151 aRes->length(SMESH::Entity_Last);
5152 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5154 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5156 return aRes._retn();
5157 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5158 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5159 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5160 return aRes._retn();
5163 //=============================================================================
5165 * \brief Returns number of mesh elements per each \a ElementType
5167 //=============================================================================
5169 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5171 SMESH::long_array_var aRes = new SMESH::long_array();
5172 aRes->length(SMESH::NB_ELEMENT_TYPES);
5173 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5176 const SMDS_MeshInfo* meshInfo = 0;
5178 meshInfo = _preMeshInfo;
5179 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5180 meshInfo = & meshDS->GetMeshInfo();
5183 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5184 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5186 return aRes._retn();
5189 //=============================================================================
5191 * Collect statistic of mesh elements given by iterator
5193 //=============================================================================
5195 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5196 SMESH::long_array& theInfo)
5198 if (!theItr) return;
5199 while (theItr->more())
5200 theInfo[ theItr->next()->GetEntityType() ]++;
5202 //=============================================================================
5204 * Returns mesh unstructed grid information.
5206 //=============================================================================
5208 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5210 SALOMEDS::TMPFile_var SeqFile;
5211 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5212 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5214 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5215 aWriter->WriteToOutputStringOn();
5216 aWriter->SetInputData(aGrid);
5217 aWriter->SetFileTypeToBinary();
5219 char* str = aWriter->GetOutputString();
5220 int size = aWriter->GetOutputStringLength();
5222 //Allocate octect buffer of required size
5223 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5224 //Copy ostrstream content to the octect buffer
5225 memcpy(OctetBuf, str, size);
5226 //Create and return TMPFile
5227 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5231 return SeqFile._retn();
5234 //=============================================================================
5235 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5236 * SMESH::ElementType type) */
5238 using namespace SMESH::Controls;
5239 //-----------------------------------------------------------------------------
5240 struct PredicateIterator : public SMDS_ElemIterator
5242 SMDS_ElemIteratorPtr _elemIter;
5243 PredicatePtr _predicate;
5244 const SMDS_MeshElement* _elem;
5246 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5247 PredicatePtr predicate):
5248 _elemIter(iterator), _predicate(predicate)
5256 virtual const SMDS_MeshElement* next()
5258 const SMDS_MeshElement* res = _elem;
5260 while ( _elemIter->more() && !_elem )
5262 _elem = _elemIter->next();
5263 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5270 //-----------------------------------------------------------------------------
5271 struct IDSourceIterator : public SMDS_ElemIterator
5273 const CORBA::Long* _idPtr;
5274 const CORBA::Long* _idEndPtr;
5275 SMESH::long_array_var _idArray;
5276 const SMDS_Mesh* _mesh;
5277 const SMDSAbs_ElementType _type;
5278 const SMDS_MeshElement* _elem;
5280 IDSourceIterator( const SMDS_Mesh* mesh,
5281 const CORBA::Long* ids,
5283 SMDSAbs_ElementType type):
5284 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5286 if ( _idPtr && nbIds && _mesh )
5289 IDSourceIterator( const SMDS_Mesh* mesh,
5290 SMESH::long_array* idArray,
5291 SMDSAbs_ElementType type):
5292 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5294 if ( idArray && _mesh )
5296 _idPtr = &_idArray[0];
5297 _idEndPtr = _idPtr + _idArray->length();
5305 virtual const SMDS_MeshElement* next()
5307 const SMDS_MeshElement* res = _elem;
5309 while ( _idPtr < _idEndPtr && !_elem )
5311 if ( _type == SMDSAbs_Node )
5313 _elem = _mesh->FindNode( *_idPtr++ );
5315 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5316 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5324 //-----------------------------------------------------------------------------
5326 struct NodeOfElemIterator : public SMDS_ElemIterator
5328 TColStd_MapOfInteger _checkedNodeIDs;
5329 SMDS_ElemIteratorPtr _elemIter;
5330 SMDS_ElemIteratorPtr _nodeIter;
5331 const SMDS_MeshElement* _node;
5333 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5335 if ( _elemIter && _elemIter->more() )
5337 _nodeIter = _elemIter->next()->nodesIterator();
5345 virtual const SMDS_MeshElement* next()
5347 const SMDS_MeshElement* res = _node;
5349 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5351 if ( _nodeIter->more() )
5353 _node = _nodeIter->next();
5354 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5359 _nodeIter = _elemIter->next()->nodesIterator();
5367 //=============================================================================
5369 * Return iterator on elements of given type in given object
5371 //=============================================================================
5373 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5374 SMESH::ElementType theType)
5376 SMDS_ElemIteratorPtr elemIt;
5377 bool typeOK = ( theType == SMESH::ALL );
5378 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5380 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5381 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5382 if ( !mesh_i ) return elemIt;
5383 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5385 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5387 elemIt = meshDS->elementsIterator( elemType );
5390 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5392 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5395 elemIt = sm->GetElements();
5396 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5398 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5399 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5403 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5405 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5406 if ( groupDS && ( elemType == groupDS->GetType() ||
5407 elemType == SMDSAbs_Node ||
5408 elemType == SMDSAbs_All ))
5410 elemIt = groupDS->GetElements();
5411 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5414 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5416 if ( filter_i->GetElementType() == theType ||
5417 elemType == SMDSAbs_Node ||
5418 elemType == SMDSAbs_All)
5420 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5421 if ( pred_i && pred_i->GetPredicate() )
5423 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5424 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5425 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5426 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5432 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5433 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5434 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5436 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5439 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5440 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5444 SMESH::long_array_var ids = theObject->GetIDs();
5445 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5447 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5450 if ( elemIt && elemIt->more() && !typeOK )
5452 if ( elemType == SMDSAbs_Node )
5454 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5458 elemIt = SMDS_ElemIteratorPtr();
5464 //=============================================================================
5465 namespace // Finding concurrent hypotheses
5466 //=============================================================================
5470 * \brief mapping of mesh dimension into shape type
5472 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5474 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5476 case 0: aType = TopAbs_VERTEX; break;
5477 case 1: aType = TopAbs_EDGE; break;
5478 case 2: aType = TopAbs_FACE; break;
5480 default:aType = TopAbs_SOLID; break;
5485 //-----------------------------------------------------------------------------
5487 * \brief Internal structure used to find concurent submeshes
5489 * It represents a pair < submesh, concurent dimension >, where
5490 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5491 * with another submesh. In other words, it is dimension of a hypothesis assigned
5498 int _dim; //!< a dimension the algo can build (concurrent dimension)
5499 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5500 TopTools_MapOfShape _shapeMap;
5501 SMESH_subMesh* _subMesh;
5502 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5504 //-----------------------------------------------------------------------------
5505 // Return the algorithm
5506 const SMESH_Algo* GetAlgo() const
5507 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5509 //-----------------------------------------------------------------------------
5511 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5513 const TopoDS_Shape& theShape)
5515 _subMesh = (SMESH_subMesh*)theSubMesh;
5516 SetShape( theDim, theShape );
5519 //-----------------------------------------------------------------------------
5521 void SetShape(const int theDim,
5522 const TopoDS_Shape& theShape)
5525 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5526 if (_dim >= _ownDim)
5527 _shapeMap.Add( theShape );
5529 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5530 for( ; anExp.More(); anExp.Next() )
5531 _shapeMap.Add( anExp.Current() );
5535 //-----------------------------------------------------------------------------
5536 //! Check sharing of sub-shapes
5537 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5538 const TopTools_MapOfShape& theToFind,
5539 const TopAbs_ShapeEnum theType)
5541 bool isShared = false;
5542 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5543 for (; !isShared && anItr.More(); anItr.Next() )
5545 const TopoDS_Shape aSubSh = anItr.Key();
5546 // check for case when concurrent dimensions are same
5547 isShared = theToFind.Contains( aSubSh );
5548 // check for sub-shape with concurrent dimension
5549 TopExp_Explorer anExp( aSubSh, theType );
5550 for ( ; !isShared && anExp.More(); anExp.Next() )
5551 isShared = theToFind.Contains( anExp.Current() );
5556 //-----------------------------------------------------------------------------
5557 //! check algorithms
5558 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5559 const SMESHDS_Hypothesis* theA2)
5561 if ( !theA1 || !theA2 ||
5562 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5563 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5564 return false; // one of the hypothesis is not algorithm
5565 // check algorithm names (should be equal)
5566 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5570 //-----------------------------------------------------------------------------
5571 //! Check if sub-shape hypotheses are concurrent
5572 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5574 if ( _subMesh == theOther->_subMesh )
5575 return false; // same sub-shape - should not be
5577 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5578 // any of the two submeshes is not on COMPOUND shape )
5579 // -> no concurrency
5580 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5581 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5582 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5583 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5584 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5587 // bool checkSubShape = ( _dim >= theOther->_dim )
5588 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5589 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5590 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5591 if ( !checkSubShape )
5594 // check algorithms to be same
5595 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5596 return true; // different algorithms -> concurrency !
5598 // check hypothesises for concurrence (skip first as algorithm)
5600 // pointers should be same, because it is referened from mesh hypothesis partition
5601 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5602 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5603 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5604 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5606 // the submeshes are concurrent if their algorithms has different parameters
5607 return nbSame != (int)theOther->_hypotheses.size() - 1;
5610 // Return true if algorithm of this SMESH_DimHyp is used if no
5611 // sub-mesh order is imposed by the user
5612 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5614 // NeedDiscreteBoundary() algo has a higher priority
5615 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5616 theOther->GetAlgo()->NeedDiscreteBoundary() )
5617 return !this->GetAlgo()->NeedDiscreteBoundary();
5619 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5622 }; // end of SMESH_DimHyp
5623 //-----------------------------------------------------------------------------
5625 typedef list<const SMESH_DimHyp*> TDimHypList;
5627 //-----------------------------------------------------------------------------
5629 void addDimHypInstance(const int theDim,
5630 const TopoDS_Shape& theShape,
5631 const SMESH_Algo* theAlgo,
5632 const SMESH_subMesh* theSubMesh,
5633 const list <const SMESHDS_Hypothesis*>& theHypList,
5634 TDimHypList* theDimHypListArr )
5636 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5637 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5638 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5639 dimHyp->_hypotheses.push_front(theAlgo);
5640 listOfdimHyp.push_back( dimHyp );
5643 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5644 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5645 theHypList.begin(), theHypList.end() );
5648 //-----------------------------------------------------------------------------
5649 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5650 TDimHypList& theListOfConcurr)
5652 if ( theListOfConcurr.empty() )
5654 theListOfConcurr.push_back( theDimHyp );
5658 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5659 while ( hypIt != theListOfConcurr.end() &&
5660 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5662 theListOfConcurr.insert( hypIt, theDimHyp );
5666 //-----------------------------------------------------------------------------
5667 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5668 const TDimHypList& theListOfDimHyp,
5669 TDimHypList& theListOfConcurrHyp,
5670 set<int>& theSetOfConcurrId )
5672 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5673 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5675 const SMESH_DimHyp* curDimHyp = *rIt;
5676 if ( curDimHyp == theDimHyp )
5677 break; // meet own dimHyp pointer in same dimension
5679 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5680 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5682 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5687 //-----------------------------------------------------------------------------
5688 void unionLists(TListOfInt& theListOfId,
5689 TListOfListOfInt& theListOfListOfId,
5692 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5693 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5695 continue; //skip already treated lists
5696 // check if other list has any same submesh object
5697 TListOfInt& otherListOfId = *it;
5698 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5699 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5702 // union two lists (from source into target)
5703 TListOfInt::iterator it2 = otherListOfId.begin();
5704 for ( ; it2 != otherListOfId.end(); it2++ ) {
5705 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5706 theListOfId.push_back(*it2);
5708 // clear source list
5709 otherListOfId.clear();
5712 //-----------------------------------------------------------------------------
5714 //! free memory allocated for dimension-hypothesis objects
5715 void removeDimHyps( TDimHypList* theArrOfList )
5717 for (int i = 0; i < 4; i++ ) {
5718 TDimHypList& listOfdimHyp = theArrOfList[i];
5719 TDimHypList::const_iterator it = listOfdimHyp.begin();
5720 for ( ; it != listOfdimHyp.end(); it++ )
5725 //-----------------------------------------------------------------------------
5727 * \brief find common submeshes with given submesh
5728 * \param theSubMeshList list of already collected submesh to check
5729 * \param theSubMesh given submesh to intersect with other
5730 * \param theCommonSubMeshes collected common submeshes
5732 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5733 const SMESH_subMesh* theSubMesh,
5734 set<const SMESH_subMesh*>& theCommon )
5738 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5739 for ( ; it != theSubMeshList.end(); it++ )
5740 theSubMesh->FindIntersection( *it, theCommon );
5741 theSubMeshList.push_back( theSubMesh );
5742 //theCommon.insert( theSubMesh );
5745 //-----------------------------------------------------------------------------
5746 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5748 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5749 for ( ; listsIt != smLists.end(); ++listsIt )
5751 const TListOfInt& smIDs = *listsIt;
5752 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5760 //=============================================================================
5762 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5764 //=============================================================================
5766 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5768 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5769 if ( isSubMeshInList( submeshID, anOrder ))
5772 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5773 return isSubMeshInList( submeshID, allConurrent );
5776 //=============================================================================
5778 * \brief Return submesh objects list in meshing order
5780 //=============================================================================
5782 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5784 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5786 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5788 return aResult._retn();
5790 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5791 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5792 anOrder.splice( anOrder.end(), allConurrent );
5795 TListOfListOfInt::iterator listIt = anOrder.begin();
5796 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5797 unionLists( *listIt, anOrder, listIndx + 1 );
5799 // convert submesh ids into interface instances
5800 // and dump command into python
5801 convertMeshOrder( anOrder, aResult, false );
5803 return aResult._retn();
5806 //=============================================================================
5808 * \brief Finds concurrent sub-meshes
5810 //=============================================================================
5812 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5814 TListOfListOfInt anOrder;
5815 ::SMESH_Mesh& mesh = GetImpl();
5817 // collect submeshes and detect concurrent algorithms and hypothesises
5818 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5820 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5821 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5822 ::SMESH_subMesh* sm = (*i_sm).second;
5824 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5826 // list of assigned hypothesises
5827 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5828 // Find out dimensions where the submesh can be concurrent.
5829 // We define the dimensions by algo of each of hypotheses in hypList
5830 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5831 for( ; hypIt != hypList.end(); hypIt++ ) {
5832 SMESH_Algo* anAlgo = 0;
5833 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5834 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5835 // hyp it-self is algo
5836 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5838 // try to find algorithm with help of sub-shapes
5839 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5840 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5841 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5844 continue; // no algorithm assigned to a current submesh
5846 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5847 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5849 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5850 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5851 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5853 } // end iterations on submesh
5855 // iterate on created dimension-hypotheses and check for concurrents
5856 for ( int i = 0; i < 4; i++ ) {
5857 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5858 // check for concurrents in own and other dimensions (step-by-step)
5859 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5860 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5861 const SMESH_DimHyp* dimHyp = *dhIt;
5862 TDimHypList listOfConcurr;
5863 set<int> setOfConcurrIds;
5864 // looking for concurrents and collect into own list
5865 for ( int j = i; j < 4; j++ )
5866 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5867 // check if any concurrents found
5868 if ( listOfConcurr.size() > 0 ) {
5869 // add own submesh to list of concurrent
5870 addInOrderOfPriority( dimHyp, listOfConcurr );
5871 list<int> listOfConcurrIds;
5872 TDimHypList::iterator hypIt = listOfConcurr.begin();
5873 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5874 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5875 anOrder.push_back( listOfConcurrIds );
5880 removeDimHyps(dimHypListArr);
5882 // now, minimise the number of concurrent groups
5883 // Here we assume that lists of submeshes can have same submesh
5884 // in case of multi-dimension algorithms, as result
5885 // list with common submesh has to be united into one list
5887 TListOfListOfInt::iterator listIt = anOrder.begin();
5888 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5889 unionLists( *listIt, anOrder, listIndx + 1 );
5895 //=============================================================================
5897 * \brief Set submesh object order
5898 * \param theSubMeshArray submesh array order
5900 //=============================================================================
5902 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5905 _preMeshInfo->ForgetOrLoad();
5908 ::SMESH_Mesh& mesh = GetImpl();
5910 TPythonDump aPythonDump; // prevent dump of called methods
5911 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5913 TListOfListOfInt subMeshOrder;
5914 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5916 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5917 TListOfInt subMeshIds;
5919 aPythonDump << ", ";
5920 aPythonDump << "[ ";
5921 // Collect subMeshes which should be clear
5922 // do it list-by-list, because modification of submesh order
5923 // take effect between concurrent submeshes only
5924 set<const SMESH_subMesh*> subMeshToClear;
5925 list<const SMESH_subMesh*> subMeshList;
5926 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5928 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5930 aPythonDump << ", ";
5931 aPythonDump << subMesh;
5932 subMeshIds.push_back( subMesh->GetId() );
5933 // detect common parts of submeshes
5934 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5935 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5937 aPythonDump << " ]";
5938 subMeshOrder.push_back( subMeshIds );
5940 // clear collected submeshes
5941 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5942 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5943 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5944 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5946 aPythonDump << " ])";
5948 mesh.SetMeshOrder( subMeshOrder );
5954 //=============================================================================
5956 * \brief Convert submesh ids into submesh interfaces
5958 //=============================================================================
5960 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5961 SMESH::submesh_array_array& theResOrder,
5962 const bool theIsDump)
5964 int nbSet = theIdsOrder.size();
5965 TPythonDump aPythonDump; // prevent dump of called methods
5967 aPythonDump << "[ ";
5968 theResOrder.length(nbSet);
5969 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5971 for( ; it != theIdsOrder.end(); it++ ) {
5972 // translate submesh identificators into submesh objects
5973 // takeing into account real number of concurrent lists
5974 const TListOfInt& aSubOrder = (*it);
5975 if (!aSubOrder.size())
5978 aPythonDump << "[ ";
5979 // convert shape indeces into interfaces
5980 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5981 aResSubSet->length(aSubOrder.size());
5982 TListOfInt::const_iterator subIt = aSubOrder.begin();
5984 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5985 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5987 SMESH::SMESH_subMesh_var subMesh =
5988 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5991 aPythonDump << ", ";
5992 aPythonDump << subMesh;
5994 aResSubSet[ j++ ] = subMesh;
5997 aPythonDump << " ]";
5999 theResOrder[ listIndx++ ] = aResSubSet;
6001 // correct number of lists
6002 theResOrder.length( listIndx );
6005 // finilise python dump
6006 aPythonDump << " ]";
6007 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6011 //================================================================================
6013 // Implementation of SMESH_MeshPartDS
6015 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6016 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6018 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6019 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6021 _meshDS = mesh_i->GetImpl().GetMeshDS();
6023 SetPersistentId( _meshDS->GetPersistentId() );
6025 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6027 // <meshPart> is the whole mesh
6028 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6030 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6031 myGroupSet = _meshDS->GetGroups();
6036 SMESH::long_array_var anIDs = meshPart->GetIDs();
6037 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6038 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6040 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6041 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6042 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6047 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6048 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6049 if ( _elements[ e->GetType() ].insert( e ).second )
6052 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6053 while ( nIt->more() )
6055 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6056 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6063 ShapeToMesh( _meshDS->ShapeToMesh() );
6065 _meshDS = 0; // to enforce iteration on _elements and _nodes
6068 // -------------------------------------------------------------------------------------
6069 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6070 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6073 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6074 for ( ; partIt != meshPart.end(); ++partIt )
6075 if ( const SMDS_MeshElement * e = *partIt )
6076 if ( _elements[ e->GetType() ].insert( e ).second )
6079 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6080 while ( nIt->more() )
6082 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6083 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6089 // -------------------------------------------------------------------------------------
6090 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6092 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6094 typedef SMDS_SetIterator
6095 <const SMDS_MeshElement*,
6096 TIDSortedElemSet::const_iterator,
6097 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6098 SMDS_MeshElement::GeomFilter
6101 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6103 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6104 _elements[type].end(),
6105 SMDS_MeshElement::GeomFilter( geomType )));
6107 // -------------------------------------------------------------------------------------
6108 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6110 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6112 typedef SMDS_SetIterator
6113 <const SMDS_MeshElement*,
6114 TIDSortedElemSet::const_iterator,
6115 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6116 SMDS_MeshElement::EntityFilter
6119 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6121 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6122 _elements[type].end(),
6123 SMDS_MeshElement::EntityFilter( entity )));
6125 // -------------------------------------------------------------------------------------
6126 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6128 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6129 if ( type == SMDSAbs_All && !_meshDS )
6131 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6133 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6134 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6136 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6138 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6139 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6141 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6142 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6144 // -------------------------------------------------------------------------------------
6145 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6146 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6148 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6149 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6150 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6152 // -------------------------------------------------------------------------------------
6153 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6154 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6155 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6156 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6157 #undef _GET_ITER_DEFINE
6159 // END Implementation of SMESH_MeshPartDS
6161 //================================================================================