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 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
113 _id = _idGenerator++;
116 _previewEditor = NULL;
121 //=============================================================================
125 //=============================================================================
127 SMESH_Mesh_i::~SMESH_Mesh_i()
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
132 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
134 aGroup->UnRegister();
135 SMESH::SMESH_GroupBase_var( itGr->second );
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
142 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
144 aSubMesh->UnRegister();
145 SMESH::SMESH_subMesh_var( itSM->second );
147 _mapSubMeshIor.clear();
149 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
153 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
154 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
157 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
161 // clear cashed shapes if no more meshes remain; (the cash is blame,
162 // together with publishing, of spent time increasing in issue 22874)
163 if ( _impl->NbMeshes() == 1 )
164 _gen_i->GetShapeReader()->ClearClientBuffer();
166 delete _editor; _editor = NULL;
167 delete _previewEditor; _previewEditor = NULL;
168 delete _impl; _impl = NULL;
169 delete _preMeshInfo; _preMeshInfo = NULL;
172 //=============================================================================
176 * Associates <this> mesh with <theShape> and puts a reference
177 * to <theShape> into the current study;
178 * the previous shape is substituted by the new one.
180 //=============================================================================
182 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
183 throw (SALOME::SALOME_Exception)
185 Unexpect aCatch(SALOME_SalomeException);
187 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
189 catch(SALOME_Exception & S_ex) {
190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
192 // to track changes of GEOM groups
193 SMESH::SMESH_Mesh_var mesh = _this();
194 addGeomGroupData( theShapeObject, mesh );
195 if ( !CORBA::is_nil( theShapeObject ))
196 _mainShapeTick = theShapeObject->GetTick();
199 //================================================================================
201 * \brief return true if mesh has a shape to build a shape on
203 //================================================================================
205 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
206 throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 res = _impl->HasShapeToMesh();
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
219 //=======================================================================
220 //function : GetShapeToMesh
222 //=======================================================================
224 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
225 throw (SALOME::SALOME_Exception)
227 Unexpect aCatch(SALOME_SalomeException);
228 GEOM::GEOM_Object_var aShapeObj;
230 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
233 aShapeObj = _gen_i->ShapeToGeomObject( S );
234 if ( aShapeObj->_is_nil() )
236 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
237 // find GEOM_Object by entry (IPAL52735)
238 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
239 for ( ; data != _geomGroupData.end(); ++data )
240 if ( data->_smeshObject->_is_equivalent( _this() ))
242 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
243 if ( study->_is_nil() ) break;
244 SALOMEDS::SObject_wrap so = study->FindObjectID( data->_groupEntry.c_str() );
245 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
246 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
252 catch(SALOME_Exception & S_ex) {
253 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
255 return aShapeObj._retn();
258 //================================================================================
260 * \brief Return false if the mesh is not yet fully loaded from the study file
262 //================================================================================
264 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
266 Unexpect aCatch(SALOME_SalomeException);
267 return !_preMeshInfo;
270 //================================================================================
272 * \brief Load full mesh data from the study file
274 //================================================================================
276 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
278 Unexpect aCatch(SALOME_SalomeException);
280 _preMeshInfo->FullLoadFromFile();
283 //================================================================================
285 * \brief Remove all nodes and elements
287 //================================================================================
289 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
291 Unexpect aCatch(SALOME_SalomeException);
293 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
297 //CheckGeomGroupModif(); // issue 20145
299 catch(SALOME_Exception & S_ex) {
300 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
303 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
306 //================================================================================
308 * \brief Remove all nodes and elements for indicated shape
310 //================================================================================
312 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
313 throw (SALOME::SALOME_Exception)
315 Unexpect aCatch(SALOME_SalomeException);
317 _preMeshInfo->FullLoadFromFile();
320 _impl->ClearSubMesh( ShapeID );
322 catch(SALOME_Exception & S_ex) {
323 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
325 _impl->GetMeshDS()->Modified();
327 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
330 //=============================================================================
332 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
334 //=============================================================================
336 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
338 SMESH::DriverMED_ReadStatus res;
341 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
342 res = SMESH::DRS_OK; break;
343 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
344 res = SMESH::DRS_EMPTY; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
346 res = SMESH::DRS_WARN_RENUMBER; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
348 res = SMESH::DRS_WARN_SKIP_ELEM; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
350 res = SMESH::DRS_WARN_DESCENDING; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
353 res = SMESH::DRS_FAIL; break;
358 //=============================================================================
360 * Convert ::SMESH_ComputeError to SMESH::ComputeError
362 //=============================================================================
364 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
366 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
367 errVar->subShapeID = -1;
368 errVar->hasBadMesh = false;
370 if ( !errorPtr || errorPtr->IsOK() )
372 errVar->code = SMESH::COMPERR_OK;
376 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
377 errVar->comment = errorPtr->myComment.c_str();
379 return errVar._retn();
382 //=============================================================================
386 * Imports mesh data from MED file
388 //=============================================================================
390 SMESH::DriverMED_ReadStatus
391 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
392 throw ( SALOME::SALOME_Exception )
394 Unexpect aCatch(SALOME_SalomeException);
397 status = _impl->MEDToMesh( theFileName, theMeshName );
399 catch( SALOME_Exception& S_ex ) {
400 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
403 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
406 CreateGroupServants();
408 int major, minor, release;
409 major = minor = release = 0;
410 MED::GetMEDVersion(theFileName, major, minor, release);
411 _medFileInfo = new SMESH::MedFileInfo();
412 _medFileInfo->fileName = theFileName;
413 _medFileInfo->fileSize = 0;
414 _medFileInfo->major = major;
415 _medFileInfo->minor = minor;
416 _medFileInfo->release = release;
417 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
419 return ConvertDriverMEDReadStatus(status);
422 //================================================================================
424 * \brief Imports mesh data from the CGNS file
426 //================================================================================
428 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
429 const int theMeshIndex,
430 std::string& theMeshName )
431 throw ( SALOME::SALOME_Exception )
433 Unexpect aCatch(SALOME_SalomeException);
436 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
438 catch( SALOME_Exception& S_ex ) {
439 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
442 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
445 CreateGroupServants();
447 return ConvertDriverMEDReadStatus(status);
450 //=============================================================================
454 * Imports mesh data from MED file
456 //=============================================================================
458 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
459 throw ( SALOME::SALOME_Exception )
463 // Read mesh with name = <theMeshName> into SMESH_Mesh
464 _impl->UNVToMesh( theFileName );
466 CreateGroupServants();
468 SMESH_CATCH( SMESH::throwCorbaException );
473 //=============================================================================
477 * Imports mesh data from STL file
479 //=============================================================================
480 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
481 throw ( SALOME::SALOME_Exception )
485 // Read mesh with name = <theMeshName> into SMESH_Mesh
486 _impl->STLToMesh( theFileName );
488 SMESH_CATCH( SMESH::throwCorbaException );
493 //================================================================================
495 * \brief Function used in SMESH_CATCH by ImportGMFFile()
497 //================================================================================
501 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
503 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
507 //================================================================================
509 * \brief Imports data from a GMF file and returns an error description
511 //================================================================================
513 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
514 bool theMakeRequiredGroups )
515 throw (SALOME::SALOME_Exception)
517 SMESH_ComputeErrorPtr error;
520 #define SMESH_CAUGHT error =
523 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
525 SMESH_CATCH( exceptionToComputeError );
529 CreateGroupServants();
531 return ConvertComputeError( error );
534 //=============================================================================
538 //=============================================================================
540 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
542 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
543 (SMESH_Hypothesis::Hypothesis_Status theStatus)
546 RETURNCASE( HYP_OK );
547 RETURNCASE( HYP_MISSING );
548 RETURNCASE( HYP_CONCURENT );
549 RETURNCASE( HYP_BAD_PARAMETER );
550 RETURNCASE( HYP_HIDDEN_ALGO );
551 RETURNCASE( HYP_HIDING_ALGO );
552 RETURNCASE( HYP_UNKNOWN_FATAL );
553 RETURNCASE( HYP_INCOMPATIBLE );
554 RETURNCASE( HYP_NOTCONFORM );
555 RETURNCASE( HYP_ALREADY_EXIST );
556 RETURNCASE( HYP_BAD_DIM );
557 RETURNCASE( HYP_BAD_SUBSHAPE );
558 RETURNCASE( HYP_BAD_GEOMETRY );
559 RETURNCASE( HYP_NEED_SHAPE );
560 RETURNCASE( HYP_INCOMPAT_HYPS );
563 return SMESH::HYP_UNKNOWN_FATAL;
566 //=============================================================================
570 * calls internal addHypothesis() and then adds a reference to <anHyp> under
571 * the SObject actually having a reference to <aSubShape>.
572 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
574 //=============================================================================
576 SMESH::Hypothesis_Status
577 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
578 SMESH::SMESH_Hypothesis_ptr anHyp,
579 CORBA::String_out anErrorText)
580 throw(SALOME::SALOME_Exception)
582 Unexpect aCatch(SALOME_SalomeException);
584 _preMeshInfo->ForgetOrLoad();
587 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
588 anErrorText = error.c_str();
590 SMESH::SMESH_Mesh_var mesh( _this() );
591 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
593 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
594 _gen_i->AddHypothesisToShape( study, 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 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
680 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
682 // Update Python script
683 if(_impl->HasShapeToMesh())
684 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
685 << aSubShape << ", " << anHyp << " )";
687 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
690 return ConvertHypothesisStatus(status);
693 //=============================================================================
697 //=============================================================================
699 SMESH_Hypothesis::Hypothesis_Status
700 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
701 SMESH::SMESH_Hypothesis_ptr anHyp)
703 if(MYDEBUG) MESSAGE("removeHypothesis()");
705 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
706 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
708 if (CORBA::is_nil( anHyp ))
709 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
711 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
714 TopoDS_Shape myLocSubShape;
715 //use PseudoShape in case if mesh has no shape
716 if( _impl->HasShapeToMesh() )
717 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
719 myLocSubShape = _impl->GetShapeToMesh();
721 const int hypId = anHyp->GetId();
722 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
723 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
725 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
729 catch(SALOME_Exception & S_ex)
731 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
736 //=============================================================================
740 //=============================================================================
742 SMESH::ListOfHypothesis *
743 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
744 throw(SALOME::SALOME_Exception)
746 Unexpect aCatch(SALOME_SalomeException);
747 if (MYDEBUG) MESSAGE("GetHypothesisList");
748 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
749 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
751 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
754 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
755 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
756 myLocSubShape = _impl->GetShapeToMesh();
757 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
758 int i = 0, n = aLocalList.size();
761 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
762 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
763 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
765 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
766 if ( id_hypptr != _mapHypo.end() )
767 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
771 catch(SALOME_Exception & S_ex) {
772 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
775 return aList._retn();
778 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
780 Unexpect aCatch(SALOME_SalomeException);
781 if (MYDEBUG) MESSAGE("GetSubMeshes");
783 SMESH::submesh_array_var aList = new SMESH::submesh_array();
786 TPythonDump aPythonDump;
787 if ( !_mapSubMeshIor.empty() )
791 aList->length( _mapSubMeshIor.size() );
793 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
794 for ( ; it != _mapSubMeshIor.end(); it++ ) {
795 if ( CORBA::is_nil( it->second )) continue;
796 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
798 if (i > 1) aPythonDump << ", ";
799 aPythonDump << it->second;
803 catch(SALOME_Exception & S_ex) {
804 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
807 // Update Python script
808 if ( !_mapSubMeshIor.empty() )
809 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
811 return aList._retn();
814 //=============================================================================
818 //=============================================================================
820 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
821 const char* theName )
822 throw(SALOME::SALOME_Exception)
824 Unexpect aCatch(SALOME_SalomeException);
825 if (CORBA::is_nil(aSubShape))
826 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
828 SMESH::SMESH_subMesh_var subMesh;
829 SMESH::SMESH_Mesh_var aMesh = _this();
831 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
833 //Get or Create the SMESH_subMesh object implementation
835 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
837 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
839 TopoDS_Iterator it( myLocSubShape );
841 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
843 subMesh = getSubMesh( subMeshId );
845 // create a new subMesh object servant if there is none for the shape
846 if ( subMesh->_is_nil() )
847 subMesh = createSubMesh( aSubShape );
848 if ( _gen_i->CanPublishInStudy( subMesh ))
850 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
851 SALOMEDS::SObject_wrap aSO =
852 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
853 if ( !aSO->_is_nil()) {
854 // Update Python script
855 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
856 << aSubShape << ", '" << theName << "' )";
860 catch(SALOME_Exception & S_ex) {
861 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
863 return subMesh._retn();
866 //=============================================================================
870 //=============================================================================
872 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
873 throw (SALOME::SALOME_Exception)
877 if ( theSubMesh->_is_nil() )
880 GEOM::GEOM_Object_var aSubShape;
881 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
882 if ( !aStudy->_is_nil() ) {
883 // Remove submesh's SObject
884 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
885 if ( !anSO->_is_nil() ) {
886 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
887 SALOMEDS::SObject_wrap anObj, aRef;
888 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
889 anObj->ReferencedObject( aRef.inout() ))
891 CORBA::Object_var obj = aRef->GetObject();
892 aSubShape = GEOM::GEOM_Object::_narrow( obj );
894 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
895 // aSubShape = theSubMesh->GetSubShape();
897 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
898 builder->RemoveObjectWithChildren( anSO );
900 // Update Python script
901 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
905 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
907 _preMeshInfo->ForgetOrLoad();
909 SMESH_CATCH( SMESH::throwCorbaException );
912 //=============================================================================
916 //=============================================================================
918 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
919 const char* theName )
920 throw(SALOME::SALOME_Exception)
922 Unexpect aCatch(SALOME_SalomeException);
924 _preMeshInfo->FullLoadFromFile();
926 SMESH::SMESH_Group_var aNewGroup =
927 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
929 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
931 SMESH::SMESH_Mesh_var mesh = _this();
932 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
933 SALOMEDS::SObject_wrap aSO =
934 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
935 if ( !aSO->_is_nil())
936 // Update Python script
937 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
938 << theElemType << ", '" << theName << "' )";
940 return aNewGroup._retn();
943 //=============================================================================
947 //=============================================================================
948 SMESH::SMESH_GroupOnGeom_ptr
949 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
951 GEOM::GEOM_Object_ptr theGeomObj)
952 throw(SALOME::SALOME_Exception)
954 Unexpect aCatch(SALOME_SalomeException);
956 _preMeshInfo->FullLoadFromFile();
958 SMESH::SMESH_GroupOnGeom_var aNewGroup;
960 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
961 if ( !aShape.IsNull() )
964 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
966 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
968 SMESH::SMESH_Mesh_var mesh = _this();
969 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
970 SALOMEDS::SObject_wrap aSO =
971 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
972 if ( !aSO->_is_nil())
973 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
974 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
978 return aNewGroup._retn();
981 //================================================================================
983 * \brief Creates a group whose contents is defined by filter
984 * \param theElemType - group type
985 * \param theName - group name
986 * \param theFilter - the filter
987 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
989 //================================================================================
991 SMESH::SMESH_GroupOnFilter_ptr
992 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
994 SMESH::Filter_ptr theFilter )
995 throw (SALOME::SALOME_Exception)
997 Unexpect aCatch(SALOME_SalomeException);
999 _preMeshInfo->FullLoadFromFile();
1001 if ( CORBA::is_nil( theFilter ))
1002 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1004 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1006 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1008 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1009 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1012 if ( !aNewGroup->_is_nil() )
1013 aNewGroup->SetFilter( theFilter );
1015 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1017 SMESH::SMESH_Mesh_var mesh = _this();
1018 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1019 SALOMEDS::SObject_wrap aSO =
1020 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1022 if ( !aSO->_is_nil())
1023 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1024 << theElemType << ", '" << theName << "', " << theFilter << " )";
1026 return aNewGroup._retn();
1029 //=============================================================================
1033 //=============================================================================
1035 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1036 throw (SALOME::SALOME_Exception)
1038 if ( theGroup->_is_nil() )
1043 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1047 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1048 if ( !aStudy->_is_nil() )
1050 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1051 if ( !aGroupSO->_is_nil() )
1053 // Update Python script
1054 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1056 // Remove group's SObject
1057 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1058 builder->RemoveObjectWithChildren( aGroupSO );
1061 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1063 // Remove the group from SMESH data structures
1064 removeGroup( aGroup->GetLocalID() );
1066 SMESH_CATCH( SMESH::throwCorbaException );
1069 //=============================================================================
1071 * Remove group with its contents
1073 //=============================================================================
1075 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1076 throw (SALOME::SALOME_Exception)
1080 _preMeshInfo->FullLoadFromFile();
1082 if ( theGroup->_is_nil() )
1085 vector<int> nodeIds; // to remove nodes becoming free
1086 if ( !theGroup->IsEmpty() )
1088 CORBA::Long elemID = theGroup->GetID( 1 );
1089 int nbElemNodes = GetElemNbNodes( elemID );
1090 if ( nbElemNodes > 0 )
1091 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1095 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1096 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1097 while ( elemIt->more() )
1099 const SMDS_MeshElement* e = elemIt->next();
1101 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1102 while ( nIt->more() )
1103 nodeIds.push_back( nIt->next()->GetID() );
1105 _impl->GetMeshDS()->RemoveElement( e );
1108 // Remove free nodes
1109 if ( theGroup->GetType() != SMESH::NODE )
1110 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1111 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1112 if ( n->NbInverseElements() == 0 )
1113 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1115 TPythonDump pyDump; // Supress dump from RemoveGroup()
1117 // Update Python script (theGroup must be alive for this)
1118 pyDump << SMESH::SMESH_Mesh_var(_this())
1119 << ".RemoveGroupWithContents( " << theGroup << " )";
1122 RemoveGroup( theGroup );
1124 SMESH_CATCH( SMESH::throwCorbaException );
1127 //================================================================================
1129 * \brief Get the list of groups existing in the mesh
1130 * \retval SMESH::ListOfGroups * - list of groups
1132 //================================================================================
1134 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1136 Unexpect aCatch(SALOME_SalomeException);
1137 if (MYDEBUG) MESSAGE("GetGroups");
1139 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1142 TPythonDump aPythonDump;
1143 if ( !_mapGroups.empty() )
1145 aPythonDump << "[ ";
1147 aList->length( _mapGroups.size() );
1149 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1150 for ( ; it != _mapGroups.end(); it++ ) {
1151 if ( CORBA::is_nil( it->second )) continue;
1152 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1154 if (i > 1) aPythonDump << ", ";
1155 aPythonDump << it->second;
1159 catch(SALOME_Exception & S_ex) {
1160 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1162 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1164 return aList._retn();
1167 //=============================================================================
1169 * Get number of groups existing in the mesh
1171 //=============================================================================
1173 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1175 Unexpect aCatch(SALOME_SalomeException);
1176 return _mapGroups.size();
1179 //=============================================================================
1181 * New group including all mesh elements present in initial groups is created.
1183 //=============================================================================
1185 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1186 SMESH::SMESH_GroupBase_ptr theGroup2,
1187 const char* theName )
1188 throw (SALOME::SALOME_Exception)
1190 SMESH::SMESH_Group_var aResGrp;
1194 _preMeshInfo->FullLoadFromFile();
1196 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1197 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1199 if ( theGroup1->GetType() != theGroup2->GetType() )
1200 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1205 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1206 if ( aResGrp->_is_nil() )
1207 return SMESH::SMESH_Group::_nil();
1209 aResGrp->AddFrom( theGroup1 );
1210 aResGrp->AddFrom( theGroup2 );
1212 // Update Python script
1213 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1214 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1216 SMESH_CATCH( SMESH::throwCorbaException );
1218 return aResGrp._retn();
1221 //=============================================================================
1223 * \brief New group including all mesh elements present in initial groups is created.
1224 * \param theGroups list of groups
1225 * \param theName name of group to be created
1226 * \return pointer to the new group
1228 //=============================================================================
1230 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1231 const char* theName )
1232 throw (SALOME::SALOME_Exception)
1234 SMESH::SMESH_Group_var aResGrp;
1237 _preMeshInfo->FullLoadFromFile();
1240 return SMESH::SMESH_Group::_nil();
1245 SMESH::ElementType aType = SMESH::ALL;
1246 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1248 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1249 if ( CORBA::is_nil( aGrp ) )
1251 if ( aType == SMESH::ALL )
1252 aType = aGrp->GetType();
1253 else if ( aType != aGrp->GetType() )
1254 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1257 if ( aType == SMESH::ALL )
1258 return SMESH::SMESH_Group::_nil();
1263 aResGrp = CreateGroup( aType, theName );
1264 if ( aResGrp->_is_nil() )
1265 return SMESH::SMESH_Group::_nil();
1267 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1268 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1270 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1271 if ( !CORBA::is_nil( aGrp ) )
1273 aResGrp->AddFrom( aGrp );
1274 if ( g > 0 ) pyDump << ", ";
1278 pyDump << " ], '" << theName << "' )";
1280 SMESH_CATCH( SMESH::throwCorbaException );
1282 return aResGrp._retn();
1285 //=============================================================================
1287 * New group is created. All mesh elements that are
1288 * present in both initial groups are added to the new one.
1290 //=============================================================================
1292 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1293 SMESH::SMESH_GroupBase_ptr theGroup2,
1294 const char* theName )
1295 throw (SALOME::SALOME_Exception)
1297 SMESH::SMESH_Group_var aResGrp;
1302 _preMeshInfo->FullLoadFromFile();
1304 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1305 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1307 if ( theGroup1->GetType() != theGroup2->GetType() )
1308 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1312 // Create Intersection
1313 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1314 if ( aResGrp->_is_nil() )
1315 return aResGrp._retn();
1317 SMESHDS_GroupBase* groupDS1 = 0;
1318 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1319 groupDS1 = grp_i->GetGroupDS();
1321 SMESHDS_GroupBase* groupDS2 = 0;
1322 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1323 groupDS2 = grp_i->GetGroupDS();
1325 SMESHDS_Group* resGroupDS = 0;
1326 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1327 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1329 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1331 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1332 while ( elemIt1->more() )
1334 const SMDS_MeshElement* e = elemIt1->next();
1335 if ( groupDS2->Contains( e ))
1336 resGroupDS->SMDSGroup().Add( e );
1339 // Update Python script
1340 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1341 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1343 SMESH_CATCH( SMESH::throwCorbaException );
1345 return aResGrp._retn();
1348 //=============================================================================
1350 \brief Intersect list of groups. New group is created. All mesh elements that
1351 are present in all initial groups simultaneously are added to the new one.
1352 \param theGroups list of groups
1353 \param theName name of group to be created
1354 \return pointer on the group
1356 //=============================================================================
1357 SMESH::SMESH_Group_ptr
1358 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1359 const char* theName )
1360 throw (SALOME::SALOME_Exception)
1362 SMESH::SMESH_Group_var aResGrp;
1367 _preMeshInfo->FullLoadFromFile();
1370 return SMESH::SMESH_Group::_nil();
1372 // check types and get SMESHDS_GroupBase's
1373 SMESH::ElementType aType = SMESH::ALL;
1374 vector< SMESHDS_GroupBase* > groupVec;
1375 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1377 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1378 if ( CORBA::is_nil( aGrp ) )
1380 if ( aType == SMESH::ALL )
1381 aType = aGrp->GetType();
1382 else if ( aType != aGrp->GetType() )
1383 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1386 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1387 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1389 if ( grpDS->IsEmpty() )
1394 groupVec.push_back( grpDS );
1397 if ( aType == SMESH::ALL ) // all groups are nil
1398 return SMESH::SMESH_Group::_nil();
1403 aResGrp = CreateGroup( aType, theName );
1405 SMESHDS_Group* resGroupDS = 0;
1406 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1407 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1408 if ( !resGroupDS || groupVec.empty() )
1409 return aResGrp._retn();
1412 size_t i, nb = groupVec.size();
1413 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1414 while ( elemIt1->more() )
1416 const SMDS_MeshElement* e = elemIt1->next();
1418 for ( i = 1; ( i < nb && inAll ); ++i )
1419 inAll = groupVec[i]->Contains( e );
1422 resGroupDS->SMDSGroup().Add( e );
1425 // Update Python script
1426 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1427 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1429 SMESH_CATCH( SMESH::throwCorbaException );
1431 return aResGrp._retn();
1434 //=============================================================================
1436 * New group is created. All mesh elements that are present in
1437 * a main group but is not present in a tool group are added to the new one
1439 //=============================================================================
1441 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1442 SMESH::SMESH_GroupBase_ptr theGroup2,
1443 const char* theName )
1444 throw (SALOME::SALOME_Exception)
1446 SMESH::SMESH_Group_var aResGrp;
1451 _preMeshInfo->FullLoadFromFile();
1453 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1454 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1456 if ( theGroup1->GetType() != theGroup2->GetType() )
1457 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1461 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1462 if ( aResGrp->_is_nil() )
1463 return aResGrp._retn();
1465 SMESHDS_GroupBase* groupDS1 = 0;
1466 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1467 groupDS1 = grp_i->GetGroupDS();
1469 SMESHDS_GroupBase* groupDS2 = 0;
1470 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1471 groupDS2 = grp_i->GetGroupDS();
1473 SMESHDS_Group* resGroupDS = 0;
1474 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1475 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1477 if ( groupDS1 && groupDS2 && resGroupDS )
1479 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1480 while ( elemIt1->more() )
1482 const SMDS_MeshElement* e = elemIt1->next();
1483 if ( !groupDS2->Contains( e ))
1484 resGroupDS->SMDSGroup().Add( e );
1487 // Update Python script
1488 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1489 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1491 SMESH_CATCH( SMESH::throwCorbaException );
1493 return aResGrp._retn();
1496 //=============================================================================
1498 \brief Cut lists of groups. New group is created. All mesh elements that are
1499 present in main groups but do not present in tool groups are added to the new one
1500 \param theMainGroups list of main groups
1501 \param theToolGroups list of tool groups
1502 \param theName name of group to be created
1503 \return pointer on the group
1505 //=============================================================================
1506 SMESH::SMESH_Group_ptr
1507 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1508 const SMESH::ListOfGroups& theToolGroups,
1509 const char* theName )
1510 throw (SALOME::SALOME_Exception)
1512 SMESH::SMESH_Group_var aResGrp;
1517 _preMeshInfo->FullLoadFromFile();
1520 return SMESH::SMESH_Group::_nil();
1522 // check types and get SMESHDS_GroupBase's
1523 SMESH::ElementType aType = SMESH::ALL;
1524 vector< SMESHDS_GroupBase* > toolGroupVec;
1525 vector< SMDS_ElemIteratorPtr > mainIterVec;
1527 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1529 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1530 if ( CORBA::is_nil( aGrp ) )
1532 if ( aType == SMESH::ALL )
1533 aType = aGrp->GetType();
1534 else if ( aType != aGrp->GetType() )
1535 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1537 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1538 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1539 if ( !grpDS->IsEmpty() )
1540 mainIterVec.push_back( grpDS->GetElements() );
1542 if ( aType == SMESH::ALL ) // all main groups are nil
1543 return SMESH::SMESH_Group::_nil();
1544 if ( mainIterVec.empty() ) // all main groups are empty
1545 return aResGrp._retn();
1547 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1549 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1550 if ( CORBA::is_nil( aGrp ) )
1552 if ( aType != aGrp->GetType() )
1553 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1555 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1556 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1557 toolGroupVec.push_back( grpDS );
1563 aResGrp = CreateGroup( aType, theName );
1565 SMESHDS_Group* resGroupDS = 0;
1566 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1567 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1569 return aResGrp._retn();
1572 size_t i, nb = toolGroupVec.size();
1573 SMDS_ElemIteratorPtr mainElemIt
1574 ( new SMDS_IteratorOnIterators
1575 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1576 while ( mainElemIt->more() )
1578 const SMDS_MeshElement* e = mainElemIt->next();
1580 for ( i = 0; ( i < nb && !isIn ); ++i )
1581 isIn = toolGroupVec[i]->Contains( e );
1584 resGroupDS->SMDSGroup().Add( e );
1587 // Update Python script
1588 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1589 << ".CutListOfGroups( " << theMainGroups << ", "
1590 << theToolGroups << ", '" << theName << "' )";
1592 SMESH_CATCH( SMESH::throwCorbaException );
1594 return aResGrp._retn();
1597 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1599 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1600 bool & toStopChecking )
1602 toStopChecking = ( nbCommon < nbChecked );
1603 return nbCommon == nbNodes;
1605 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1606 bool & toStopChecking )
1608 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1609 return nbCommon == nbCorners;
1611 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1612 bool & toStopChecking )
1614 return nbCommon > 0;
1616 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1617 bool & toStopChecking )
1619 return nbCommon >= (nbNodes+1) / 2;
1623 //=============================================================================
1625 * Create a group of entities basing on nodes of other groups.
1626 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1627 * \param [in] anElemType - a type of elements to include to the new group.
1628 * \param [in] theName - a name of the new group.
1629 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1630 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1631 * new group provided that it is based on nodes of an element of \a aListOfGroups
1632 * \return SMESH_Group - the created group
1634 // IMP 19939, bug 22010, IMP 22635
1635 //=============================================================================
1637 SMESH::SMESH_Group_ptr
1638 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1639 SMESH::ElementType theElemType,
1640 const char* theName,
1641 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1642 CORBA::Boolean theUnderlyingOnly)
1643 throw (SALOME::SALOME_Exception)
1645 SMESH::SMESH_Group_var aResGrp;
1649 _preMeshInfo->FullLoadFromFile();
1651 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1653 if ( !theName || !aMeshDS )
1654 return SMESH::SMESH_Group::_nil();
1656 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1658 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1659 SMESH_Comment nbCoNoStr( "SMESH.");
1660 switch ( theNbCommonNodes ) {
1661 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1662 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1663 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1664 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1665 default: return aResGrp._retn();
1667 int nbChecked, nbCommon, nbNodes, nbCorners;
1673 aResGrp = CreateGroup( theElemType, theName );
1674 if ( aResGrp->_is_nil() )
1675 return SMESH::SMESH_Group::_nil();
1677 SMESHDS_GroupBase* groupBaseDS =
1678 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1679 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1681 vector<bool> isNodeInGroups;
1683 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1685 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1686 if ( CORBA::is_nil( aGrp ) )
1688 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1689 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1692 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1693 if ( !elIt ) continue;
1695 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1697 while ( elIt->more() ) {
1698 const SMDS_MeshElement* el = elIt->next();
1699 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1700 while ( nIt->more() )
1701 resGroupCore.Add( nIt->next() );
1704 // get elements of theElemType based on nodes of every element of group
1705 else if ( theUnderlyingOnly )
1707 while ( elIt->more() )
1709 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1710 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1711 TIDSortedElemSet checkedElems;
1712 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1713 while ( nIt->more() )
1715 const SMDS_MeshNode* n = nIt->next();
1716 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1717 // check nodes of elements of theElemType around el
1718 while ( elOfTypeIt->more() )
1720 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1721 if ( !checkedElems.insert( elOfType ).second ) continue;
1722 nbNodes = elOfType->NbNodes();
1723 nbCorners = elOfType->NbCornerNodes();
1725 bool toStopChecking = false;
1726 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1727 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1728 if ( elNodes.count( nIt2->next() ) &&
1729 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1731 resGroupCore.Add( elOfType );
1738 // get all nodes of elements of groups
1741 while ( elIt->more() )
1743 const SMDS_MeshElement* el = elIt->next(); // an element of group
1744 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1745 while ( nIt->more() )
1747 const SMDS_MeshNode* n = nIt->next();
1748 if ( n->GetID() >= (int) isNodeInGroups.size() )
1749 isNodeInGroups.resize( n->GetID() + 1, false );
1750 isNodeInGroups[ n->GetID() ] = true;
1756 // Get elements of theElemType based on a certain number of nodes of elements of groups
1757 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1759 const SMDS_MeshNode* n;
1760 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1761 const int isNodeInGroupsSize = isNodeInGroups.size();
1762 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1764 if ( !isNodeInGroups[ iN ] ||
1765 !( n = aMeshDS->FindNode( iN )))
1768 // check nodes of elements of theElemType around n
1769 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1770 while ( elOfTypeIt->more() )
1772 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1773 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1778 nbNodes = elOfType->NbNodes();
1779 nbCorners = elOfType->NbCornerNodes();
1781 bool toStopChecking = false;
1782 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1783 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1785 const int nID = nIt->next()->GetID();
1786 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1787 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1789 resGroupCore.Add( elOfType );
1797 // Update Python script
1798 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1799 << ".CreateDimGroup( "
1800 << theGroups << ", " << theElemType << ", '" << theName << "', "
1801 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1803 SMESH_CATCH( SMESH::throwCorbaException );
1805 return aResGrp._retn();
1808 //================================================================================
1810 * \brief Remember GEOM group data
1812 //================================================================================
1814 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1815 CORBA::Object_ptr theSmeshObj)
1817 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1820 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1821 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1822 if ( groupSO->_is_nil() )
1825 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1826 GEOM::GEOM_IGroupOperations_wrap groupOp =
1827 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1828 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1831 _geomGroupData.push_back( TGeomGroupData() );
1832 TGeomGroupData & groupData = _geomGroupData.back();
1834 CORBA::String_var entry = groupSO->GetID();
1835 groupData._groupEntry = entry.in();
1837 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1838 groupData._indices.insert( ids[i] );
1840 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1841 // shape index in SMESHDS
1842 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1843 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1846 //================================================================================
1848 * Remove GEOM group data relating to removed smesh object
1850 //================================================================================
1852 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1854 list<TGeomGroupData>::iterator
1855 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1856 for ( ; data != dataEnd; ++data ) {
1857 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1858 _geomGroupData.erase( data );
1864 //================================================================================
1866 * \brief Return new group contents if it has been changed and update group data
1868 //================================================================================
1870 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1872 TopoDS_Shape newShape;
1875 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1876 if ( study->_is_nil() ) return newShape; // means "not changed"
1877 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1878 if ( !groupSO->_is_nil() )
1880 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1881 if ( CORBA::is_nil( groupObj )) return newShape;
1882 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1884 // get indices of group items
1885 set<int> curIndices;
1886 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1887 GEOM::GEOM_IGroupOperations_wrap groupOp =
1888 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1889 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1890 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1891 curIndices.insert( ids[i] );
1893 if ( groupData._indices == curIndices )
1894 return newShape; // group not changed
1897 groupData._indices = curIndices;
1899 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1900 if ( !geomClient ) return newShape;
1901 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1902 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1903 newShape = _gen_i->GeomObjectToShape( geomGroup );
1906 if ( newShape.IsNull() ) {
1907 // geom group becomes empty - return empty compound
1908 TopoDS_Compound compound;
1909 BRep_Builder().MakeCompound(compound);
1910 newShape = compound;
1917 //-----------------------------------------------------------------------------
1919 * \brief Storage of shape and index used in CheckGeomGroupModif()
1921 struct TIndexedShape
1924 TopoDS_Shape _shape;
1925 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1927 //-----------------------------------------------------------------------------
1929 * \brief Data to re-create a group on geometry
1931 struct TGroupOnGeomData
1935 SMDSAbs_ElementType _type;
1937 Quantity_Color _color;
1941 //=============================================================================
1943 * \brief Update data if geometry changes
1947 //=============================================================================
1949 void SMESH_Mesh_i::CheckGeomModif()
1951 if ( !_impl->HasShapeToMesh() ) return;
1953 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1954 if ( study->_is_nil() ) return;
1956 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1957 //if ( mainGO->_is_nil() ) return;
1959 // Update after group modification
1961 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1962 called by other mesh (IPAL52735) */
1963 mainGO->GetType() == GEOM_GROUP ||
1964 mainGO->GetTick() == _mainShapeTick )
1966 CheckGeomGroupModif();
1970 // Update after shape transformation like Translate
1972 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1973 if ( !geomClient ) return;
1974 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1975 if ( geomGen->_is_nil() ) return;
1977 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1978 geomClient->RemoveShapeFromBuffer( ior.in() );
1980 // Update data taking into account that
1981 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1984 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1985 if ( newShape.IsNull() )
1988 _mainShapeTick = mainGO->GetTick();
1990 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1992 // store data of groups on geometry
1993 vector< TGroupOnGeomData > groupsData;
1994 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1995 groupsData.reserve( groups.size() );
1996 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1997 for ( ; g != groups.end(); ++g )
1998 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2000 TGroupOnGeomData data;
2001 data._oldID = group->GetID();
2002 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2003 data._type = group->GetType();
2004 data._name = group->GetStoreName();
2005 data._color = group->GetColor();
2006 groupsData.push_back( data );
2008 // store assigned hypotheses
2009 vector< pair< int, THypList > > ids2Hyps;
2010 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2011 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2013 const TopoDS_Shape& s = s2hyps.Key();
2014 const THypList& hyps = s2hyps.ChangeValue();
2015 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2018 // change shape to mesh
2019 int oldNbSubShapes = meshDS->MaxShapeIndex();
2020 _impl->ShapeToMesh( TopoDS_Shape() );
2021 _impl->ShapeToMesh( newShape );
2023 // re-add shapes of geom groups
2024 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2025 for ( ; data != _geomGroupData.end(); ++data )
2027 TopoDS_Shape newShape = newGroupShape( *data );
2028 if ( !newShape.IsNull() )
2030 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2032 TopoDS_Compound compound;
2033 BRep_Builder().MakeCompound( compound );
2034 BRep_Builder().Add( compound, newShape );
2035 newShape = compound;
2037 _impl->GetSubMesh( newShape );
2040 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2041 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2042 SALOME::INTERNAL_ERROR );
2044 // re-assign hypotheses
2045 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2047 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2048 const THypList& hyps = ids2Hyps[i].second;
2049 THypList::const_iterator h = hyps.begin();
2050 for ( ; h != hyps.end(); ++h )
2051 _impl->AddHypothesis( s, (*h)->GetID() );
2055 for ( size_t i = 0; i < groupsData.size(); ++i )
2057 const TGroupOnGeomData& data = groupsData[i];
2059 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2060 if ( i2g == _mapGroups.end() ) continue;
2062 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2063 if ( !gr_i ) continue;
2066 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2067 meshDS->IndexToShape( data._shapeID ));
2070 _mapGroups.erase( i2g );
2074 g->GetGroupDS()->SetColor( data._color );
2075 gr_i->changeLocalId( id );
2076 _mapGroups[ id ] = i2g->second;
2077 if ( data._oldID != id )
2078 _mapGroups.erase( i2g );
2082 // update _mapSubMesh
2083 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2084 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2085 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2089 //=============================================================================
2091 * \brief Update objects depending on changed geom groups
2093 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2094 * issue 0020210: Update of a smesh group after modification of the associated geom group
2096 //=============================================================================
2098 void SMESH_Mesh_i::CheckGeomGroupModif()
2100 if ( !_impl->HasShapeToMesh() ) return;
2102 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2103 if ( study->_is_nil() ) return;
2105 CORBA::Long nbEntities = NbNodes() + NbElements();
2107 // Check if group contents changed
2109 typedef map< string, TopoDS_Shape > TEntry2Geom;
2110 TEntry2Geom newGroupContents;
2112 list<TGeomGroupData>::iterator
2113 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2114 for ( ; data != dataEnd; ++data )
2116 pair< TEntry2Geom::iterator, bool > it_new =
2117 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2118 bool processedGroup = !it_new.second;
2119 TopoDS_Shape& newShape = it_new.first->second;
2120 if ( !processedGroup )
2121 newShape = newGroupShape( *data );
2122 if ( newShape.IsNull() )
2123 continue; // no changes
2126 _preMeshInfo->ForgetOrLoad();
2128 if ( processedGroup ) { // update group indices
2129 list<TGeomGroupData>::iterator data2 = data;
2130 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2131 data->_indices = data2->_indices;
2134 // Update SMESH objects according to new GEOM group contents
2136 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2137 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2139 int oldID = submesh->GetId();
2140 if ( !_mapSubMeshIor.count( oldID ))
2142 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2144 // update hypotheses
2145 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2146 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2147 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2149 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2150 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2152 // care of submeshes
2153 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2154 int newID = newSubmesh->GetId();
2155 if ( newID != oldID ) {
2156 _mapSubMesh [ newID ] = newSubmesh;
2157 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2158 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2159 _mapSubMesh. erase(oldID);
2160 _mapSubMesh_i. erase(oldID);
2161 _mapSubMeshIor.erase(oldID);
2162 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2167 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2168 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2169 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2171 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2173 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2174 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2175 ds->SetShape( newShape );
2180 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2181 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2183 // Remove groups and submeshes basing on removed sub-shapes
2185 TopTools_MapOfShape newShapeMap;
2186 TopoDS_Iterator shapeIt( newShape );
2187 for ( ; shapeIt.More(); shapeIt.Next() )
2188 newShapeMap.Add( shapeIt.Value() );
2190 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2191 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2193 if ( newShapeMap.Contains( shapeIt.Value() ))
2195 TopTools_IndexedMapOfShape oldShapeMap;
2196 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2197 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2199 const TopoDS_Shape& oldShape = oldShapeMap(i);
2200 int oldInd = meshDS->ShapeToIndex( oldShape );
2202 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2203 if ( i_smIor != _mapSubMeshIor.end() ) {
2204 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2207 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2208 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2210 // check if a group bases on oldInd shape
2211 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2212 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2213 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2214 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2216 RemoveGroup( i_grp->second ); // several groups can base on same shape
2217 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2222 // Reassign hypotheses and update groups after setting the new shape to mesh
2224 // collect anassigned hypotheses
2225 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2226 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2227 TShapeHypList assignedHyps;
2228 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2230 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2231 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2232 if ( !hyps.empty() ) {
2233 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2234 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2235 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2238 // collect shapes supporting groups
2239 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2240 TShapeTypeList groupData;
2241 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2242 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2243 for ( ; grIt != groups.end(); ++grIt )
2245 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2247 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2249 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2251 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2252 _impl->ShapeToMesh( newShape );
2254 // reassign hypotheses
2255 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2256 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2258 TIndexedShape& geom = indS_hyps->first;
2259 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2260 int oldID = geom._index;
2261 int newID = meshDS->ShapeToIndex( geom._shape );
2262 if ( oldID == 1 ) { // main shape
2264 geom._shape = newShape;
2268 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2269 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2270 // care of sub-meshes
2271 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2272 if ( newID != oldID ) {
2273 _mapSubMesh [ newID ] = newSubmesh;
2274 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2275 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2276 _mapSubMesh. erase(oldID);
2277 _mapSubMesh_i. erase(oldID);
2278 _mapSubMeshIor.erase(oldID);
2279 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2283 TShapeTypeList::iterator geomType = groupData.begin();
2284 for ( ; geomType != groupData.end(); ++geomType )
2286 const TIndexedShape& geom = geomType->first;
2287 int oldID = geom._index;
2288 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2291 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2292 CORBA::String_var name = groupSO->GetName();
2294 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2296 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2297 group_i->changeLocalId( newID );
2300 break; // everything has been updated
2303 } // loop on group data
2307 CORBA::Long newNbEntities = NbNodes() + NbElements();
2308 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2309 if ( newNbEntities != nbEntities )
2311 // Add all SObjects with icons to soToUpdateIcons
2312 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2314 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2315 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2316 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2318 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2319 i_gr != _mapGroups.end(); ++i_gr ) // groups
2320 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2323 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2324 for ( ; so != soToUpdateIcons.end(); ++so )
2325 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2328 //=============================================================================
2330 * \brief Create standalone group from a group on geometry or filter
2332 //=============================================================================
2334 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2335 throw (SALOME::SALOME_Exception)
2337 SMESH::SMESH_Group_var aGroup;
2342 _preMeshInfo->FullLoadFromFile();
2344 if ( theGroup->_is_nil() )
2345 return aGroup._retn();
2347 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2349 return aGroup._retn();
2351 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2353 const int anId = aGroupToRem->GetLocalID();
2354 if ( !_impl->ConvertToStandalone( anId ) )
2355 return aGroup._retn();
2356 removeGeomGroupData( theGroup );
2358 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2360 // remove old instance of group from own map
2361 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2362 _mapGroups.erase( anId );
2364 SALOMEDS::StudyBuilder_var builder;
2365 SALOMEDS::SObject_wrap aGroupSO;
2366 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2367 if ( !aStudy->_is_nil() ) {
2368 builder = aStudy->NewBuilder();
2369 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2370 if ( !aGroupSO->_is_nil() )
2372 // remove reference to geometry
2373 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2374 for ( ; chItr->More(); chItr->Next() )
2375 // Remove group's child SObject
2376 builder->RemoveObject( chItr->Value() );
2378 // Update Python script
2379 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2380 << ".ConvertToStandalone( " << aGroupSO << " )";
2382 // change icon of Group on Filter
2385 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2386 const int isEmpty = ( elemTypes->length() == 0 );
2389 SALOMEDS::GenericAttribute_wrap anAttr =
2390 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2391 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2392 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2398 // remember new group in own map
2399 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2400 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2402 // register CORBA object for persistence
2403 _gen_i->RegisterObject( aGroup );
2405 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2406 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2407 //aGroup->Register();
2408 aGroupToRem->UnRegister();
2410 SMESH_CATCH( SMESH::throwCorbaException );
2412 return aGroup._retn();
2415 //=============================================================================
2419 //=============================================================================
2421 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2423 if(MYDEBUG) MESSAGE( "createSubMesh" );
2424 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2425 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2426 const int subMeshId = mySubMesh->GetId();
2428 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2429 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2431 _mapSubMesh [subMeshId] = mySubMesh;
2432 _mapSubMesh_i [subMeshId] = subMeshServant;
2433 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2435 subMeshServant->Register();
2437 // register CORBA object for persistence
2438 int nextId = _gen_i->RegisterObject( subMesh );
2439 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2440 else { nextId = 0; } // avoid "unused variable" warning
2442 // to track changes of GEOM groups
2443 addGeomGroupData( theSubShapeObject, subMesh );
2445 return subMesh._retn();
2448 //=======================================================================
2449 //function : getSubMesh
2451 //=======================================================================
2453 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2455 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2456 if ( it == _mapSubMeshIor.end() )
2457 return SMESH::SMESH_subMesh::_nil();
2459 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2462 //=============================================================================
2466 //=============================================================================
2468 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2469 GEOM::GEOM_Object_ptr theSubShapeObject )
2471 bool isHypChanged = false;
2472 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2473 return isHypChanged;
2475 const int subMeshId = theSubMesh->GetId();
2477 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2479 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2481 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2484 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2485 isHypChanged = !hyps.empty();
2486 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2487 for ( ; hyp != hyps.end(); ++hyp )
2488 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2495 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2496 isHypChanged = ( aHypList->length() > 0 );
2497 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2498 removeHypothesis( theSubShapeObject, aHypList[i] );
2501 catch( const SALOME::SALOME_Exception& ) {
2502 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2504 removeGeomGroupData( theSubShapeObject );
2508 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2509 if ( id_smi != _mapSubMesh_i.end() )
2510 id_smi->second->UnRegister();
2512 // remove a CORBA object
2513 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2514 if ( id_smptr != _mapSubMeshIor.end() )
2515 SMESH::SMESH_subMesh_var( id_smptr->second );
2517 _mapSubMesh.erase(subMeshId);
2518 _mapSubMesh_i.erase(subMeshId);
2519 _mapSubMeshIor.erase(subMeshId);
2521 return isHypChanged;
2524 //=============================================================================
2528 //=============================================================================
2530 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2531 const char* theName,
2532 const TopoDS_Shape& theShape,
2533 const SMESH_PredicatePtr& thePredicate )
2535 std::string newName;
2536 if ( !theName || strlen( theName ) == 0 )
2538 std::set< std::string > presentNames;
2539 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2540 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2542 CORBA::String_var name = i_gr->second->GetName();
2543 presentNames.insert( name.in() );
2546 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2547 } while ( !presentNames.insert( newName ).second );
2548 theName = newName.c_str();
2551 SMESH::SMESH_GroupBase_var aGroup;
2552 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2554 SMESH_GroupBase_i* aGroupImpl;
2555 if ( !theShape.IsNull() )
2556 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2557 else if ( thePredicate )
2558 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2560 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2562 aGroup = aGroupImpl->_this();
2563 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2564 aGroupImpl->Register();
2566 // register CORBA object for persistence
2567 int nextId = _gen_i->RegisterObject( aGroup );
2568 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2569 else { nextId = 0; } // avoid "unused variable" warning in release mode
2571 // to track changes of GEOM groups
2572 if ( !theShape.IsNull() ) {
2573 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2574 addGeomGroupData( geom, aGroup );
2577 return aGroup._retn();
2580 //=============================================================================
2582 * SMESH_Mesh_i::removeGroup
2584 * Should be called by ~SMESH_Group_i()
2586 //=============================================================================
2588 void SMESH_Mesh_i::removeGroup( const int theId )
2590 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2591 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2592 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2593 _mapGroups.erase( theId );
2594 removeGeomGroupData( group );
2595 if ( !_impl->RemoveGroup( theId ))
2597 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2598 RemoveGroup( group );
2600 group->UnRegister();
2604 //=============================================================================
2608 //=============================================================================
2610 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2611 throw(SALOME::SALOME_Exception)
2613 SMESH::log_array_var aLog;
2617 _preMeshInfo->FullLoadFromFile();
2619 list < SMESHDS_Command * >logDS = _impl->GetLog();
2620 aLog = new SMESH::log_array;
2622 int lg = logDS.size();
2625 list < SMESHDS_Command * >::iterator its = logDS.begin();
2626 while(its != logDS.end()){
2627 SMESHDS_Command *com = *its;
2628 int comType = com->GetType();
2630 int lgcom = com->GetNumber();
2632 const list < int >&intList = com->GetIndexes();
2633 int inum = intList.size();
2635 list < int >::const_iterator ii = intList.begin();
2636 const list < double >&coordList = com->GetCoords();
2637 int rnum = coordList.size();
2639 list < double >::const_iterator ir = coordList.begin();
2640 aLog[indexLog].commandType = comType;
2641 aLog[indexLog].number = lgcom;
2642 aLog[indexLog].coords.length(rnum);
2643 aLog[indexLog].indexes.length(inum);
2644 for(int i = 0; i < rnum; i++){
2645 aLog[indexLog].coords[i] = *ir;
2646 //MESSAGE(" "<<i<<" "<<ir.Value());
2649 for(int i = 0; i < inum; i++){
2650 aLog[indexLog].indexes[i] = *ii;
2651 //MESSAGE(" "<<i<<" "<<ii.Value());
2660 SMESH_CATCH( SMESH::throwCorbaException );
2662 return aLog._retn();
2666 //=============================================================================
2670 //=============================================================================
2672 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2676 SMESH_CATCH( SMESH::throwCorbaException );
2679 //=============================================================================
2683 //=============================================================================
2685 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2690 //=============================================================================
2694 //=============================================================================
2696 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2701 //=============================================================================
2704 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2705 // issue 0020918: groups removal is caused by hyp modification
2706 // issue 0021208: to forget not loaded mesh data at hyp modification
2707 struct TCallUp_i : public SMESH_Mesh::TCallUp
2709 SMESH_Mesh_i* _mesh;
2710 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2711 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2712 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2713 virtual void Load () { _mesh->Load(); }
2717 //================================================================================
2719 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2721 //================================================================================
2723 void SMESH_Mesh_i::onHypothesisModified()
2726 _preMeshInfo->ForgetOrLoad();
2729 //=============================================================================
2733 //=============================================================================
2735 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2737 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2740 _impl->SetCallUp( new TCallUp_i(this));
2743 //=============================================================================
2747 //=============================================================================
2749 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2751 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2755 //=============================================================================
2757 * Return mesh editor
2759 //=============================================================================
2761 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2762 throw (SALOME::SALOME_Exception)
2764 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2768 _preMeshInfo->FullLoadFromFile();
2770 // Create MeshEditor
2772 _editor = new SMESH_MeshEditor_i( this, false );
2773 aMeshEdVar = _editor->_this();
2775 // Update Python script
2776 TPythonDump() << _editor << " = "
2777 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2779 SMESH_CATCH( SMESH::throwCorbaException );
2781 return aMeshEdVar._retn();
2784 //=============================================================================
2786 * Return mesh edition previewer
2788 //=============================================================================
2790 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2791 throw (SALOME::SALOME_Exception)
2793 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2797 _preMeshInfo->FullLoadFromFile();
2799 if ( !_previewEditor )
2800 _previewEditor = new SMESH_MeshEditor_i( this, true );
2801 aMeshEdVar = _previewEditor->_this();
2803 SMESH_CATCH( SMESH::throwCorbaException );
2805 return aMeshEdVar._retn();
2808 //================================================================================
2810 * \brief Return true if the mesh has been edited since a last total re-compute
2811 * and those modifications may prevent successful partial re-compute
2813 //================================================================================
2815 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2817 Unexpect aCatch(SALOME_SalomeException);
2818 return _impl->HasModificationsToDiscard();
2821 //================================================================================
2823 * \brief Returns a random unique color
2825 //================================================================================
2827 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2829 const int MAX_ATTEMPTS = 100;
2831 double tolerance = 0.5;
2832 SALOMEDS::Color col;
2836 // generate random color
2837 double red = (double)rand() / RAND_MAX;
2838 double green = (double)rand() / RAND_MAX;
2839 double blue = (double)rand() / RAND_MAX;
2840 // check existence in the list of the existing colors
2841 bool matched = false;
2842 std::list<SALOMEDS::Color>::const_iterator it;
2843 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2844 SALOMEDS::Color color = *it;
2845 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2846 matched = tol < tolerance;
2848 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2849 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2857 //=============================================================================
2859 * Sets auto-color mode. If it is on, groups get unique random colors
2861 //=============================================================================
2863 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2865 Unexpect aCatch(SALOME_SalomeException);
2866 _impl->SetAutoColor(theAutoColor);
2868 TPythonDump pyDump; // not to dump group->SetColor() from below code
2869 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2871 std::list<SALOMEDS::Color> aReservedColors;
2872 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2873 for ( ; it != _mapGroups.end(); it++ ) {
2874 if ( CORBA::is_nil( it->second )) continue;
2875 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2876 it->second->SetColor( aColor );
2877 aReservedColors.push_back( aColor );
2881 //=============================================================================
2883 * Returns true if auto-color mode is on
2885 //=============================================================================
2887 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2889 Unexpect aCatch(SALOME_SalomeException);
2890 return _impl->GetAutoColor();
2893 //=============================================================================
2895 * Checks if there are groups with equal names
2897 //=============================================================================
2899 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2901 return _impl->HasDuplicatedGroupNamesMED();
2904 //================================================================================
2906 * \brief Care of a file before exporting mesh into it
2908 //================================================================================
2910 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2912 SMESH_File aFile( file );
2914 if (aFile.exists()) {
2915 // existing filesystem node
2916 if ( !aFile.isDirectory() ) {
2917 if ( aFile.openForWriting() ) {
2918 if ( overwrite && ! aFile.remove()) {
2919 msg << "Can't replace " << aFile.getName();
2922 msg << "Can't write into " << aFile.getName();
2925 msg << "Location " << aFile.getName() << " is not a file";
2929 // nonexisting file; check if it can be created
2930 if ( !aFile.openForWriting() ) {
2931 msg << "You cannot create the file "
2933 << ". Check the directory existance and access rights";
2941 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2945 //================================================================================
2947 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2948 * \param file - file name
2949 * \param overwrite - to erase the file or not
2950 * \retval string - mesh name
2952 //================================================================================
2954 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2955 CORBA::Boolean overwrite)
2958 PrepareForWriting(file, overwrite);
2959 string aMeshName = "Mesh";
2960 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2961 if ( !aStudy->_is_nil() ) {
2962 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2963 if ( !aMeshSO->_is_nil() ) {
2964 CORBA::String_var name = aMeshSO->GetName();
2966 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2967 if ( !aStudy->GetProperties()->IsLocked() )
2969 SALOMEDS::GenericAttribute_wrap anAttr;
2970 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2971 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2972 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2973 ASSERT(!aFileName->_is_nil());
2974 aFileName->SetValue(file);
2975 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2976 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2977 ASSERT(!aFileType->_is_nil());
2978 aFileType->SetValue("FICHIERMED");
2982 // Update Python script
2983 // set name of mesh before export
2984 TPythonDump() << _gen_i << ".SetName("
2985 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2987 // check names of groups
2993 //================================================================================
2995 * \brief Export to med file
2997 //================================================================================
2999 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3000 CORBA::Boolean auto_groups,
3001 CORBA::Boolean overwrite,
3002 CORBA::Boolean autoDimension)
3003 throw(SALOME::SALOME_Exception)
3007 _preMeshInfo->FullLoadFromFile();
3009 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3010 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, 0, autoDimension );
3012 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3013 << file << "', " << auto_groups << ", "
3014 << overwrite << ", "
3015 << autoDimension << " )";
3017 SMESH_CATCH( SMESH::throwCorbaException );
3020 //================================================================================
3022 * \brief Export a mesh to a med file
3024 //================================================================================
3026 void SMESH_Mesh_i::ExportToMED (const char* file,
3027 CORBA::Boolean auto_groups)
3028 throw(SALOME::SALOME_Exception)
3030 ExportToMEDX(file, auto_groups, true);
3033 //================================================================================
3035 * \brief Export a mesh to a med file
3037 //================================================================================
3039 void SMESH_Mesh_i::ExportMED (const char* file,
3040 CORBA::Boolean auto_groups)
3041 throw(SALOME::SALOME_Exception)
3043 ExportToMEDX(file, auto_groups, true);
3046 //================================================================================
3048 * \brief Export a mesh to a SAUV file
3050 //================================================================================
3052 void SMESH_Mesh_i::ExportSAUV (const char* file,
3053 CORBA::Boolean auto_groups)
3054 throw(SALOME::SALOME_Exception)
3056 Unexpect aCatch(SALOME_SalomeException);
3058 _preMeshInfo->FullLoadFromFile();
3060 string aMeshName = prepareMeshNameAndGroups(file, true);
3061 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3062 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3063 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3067 //================================================================================
3069 * \brief Export a mesh to a DAT file
3071 //================================================================================
3073 void SMESH_Mesh_i::ExportDAT (const char *file)
3074 throw(SALOME::SALOME_Exception)
3076 Unexpect aCatch(SALOME_SalomeException);
3078 _preMeshInfo->FullLoadFromFile();
3080 // Update Python script
3081 // check names of groups
3083 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3086 PrepareForWriting(file);
3087 _impl->ExportDAT(file);
3090 //================================================================================
3092 * \brief Export a mesh to an UNV file
3094 //================================================================================
3096 void SMESH_Mesh_i::ExportUNV (const char *file)
3097 throw(SALOME::SALOME_Exception)
3099 Unexpect aCatch(SALOME_SalomeException);
3101 _preMeshInfo->FullLoadFromFile();
3103 // Update Python script
3104 // check names of groups
3106 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3109 PrepareForWriting(file);
3110 _impl->ExportUNV(file);
3113 //================================================================================
3115 * \brief Export a mesh to an STL file
3117 //================================================================================
3119 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3120 throw(SALOME::SALOME_Exception)
3122 Unexpect aCatch(SALOME_SalomeException);
3124 _preMeshInfo->FullLoadFromFile();
3126 // Update Python script
3127 // check names of groups
3129 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3130 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3133 PrepareForWriting(file);
3134 _impl->ExportSTL(file, isascii);
3137 //================================================================================
3139 * \brief Export a part of mesh to a med file
3141 //================================================================================
3143 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3145 CORBA::Boolean auto_groups,
3146 CORBA::Boolean overwrite,
3147 CORBA::Boolean autoDimension,
3148 const GEOM::ListOfFields& fields,
3149 const char* geomAssocFields)
3150 throw (SALOME::SALOME_Exception)
3154 _preMeshInfo->FullLoadFromFile();
3157 bool have0dField = false;
3158 if ( fields.length() > 0 )
3160 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3161 if ( shapeToMesh->_is_nil() )
3162 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3164 for ( size_t i = 0; i < fields.length(); ++i )
3166 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3167 THROW_SALOME_CORBA_EXCEPTION
3168 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3169 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3170 if ( fieldShape->_is_nil() )
3171 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3172 if ( !fieldShape->IsSame( shapeToMesh ) )
3173 THROW_SALOME_CORBA_EXCEPTION
3174 ( "Field defined not on shape", SALOME::BAD_PARAM);
3175 if ( fields[i]->GetDimension() == 0 )
3178 if ( geomAssocFields )
3179 for ( int i = 0; geomAssocFields[i]; ++i )
3180 switch ( geomAssocFields[i] ) {
3181 case 'v':case 'e':case 'f':case 's': break;
3182 case 'V':case 'E':case 'F':case 'S': break;
3183 default: THROW_SALOME_CORBA_EXCEPTION
3184 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3188 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3192 string aMeshName = "Mesh";
3193 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3194 if ( CORBA::is_nil( meshPart ) ||
3195 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3197 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3198 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3199 0, autoDimension, /*addODOnVertices=*/have0dField);
3200 meshDS = _impl->GetMeshDS();
3205 _preMeshInfo->FullLoadFromFile();
3207 PrepareForWriting(file, overwrite);
3209 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3210 if ( !aStudy->_is_nil() ) {
3211 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3212 if ( !SO->_is_nil() ) {
3213 CORBA::String_var name = SO->GetName();
3217 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3218 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3219 partDS, autoDimension, /*addODOnVertices=*/have0dField);
3220 meshDS = tmpDSDeleter._obj = partDS;
3225 if ( _impl->HasShapeToMesh() )
3227 DriverMED_W_Field fieldWriter;
3228 fieldWriter.SetFile( file );
3229 fieldWriter.SetMeshName( aMeshName );
3230 fieldWriter.AddODOnVertices( have0dField );
3232 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3236 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3237 goList->length( fields.length() );
3238 for ( size_t i = 0; i < fields.length(); ++i )
3240 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3243 TPythonDump() << _this() << ".ExportPartToMED( "
3244 << meshPart << ", r'" << file << "', "
3245 << auto_groups << ", " << overwrite << ", "
3246 << autoDimension << ", " << goList
3247 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3249 SMESH_CATCH( SMESH::throwCorbaException );
3252 //================================================================================
3254 * Write GEOM fields to MED file
3256 //================================================================================
3258 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3259 SMESHDS_Mesh* meshDS,
3260 const GEOM::ListOfFields& fields,
3261 const char* geomAssocFields)
3263 #define METH "SMESH_Mesh_i::exportMEDFields() "
3265 if (( fields.length() < 1 ) &&
3266 ( !geomAssocFields || !geomAssocFields[0] ))
3269 std::vector< std::vector< double > > dblVals;
3270 std::vector< std::vector< int > > intVals;
3271 std::vector< int > subIdsByDim[ 4 ];
3272 const double noneDblValue = 0.;
3273 const double noneIntValue = 0;
3275 for ( size_t iF = 0; iF < fields.length(); ++iF )
3279 int dim = fields[ iF ]->GetDimension();
3280 SMDSAbs_ElementType elemType;
3281 TopAbs_ShapeEnum shapeType;
3283 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3284 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3285 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3286 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3288 continue; // skip fields on whole shape
3290 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3291 if ( dataType == GEOM::FDT_String )
3293 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3294 if ( stepIDs->length() < 1 )
3296 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3297 if ( comps->length() < 1 )
3299 CORBA::String_var name = fields[ iF ]->GetName();
3301 if ( !fieldWriter.Set( meshDS,
3305 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3308 for ( size_t iC = 0; iC < comps->length(); ++iC )
3309 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3311 dblVals.resize( comps->length() );
3312 intVals.resize( comps->length() );
3314 // find sub-shape IDs
3316 std::vector< int >& subIds = subIdsByDim[ dim ];
3317 if ( subIds.empty() )
3318 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3319 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3320 subIds.push_back( id );
3324 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3328 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3330 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3331 if ( step->_is_nil() )
3334 CORBA::Long stamp = step->GetStamp();
3335 CORBA::Long id = step->GetID();
3336 fieldWriter.SetDtIt( int( stamp ), int( id ));
3338 // fill dblVals or intVals
3339 for ( size_t iC = 0; iC < comps->length(); ++iC )
3340 if ( dataType == GEOM::FDT_Double )
3342 dblVals[ iC ].clear();
3343 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3347 intVals[ iC ].clear();
3348 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3352 case GEOM::FDT_Double:
3354 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3355 if ( dblStep->_is_nil() ) continue;
3356 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3357 if ( vv->length() != subIds.size() * comps->length() )
3358 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3359 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3360 for ( size_t iC = 0; iC < comps->length(); ++iC )
3361 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3366 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3367 if ( intStep->_is_nil() ) continue;
3368 GEOM::ListOfLong_var vv = intStep->GetValues();
3369 if ( vv->length() != subIds.size() * comps->length() )
3370 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3371 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3372 for ( size_t iC = 0; iC < comps->length(); ++iC )
3373 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3376 case GEOM::FDT_Bool:
3378 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3379 if ( boolStep->_is_nil() ) continue;
3380 GEOM::short_array_var vv = boolStep->GetValues();
3381 if ( vv->length() != subIds.size() * comps->length() )
3382 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3383 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3384 for ( size_t iC = 0; iC < comps->length(); ++iC )
3385 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3391 // pass values to fieldWriter
3392 elemIt = fieldWriter.GetOrderedElems();
3393 if ( dataType == GEOM::FDT_Double )
3394 while ( elemIt->more() )
3396 const SMDS_MeshElement* e = elemIt->next();
3397 const int shapeID = e->getshapeId();
3398 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3399 for ( size_t iC = 0; iC < comps->length(); ++iC )
3400 fieldWriter.AddValue( noneDblValue );
3402 for ( size_t iC = 0; iC < comps->length(); ++iC )
3403 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3406 while ( elemIt->more() )
3408 const SMDS_MeshElement* e = elemIt->next();
3409 const int shapeID = e->getshapeId();
3410 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3411 for ( size_t iC = 0; iC < comps->length(); ++iC )
3412 fieldWriter.AddValue( (double) noneIntValue );
3414 for ( size_t iC = 0; iC < comps->length(); ++iC )
3415 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3419 fieldWriter.Perform();
3420 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3421 if ( res && res->IsKO() )
3423 if ( res->myComment.empty() )
3424 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3426 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3432 if ( !geomAssocFields || !geomAssocFields[0] )
3435 // write geomAssocFields
3437 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3438 shapeDim[ TopAbs_COMPOUND ] = 3;
3439 shapeDim[ TopAbs_COMPSOLID ] = 3;
3440 shapeDim[ TopAbs_SOLID ] = 3;
3441 shapeDim[ TopAbs_SHELL ] = 2;
3442 shapeDim[ TopAbs_FACE ] = 2;
3443 shapeDim[ TopAbs_WIRE ] = 1;
3444 shapeDim[ TopAbs_EDGE ] = 1;
3445 shapeDim[ TopAbs_VERTEX ] = 0;
3446 shapeDim[ TopAbs_SHAPE ] = 3;
3448 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3450 std::vector< std::string > compNames;
3451 switch ( geomAssocFields[ iF ]) {
3453 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3454 compNames.push_back( "dim" );
3457 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3460 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3463 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3467 compNames.push_back( "id" );
3468 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3469 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3471 fieldWriter.SetDtIt( -1, -1 );
3473 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3477 if ( compNames.size() == 2 ) // _vertices_
3478 while ( elemIt->more() )
3480 const SMDS_MeshElement* e = elemIt->next();
3481 const int shapeID = e->getshapeId();
3484 fieldWriter.AddValue( (double) -1 );
3485 fieldWriter.AddValue( (double) -1 );
3489 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3490 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3491 fieldWriter.AddValue( (double) shapeID );
3495 while ( elemIt->more() )
3497 const SMDS_MeshElement* e = elemIt->next();
3498 const int shapeID = e->getshapeId();
3500 fieldWriter.AddValue( (double) -1 );
3502 fieldWriter.AddValue( (double) shapeID );
3506 fieldWriter.Perform();
3507 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3508 if ( res && res->IsKO() )
3510 if ( res->myComment.empty() )
3511 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3513 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3516 } // loop on geomAssocFields
3521 //================================================================================
3523 * \brief Export a part of mesh to a DAT file
3525 //================================================================================
3527 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3529 throw (SALOME::SALOME_Exception)
3531 Unexpect aCatch(SALOME_SalomeException);
3533 _preMeshInfo->FullLoadFromFile();
3535 PrepareForWriting(file);
3537 SMESH_MeshPartDS partDS( meshPart );
3538 _impl->ExportDAT(file,&partDS);
3540 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3541 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3543 //================================================================================
3545 * \brief Export a part of mesh to an UNV file
3547 //================================================================================
3549 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3551 throw (SALOME::SALOME_Exception)
3553 Unexpect aCatch(SALOME_SalomeException);
3555 _preMeshInfo->FullLoadFromFile();
3557 PrepareForWriting(file);
3559 SMESH_MeshPartDS partDS( meshPart );
3560 _impl->ExportUNV(file, &partDS);
3562 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3563 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3565 //================================================================================
3567 * \brief Export a part of mesh to an STL file
3569 //================================================================================
3571 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3573 ::CORBA::Boolean isascii)
3574 throw (SALOME::SALOME_Exception)
3576 Unexpect aCatch(SALOME_SalomeException);
3578 _preMeshInfo->FullLoadFromFile();
3580 PrepareForWriting(file);
3582 SMESH_MeshPartDS partDS( meshPart );
3583 _impl->ExportSTL(file, isascii, &partDS);
3585 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3586 << meshPart<< ", r'" << file << "', " << isascii << ")";
3589 //================================================================================
3591 * \brief Export a part of mesh to an STL file
3593 //================================================================================
3595 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3597 CORBA::Boolean overwrite)
3598 throw (SALOME::SALOME_Exception)
3601 Unexpect aCatch(SALOME_SalomeException);
3603 _preMeshInfo->FullLoadFromFile();
3605 PrepareForWriting(file,overwrite);
3607 std::string meshName("");
3608 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3609 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3610 if ( !so->_is_nil() )
3612 CORBA::String_var name = so->GetName();
3613 meshName = name.in();
3615 SMESH_MeshPartDS partDS( meshPart );
3616 _impl->ExportCGNS(file, &partDS, meshName.c_str() );
3618 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3619 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3621 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3625 //================================================================================
3627 * \brief Export a part of mesh to a GMF file
3629 //================================================================================
3631 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3633 bool withRequiredGroups)
3634 throw (SALOME::SALOME_Exception)
3636 Unexpect aCatch(SALOME_SalomeException);
3638 _preMeshInfo->FullLoadFromFile();
3640 PrepareForWriting(file,/*overwrite=*/true);
3642 SMESH_MeshPartDS partDS( meshPart );
3643 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3645 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3646 << meshPart<< ", r'"
3648 << withRequiredGroups << ")";
3651 //=============================================================================
3653 * Return computation progress [0.,1]
3655 //=============================================================================
3657 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3661 return _impl->GetComputeProgress();
3663 SMESH_CATCH( SMESH::doNothing );
3667 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3669 Unexpect aCatch(SALOME_SalomeException);
3671 return _preMeshInfo->NbNodes();
3673 return _impl->NbNodes();
3676 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3678 Unexpect aCatch(SALOME_SalomeException);
3680 return _preMeshInfo->NbElements();
3682 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3685 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3687 Unexpect aCatch(SALOME_SalomeException);
3689 return _preMeshInfo->Nb0DElements();
3691 return _impl->Nb0DElements();
3694 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3696 Unexpect aCatch(SALOME_SalomeException);
3698 return _preMeshInfo->NbBalls();
3700 return _impl->NbBalls();
3703 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3705 Unexpect aCatch(SALOME_SalomeException);
3707 return _preMeshInfo->NbEdges();
3709 return _impl->NbEdges();
3712 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3713 throw(SALOME::SALOME_Exception)
3715 Unexpect aCatch(SALOME_SalomeException);
3717 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3719 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3722 //=============================================================================
3724 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3726 Unexpect aCatch(SALOME_SalomeException);
3728 return _preMeshInfo->NbFaces();
3730 return _impl->NbFaces();
3733 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3735 Unexpect aCatch(SALOME_SalomeException);
3737 return _preMeshInfo->NbTriangles();
3739 return _impl->NbTriangles();
3742 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3744 Unexpect aCatch(SALOME_SalomeException);
3746 return _preMeshInfo->NbBiQuadTriangles();
3748 return _impl->NbBiQuadTriangles();
3751 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3753 Unexpect aCatch(SALOME_SalomeException);
3755 return _preMeshInfo->NbQuadrangles();
3757 return _impl->NbQuadrangles();
3760 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3762 Unexpect aCatch(SALOME_SalomeException);
3764 return _preMeshInfo->NbBiQuadQuadrangles();
3766 return _impl->NbBiQuadQuadrangles();
3769 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3771 Unexpect aCatch(SALOME_SalomeException);
3773 return _preMeshInfo->NbPolygons();
3775 return _impl->NbPolygons();
3778 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3780 Unexpect aCatch(SALOME_SalomeException);
3782 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3784 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3787 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3788 throw(SALOME::SALOME_Exception)
3790 Unexpect aCatch(SALOME_SalomeException);
3792 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3794 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3797 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3798 throw(SALOME::SALOME_Exception)
3800 Unexpect aCatch(SALOME_SalomeException);
3802 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3804 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3807 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3808 throw(SALOME::SALOME_Exception)
3810 Unexpect aCatch(SALOME_SalomeException);
3812 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3814 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3817 //=============================================================================
3819 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3821 Unexpect aCatch(SALOME_SalomeException);
3823 return _preMeshInfo->NbVolumes();
3825 return _impl->NbVolumes();
3828 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3830 Unexpect aCatch(SALOME_SalomeException);
3832 return _preMeshInfo->NbTetras();
3834 return _impl->NbTetras();
3837 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3839 Unexpect aCatch(SALOME_SalomeException);
3841 return _preMeshInfo->NbHexas();
3843 return _impl->NbHexas();
3846 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3848 Unexpect aCatch(SALOME_SalomeException);
3850 return _preMeshInfo->NbTriQuadHexas();
3852 return _impl->NbTriQuadraticHexas();
3855 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3857 Unexpect aCatch(SALOME_SalomeException);
3859 return _preMeshInfo->NbPyramids();
3861 return _impl->NbPyramids();
3864 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3866 Unexpect aCatch(SALOME_SalomeException);
3868 return _preMeshInfo->NbPrisms();
3870 return _impl->NbPrisms();
3873 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3875 Unexpect aCatch(SALOME_SalomeException);
3877 return _preMeshInfo->NbHexPrisms();
3879 return _impl->NbHexagonalPrisms();
3882 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3884 Unexpect aCatch(SALOME_SalomeException);
3886 return _preMeshInfo->NbPolyhedrons();
3888 return _impl->NbPolyhedrons();
3891 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3892 throw(SALOME::SALOME_Exception)
3894 Unexpect aCatch(SALOME_SalomeException);
3896 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3898 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3901 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3902 throw(SALOME::SALOME_Exception)
3904 Unexpect aCatch(SALOME_SalomeException);
3906 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3908 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3911 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3912 throw(SALOME::SALOME_Exception)
3914 Unexpect aCatch(SALOME_SalomeException);
3916 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3918 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3921 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3922 throw(SALOME::SALOME_Exception)
3924 Unexpect aCatch(SALOME_SalomeException);
3926 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3928 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3931 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3932 throw(SALOME::SALOME_Exception)
3934 Unexpect aCatch(SALOME_SalomeException);
3936 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3938 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3941 //=============================================================================
3943 * Returns nb of published sub-meshes
3945 //=============================================================================
3947 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3949 Unexpect aCatch(SALOME_SalomeException);
3950 return _mapSubMesh_i.size();
3953 //=============================================================================
3955 * Dumps mesh into a string
3957 //=============================================================================
3959 char* SMESH_Mesh_i::Dump()
3963 return CORBA::string_dup( os.str().c_str() );
3966 //=============================================================================
3968 * Method of SMESH_IDSource interface
3970 //=============================================================================
3972 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3974 return GetElementsId();
3977 //=============================================================================
3979 * Returns ids of all elements
3981 //=============================================================================
3983 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3984 throw (SALOME::SALOME_Exception)
3986 Unexpect aCatch(SALOME_SalomeException);
3988 _preMeshInfo->FullLoadFromFile();
3990 SMESH::long_array_var aResult = new SMESH::long_array();
3991 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3993 if ( aSMESHDS_Mesh == NULL )
3994 return aResult._retn();
3996 long nbElements = NbElements();
3997 aResult->length( nbElements );
3998 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3999 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4000 aResult[i] = anIt->next()->GetID();
4002 return aResult._retn();
4006 //=============================================================================
4008 * Returns ids of all elements of given type
4010 //=============================================================================
4012 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4013 throw (SALOME::SALOME_Exception)
4015 Unexpect aCatch(SALOME_SalomeException);
4017 _preMeshInfo->FullLoadFromFile();
4019 SMESH::long_array_var aResult = new SMESH::long_array();
4020 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4022 if ( aSMESHDS_Mesh == NULL )
4023 return aResult._retn();
4025 long nbElements = NbElements();
4027 // No sense in returning ids of elements along with ids of nodes:
4028 // when theElemType == SMESH::ALL, return node ids only if
4029 // there are no elements
4030 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4031 return GetNodesId();
4033 aResult->length( nbElements );
4037 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4038 while ( i < nbElements && anIt->more() )
4039 aResult[i++] = anIt->next()->GetID();
4041 aResult->length( i );
4043 return aResult._retn();
4046 //=============================================================================
4048 * Returns ids of all nodes
4050 //=============================================================================
4052 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4053 throw (SALOME::SALOME_Exception)
4055 Unexpect aCatch(SALOME_SalomeException);
4057 _preMeshInfo->FullLoadFromFile();
4059 SMESH::long_array_var aResult = new SMESH::long_array();
4060 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4062 if ( aSMESHDS_Mesh == NULL )
4063 return aResult._retn();
4065 long nbNodes = NbNodes();
4066 aResult->length( nbNodes );
4067 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4068 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4069 aResult[i] = anIt->next()->GetID();
4071 return aResult._retn();
4074 //=============================================================================
4078 //=============================================================================
4080 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4081 throw (SALOME::SALOME_Exception)
4083 SMESH::ElementType type = SMESH::ALL;
4087 _preMeshInfo->FullLoadFromFile();
4089 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4091 SMESH_CATCH( SMESH::throwCorbaException );
4096 //=============================================================================
4100 //=============================================================================
4102 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4103 throw (SALOME::SALOME_Exception)
4106 _preMeshInfo->FullLoadFromFile();
4108 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4110 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4112 return ( SMESH::EntityType ) e->GetEntityType();
4115 //=============================================================================
4119 //=============================================================================
4121 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4122 throw (SALOME::SALOME_Exception)
4125 _preMeshInfo->FullLoadFromFile();
4127 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4129 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4131 return ( SMESH::GeometryType ) e->GetGeomType();
4134 //=============================================================================
4136 * Returns ID of elements for given submesh
4138 //=============================================================================
4139 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4140 throw (SALOME::SALOME_Exception)
4142 SMESH::long_array_var aResult = new SMESH::long_array();
4146 _preMeshInfo->FullLoadFromFile();
4148 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4149 if(!SM) return aResult._retn();
4151 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4152 if(!SDSM) return aResult._retn();
4154 aResult->length(SDSM->NbElements());
4156 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4158 while ( eIt->more() ) {
4159 aResult[i++] = eIt->next()->GetID();
4162 SMESH_CATCH( SMESH::throwCorbaException );
4164 return aResult._retn();
4167 //=============================================================================
4169 * Returns ID of nodes for given submesh
4170 * If param all==true - returns all nodes, else -
4171 * returns only nodes on shapes.
4173 //=============================================================================
4175 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4177 throw (SALOME::SALOME_Exception)
4179 SMESH::long_array_var aResult = new SMESH::long_array();
4183 _preMeshInfo->FullLoadFromFile();
4185 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4186 if(!SM) return aResult._retn();
4188 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4189 if(!SDSM) return aResult._retn();
4192 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4193 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4194 while ( nIt->more() ) {
4195 const SMDS_MeshNode* elem = nIt->next();
4196 theElems.insert( elem->GetID() );
4199 else { // all nodes of submesh elements
4200 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4201 while ( eIt->more() ) {
4202 const SMDS_MeshElement* anElem = eIt->next();
4203 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4204 while ( nIt->more() ) {
4205 const SMDS_MeshElement* elem = nIt->next();
4206 theElems.insert( elem->GetID() );
4211 aResult->length(theElems.size());
4212 set<int>::iterator itElem;
4214 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4215 aResult[i++] = *itElem;
4217 SMESH_CATCH( SMESH::throwCorbaException );
4219 return aResult._retn();
4222 //=============================================================================
4224 * Returns type of elements for given submesh
4226 //=============================================================================
4228 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4229 throw (SALOME::SALOME_Exception)
4231 SMESH::ElementType type = SMESH::ALL;
4235 _preMeshInfo->FullLoadFromFile();
4237 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4238 if(!SM) return SMESH::ALL;
4240 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4241 if(!SDSM) return SMESH::ALL;
4243 if(SDSM->NbElements()==0)
4244 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4246 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4247 const SMDS_MeshElement* anElem = eIt->next();
4249 type = ( SMESH::ElementType ) anElem->GetType();
4251 SMESH_CATCH( SMESH::throwCorbaException );
4257 //=============================================================================
4259 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4261 //=============================================================================
4263 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4266 _preMeshInfo->FullLoadFromFile();
4268 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4269 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4274 //=============================================================================
4276 * Get XYZ coordinates of node as list of double
4277 * If there is not node for given ID - returns empty list
4279 //=============================================================================
4281 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4284 _preMeshInfo->FullLoadFromFile();
4286 SMESH::double_array_var aResult = new SMESH::double_array();
4287 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4288 if ( aSMESHDS_Mesh == NULL )
4289 return aResult._retn();
4292 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4294 return aResult._retn();
4298 aResult[0] = aNode->X();
4299 aResult[1] = aNode->Y();
4300 aResult[2] = aNode->Z();
4301 return aResult._retn();
4305 //=============================================================================
4307 * For given node returns list of IDs of inverse elements
4308 * If there is not node for given ID - returns empty list
4310 //=============================================================================
4312 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4315 _preMeshInfo->FullLoadFromFile();
4317 SMESH::long_array_var aResult = new SMESH::long_array();
4318 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4319 if ( aSMESHDS_Mesh == NULL )
4320 return aResult._retn();
4323 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4325 return aResult._retn();
4327 // find inverse elements
4328 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4329 aResult->length( aNode->NbInverseElements() );
4330 for( int i = 0; eIt->more(); ++i )
4332 const SMDS_MeshElement* elem = eIt->next();
4333 aResult[ i ] = elem->GetID();
4335 return aResult._retn();
4338 //=============================================================================
4340 * \brief Return position of a node on shape
4342 //=============================================================================
4344 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4347 _preMeshInfo->FullLoadFromFile();
4349 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4350 aNodePosition->shapeID = 0;
4351 aNodePosition->shapeType = GEOM::SHAPE;
4353 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4354 if ( !mesh ) return aNodePosition;
4356 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4358 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4360 aNodePosition->shapeID = aNode->getshapeId();
4361 switch ( pos->GetTypeOfPosition() ) {
4363 aNodePosition->shapeType = GEOM::EDGE;
4364 aNodePosition->params.length(1);
4365 aNodePosition->params[0] =
4366 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4369 aNodePosition->shapeType = GEOM::FACE;
4370 aNodePosition->params.length(2);
4371 aNodePosition->params[0] =
4372 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4373 aNodePosition->params[1] =
4374 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4376 case SMDS_TOP_VERTEX:
4377 aNodePosition->shapeType = GEOM::VERTEX;
4379 case SMDS_TOP_3DSPACE:
4380 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4381 aNodePosition->shapeType = GEOM::SOLID;
4382 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4383 aNodePosition->shapeType = GEOM::SHELL;
4389 return aNodePosition;
4392 //=============================================================================
4394 * \brief Return position of an element on shape
4396 //=============================================================================
4398 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4401 _preMeshInfo->FullLoadFromFile();
4403 SMESH::ElementPosition anElementPosition;
4404 anElementPosition.shapeID = 0;
4405 anElementPosition.shapeType = GEOM::SHAPE;
4407 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4408 if ( !mesh ) return anElementPosition;
4410 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4412 anElementPosition.shapeID = anElem->getshapeId();
4413 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4414 if ( !aSp.IsNull() ) {
4415 switch ( aSp.ShapeType() ) {
4417 anElementPosition.shapeType = GEOM::EDGE;
4420 anElementPosition.shapeType = GEOM::FACE;
4423 anElementPosition.shapeType = GEOM::VERTEX;
4426 anElementPosition.shapeType = GEOM::SOLID;
4429 anElementPosition.shapeType = GEOM::SHELL;
4435 return anElementPosition;
4438 //=============================================================================
4440 * If given element is node returns IDs of shape from position
4441 * If there is not node for given ID - returns -1
4443 //=============================================================================
4445 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4448 _preMeshInfo->FullLoadFromFile();
4450 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4451 if ( aSMESHDS_Mesh == NULL )
4455 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4457 return aNode->getshapeId();
4464 //=============================================================================
4466 * For given element returns ID of result shape after
4467 * ::FindShape() from SMESH_MeshEditor
4468 * If there is not element for given ID - returns -1
4470 //=============================================================================
4472 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4475 _preMeshInfo->FullLoadFromFile();
4477 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4478 if ( aSMESHDS_Mesh == NULL )
4481 // try to find element
4482 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4486 ::SMESH_MeshEditor aMeshEditor(_impl);
4487 int index = aMeshEditor.FindShape( elem );
4495 //=============================================================================
4497 * Returns number of nodes for given element
4498 * If there is not element for given ID - returns -1
4500 //=============================================================================
4502 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4505 _preMeshInfo->FullLoadFromFile();
4507 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4508 if ( aSMESHDS_Mesh == NULL ) return -1;
4509 // try to find element
4510 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4511 if(!elem) return -1;
4512 return elem->NbNodes();
4516 //=============================================================================
4518 * Returns ID of node by given index for given element
4519 * If there is not element for given ID - returns -1
4520 * If there is not node for given index - returns -2
4522 //=============================================================================
4524 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4527 _preMeshInfo->FullLoadFromFile();
4529 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4530 if ( aSMESHDS_Mesh == NULL ) return -1;
4531 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4532 if(!elem) return -1;
4533 if( index>=elem->NbNodes() || index<0 ) return -1;
4534 return elem->GetNode(index)->GetID();
4537 //=============================================================================
4539 * Returns IDs of nodes of given element
4541 //=============================================================================
4543 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4546 _preMeshInfo->FullLoadFromFile();
4548 SMESH::long_array_var aResult = new SMESH::long_array();
4549 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4551 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4553 aResult->length( elem->NbNodes() );
4554 for ( int i = 0; i < elem->NbNodes(); ++i )
4555 aResult[ i ] = elem->GetNode( i )->GetID();
4558 return aResult._retn();
4561 //=============================================================================
4563 * Returns true if given node is medium node
4564 * in given quadratic element
4566 //=============================================================================
4568 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4571 _preMeshInfo->FullLoadFromFile();
4573 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4574 if ( aSMESHDS_Mesh == NULL ) return false;
4576 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4577 if(!aNode) return false;
4578 // try to find element
4579 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4580 if(!elem) return false;
4582 return elem->IsMediumNode(aNode);
4586 //=============================================================================
4588 * Returns true if given node is medium node
4589 * in one of quadratic elements
4591 //=============================================================================
4593 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4594 SMESH::ElementType theElemType)
4597 _preMeshInfo->FullLoadFromFile();
4599 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4600 if ( aSMESHDS_Mesh == NULL ) return false;
4603 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4604 if(!aNode) return false;
4606 SMESH_MesherHelper aHelper( *(_impl) );
4608 SMDSAbs_ElementType aType;
4609 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4610 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4611 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4612 else aType = SMDSAbs_All;
4614 return aHelper.IsMedium(aNode,aType);
4618 //=============================================================================
4620 * Returns number of edges for given element
4622 //=============================================================================
4624 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4627 _preMeshInfo->FullLoadFromFile();
4629 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4630 if ( aSMESHDS_Mesh == NULL ) return -1;
4631 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4632 if(!elem) return -1;
4633 return elem->NbEdges();
4637 //=============================================================================
4639 * Returns number of faces for given element
4641 //=============================================================================
4643 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4646 _preMeshInfo->FullLoadFromFile();
4648 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4649 if ( aSMESHDS_Mesh == NULL ) return -1;
4650 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4651 if(!elem) return -1;
4652 return elem->NbFaces();
4655 //=======================================================================
4656 //function : GetElemFaceNodes
4657 //purpose : Returns nodes of given face (counted from zero) for given element.
4658 //=======================================================================
4660 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4661 CORBA::Short faceIndex)
4664 _preMeshInfo->FullLoadFromFile();
4666 SMESH::long_array_var aResult = new SMESH::long_array();
4667 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4669 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4671 SMDS_VolumeTool vtool( elem );
4672 if ( faceIndex < vtool.NbFaces() )
4674 aResult->length( vtool.NbFaceNodes( faceIndex ));
4675 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4676 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4677 aResult[ i ] = nn[ i ]->GetID();
4681 return aResult._retn();
4684 //=======================================================================
4685 //function : GetElemFaceNodes
4686 //purpose : Returns three components of normal of given mesh face.
4687 //=======================================================================
4689 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4690 CORBA::Boolean normalized)
4693 _preMeshInfo->FullLoadFromFile();
4695 SMESH::double_array_var aResult = new SMESH::double_array();
4697 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4700 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4702 aResult->length( 3 );
4703 aResult[ 0 ] = normal.X();
4704 aResult[ 1 ] = normal.Y();
4705 aResult[ 2 ] = normal.Z();
4708 return aResult._retn();
4711 //=======================================================================
4712 //function : FindElementByNodes
4713 //purpose : Returns an element based on all given nodes.
4714 //=======================================================================
4716 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4719 _preMeshInfo->FullLoadFromFile();
4721 CORBA::Long elemID(0);
4722 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4724 vector< const SMDS_MeshNode * > nn( nodes.length() );
4725 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4726 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4729 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4730 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4731 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4732 _impl->NbVolumes( ORDER_QUADRATIC )))
4733 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4735 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4740 //=============================================================================
4742 * Returns true if given element is polygon
4744 //=============================================================================
4746 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4749 _preMeshInfo->FullLoadFromFile();
4751 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4752 if ( aSMESHDS_Mesh == NULL ) return false;
4753 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4754 if(!elem) return false;
4755 return elem->IsPoly();
4759 //=============================================================================
4761 * Returns true if given element is quadratic
4763 //=============================================================================
4765 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4768 _preMeshInfo->FullLoadFromFile();
4770 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4771 if ( aSMESHDS_Mesh == NULL ) return false;
4772 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4773 if(!elem) return false;
4774 return elem->IsQuadratic();
4777 //=============================================================================
4779 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4781 //=============================================================================
4783 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4786 _preMeshInfo->FullLoadFromFile();
4788 if ( const SMDS_BallElement* ball =
4789 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4790 return ball->GetDiameter();
4795 //=============================================================================
4797 * Returns bary center for given element
4799 //=============================================================================
4801 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4804 _preMeshInfo->FullLoadFromFile();
4806 SMESH::double_array_var aResult = new SMESH::double_array();
4807 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4808 if ( aSMESHDS_Mesh == NULL )
4809 return aResult._retn();
4811 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4813 return aResult._retn();
4815 if(elem->GetType()==SMDSAbs_Volume) {
4816 SMDS_VolumeTool aTool;
4817 if(aTool.Set(elem)) {
4819 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4824 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4826 double x=0., y=0., z=0.;
4827 for(; anIt->more(); ) {
4829 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4843 return aResult._retn();
4846 //================================================================================
4848 * \brief Create a group of elements preventing computation of a sub-shape
4850 //================================================================================
4852 SMESH::ListOfGroups*
4853 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4854 const char* theGroupName )
4855 throw ( SALOME::SALOME_Exception )
4857 Unexpect aCatch(SALOME_SalomeException);
4859 if ( !theGroupName || strlen( theGroupName) == 0 )
4860 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4862 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4863 ::SMESH_MeshEditor::ElemFeatures elemType;
4865 // submesh by subshape id
4866 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4867 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4870 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4871 if ( error && !error->myBadElements.empty())
4873 // sort bad elements by type
4874 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4875 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4876 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4877 for ( ; elemIt != elemEnd; ++elemIt )
4879 const SMDS_MeshElement* elem = *elemIt;
4880 if ( !elem ) continue;
4882 if ( elem->GetID() < 1 )
4884 // elem is a temporary element, make a real element
4885 vector< const SMDS_MeshNode* > nodes;
4886 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4887 while ( nIt->more() && elem )
4889 nodes.push_back( nIt->next() );
4890 if ( nodes.back()->GetID() < 1 )
4891 elem = 0; // a temporary element on temporary nodes
4895 ::SMESH_MeshEditor editor( _impl );
4896 elem = editor.AddElement( nodes, elemType.Init( elem ));
4900 elemsByType[ elem->GetType() ].push_back( elem );
4903 // how many groups to create?
4905 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4906 nbTypes += int( !elemsByType[ i ].empty() );
4907 groups->length( nbTypes );
4910 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4912 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4913 if ( elems.empty() ) continue;
4915 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4916 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4918 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4919 SMESH::SMESH_Mesh_var mesh = _this();
4920 SALOMEDS::SObject_wrap aSO =
4921 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4922 GEOM::GEOM_Object::_nil(), theGroupName);
4924 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4925 if ( !grp_i ) continue;
4927 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4928 for ( size_t iE = 0; iE < elems.size(); ++iE )
4929 grpDS->SMDSGroup().Add( elems[ iE ]);
4934 return groups._retn();
4937 //=============================================================================
4939 * Create and publish group servants if any groups were imported or created anyhow
4941 //=============================================================================
4943 void SMESH_Mesh_i::CreateGroupServants()
4945 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4946 SMESH::SMESH_Mesh_var aMesh = _this();
4949 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4950 while ( groupIt->more() )
4952 ::SMESH_Group* group = groupIt->next();
4953 int anId = group->GetGroupDS()->GetID();
4955 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4956 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4958 addedIDs.insert( anId );
4960 SMESH_GroupBase_i* aGroupImpl;
4962 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4963 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4965 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4966 shape = groupOnGeom->GetShape();
4969 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4972 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4973 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4974 aGroupImpl->Register();
4976 // register CORBA object for persistence
4977 int nextId = _gen_i->RegisterObject( groupVar );
4978 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4979 else { nextId = 0; } // avoid "unused variable" warning in release mode
4981 // publishing the groups in the study
4982 if ( !aStudy->_is_nil() ) {
4983 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4984 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4987 if ( !addedIDs.empty() )
4990 set<int>::iterator id = addedIDs.begin();
4991 for ( ; id != addedIDs.end(); ++id )
4993 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4994 int i = std::distance( _mapGroups.begin(), it );
4995 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5000 //=============================================================================
5002 * \brief Return groups cantained in _mapGroups by their IDs
5004 //=============================================================================
5006 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5008 int nbGroups = groupIDs.size();
5009 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5010 aList->length( nbGroups );
5012 list<int>::const_iterator ids = groupIDs.begin();
5013 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5015 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5016 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5017 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5019 aList->length( nbGroups );
5020 return aList._retn();
5023 //=============================================================================
5025 * \brief Return information about imported file
5027 //=============================================================================
5029 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5031 SMESH::MedFileInfo_var res( _medFileInfo );
5032 if ( !res.operator->() ) {
5033 res = new SMESH::MedFileInfo;
5035 res->fileSize = res->major = res->minor = res->release = -1;
5040 //=============================================================================
5042 * \brief Pass names of mesh groups from study to mesh DS
5044 //=============================================================================
5046 void SMESH_Mesh_i::checkGroupNames()
5048 int nbGrp = NbGroups();
5052 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5053 if ( aStudy->_is_nil() )
5054 return; // nothing to do
5056 SMESH::ListOfGroups* grpList = 0;
5057 // avoid dump of "GetGroups"
5059 // store python dump into a local variable inside local scope
5060 SMESH::TPythonDump pDump; // do not delete this line of code
5061 grpList = GetGroups();
5064 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5065 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5068 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5069 if ( aGrpSO->_is_nil() )
5071 // correct name of the mesh group if necessary
5072 const char* guiName = aGrpSO->GetName();
5073 if ( strcmp(guiName, aGrp->GetName()) )
5074 aGrp->SetName( guiName );
5078 //=============================================================================
5080 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5082 //=============================================================================
5083 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5085 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5089 //=============================================================================
5091 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5093 //=============================================================================
5095 char* SMESH_Mesh_i::GetParameters()
5097 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5100 //=============================================================================
5102 * \brief Returns list of notebook variables used for last Mesh operation
5104 //=============================================================================
5105 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5107 SMESH::string_array_var aResult = new SMESH::string_array();
5108 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5110 CORBA::String_var aParameters = GetParameters();
5111 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5112 if ( !aStudy->_is_nil()) {
5113 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5114 if ( aSections->length() > 0 ) {
5115 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5116 aResult->length( aVars.length() );
5117 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5118 aResult[i] = CORBA::string_dup( aVars[i] );
5122 return aResult._retn();
5125 //=======================================================================
5126 //function : GetTypes
5127 //purpose : Returns types of elements it contains
5128 //=======================================================================
5130 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5133 return _preMeshInfo->GetTypes();
5135 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5139 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5140 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5141 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5142 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5143 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5144 if (_impl->NbNodes() &&
5145 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5146 types->length( nbTypes );
5148 return types._retn();
5151 //=======================================================================
5152 //function : GetMesh
5153 //purpose : Returns self
5154 //=======================================================================
5156 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5158 return SMESH::SMESH_Mesh::_duplicate( _this() );
5161 //=======================================================================
5162 //function : IsMeshInfoCorrect
5163 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5164 // * happen if mesh data is not yet fully loaded from the file of study.
5165 //=======================================================================
5167 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5169 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5172 //=============================================================================
5174 * \brief Returns number of mesh elements per each \a EntityType
5176 //=============================================================================
5178 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5181 return _preMeshInfo->GetMeshInfo();
5183 SMESH::long_array_var aRes = new SMESH::long_array();
5184 aRes->length(SMESH::Entity_Last);
5185 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5187 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5189 return aRes._retn();
5190 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5191 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5192 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5193 return aRes._retn();
5196 //=============================================================================
5198 * \brief Returns number of mesh elements per each \a ElementType
5200 //=============================================================================
5202 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5204 SMESH::long_array_var aRes = new SMESH::long_array();
5205 aRes->length(SMESH::NB_ELEMENT_TYPES);
5206 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5209 const SMDS_MeshInfo* meshInfo = 0;
5211 meshInfo = _preMeshInfo;
5212 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5213 meshInfo = & meshDS->GetMeshInfo();
5216 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5217 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5219 return aRes._retn();
5222 //=============================================================================
5224 * Collect statistic of mesh elements given by iterator
5226 //=============================================================================
5228 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5229 SMESH::long_array& theInfo)
5231 if (!theItr) return;
5232 while (theItr->more())
5233 theInfo[ theItr->next()->GetEntityType() ]++;
5235 //=============================================================================
5237 * Returns mesh unstructed grid information.
5239 //=============================================================================
5241 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5243 SALOMEDS::TMPFile_var SeqFile;
5244 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5245 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5247 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5248 aWriter->WriteToOutputStringOn();
5249 aWriter->SetInputData(aGrid);
5250 aWriter->SetFileTypeToBinary();
5252 char* str = aWriter->GetOutputString();
5253 int size = aWriter->GetOutputStringLength();
5255 //Allocate octect buffer of required size
5256 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5257 //Copy ostrstream content to the octect buffer
5258 memcpy(OctetBuf, str, size);
5259 //Create and return TMPFile
5260 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5264 return SeqFile._retn();
5267 //=============================================================================
5268 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5269 * SMESH::ElementType type) */
5271 using namespace SMESH::Controls;
5272 //-----------------------------------------------------------------------------
5273 struct PredicateIterator : public SMDS_ElemIterator
5275 SMDS_ElemIteratorPtr _elemIter;
5276 PredicatePtr _predicate;
5277 const SMDS_MeshElement* _elem;
5279 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5280 PredicatePtr predicate):
5281 _elemIter(iterator), _predicate(predicate)
5289 virtual const SMDS_MeshElement* next()
5291 const SMDS_MeshElement* res = _elem;
5293 while ( _elemIter->more() && !_elem )
5295 _elem = _elemIter->next();
5296 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5303 //-----------------------------------------------------------------------------
5304 struct IDSourceIterator : public SMDS_ElemIterator
5306 const CORBA::Long* _idPtr;
5307 const CORBA::Long* _idEndPtr;
5308 SMESH::long_array_var _idArray;
5309 const SMDS_Mesh* _mesh;
5310 const SMDSAbs_ElementType _type;
5311 const SMDS_MeshElement* _elem;
5313 IDSourceIterator( const SMDS_Mesh* mesh,
5314 const CORBA::Long* ids,
5316 SMDSAbs_ElementType type):
5317 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5319 if ( _idPtr && nbIds && _mesh )
5322 IDSourceIterator( const SMDS_Mesh* mesh,
5323 SMESH::long_array* idArray,
5324 SMDSAbs_ElementType type):
5325 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5327 if ( idArray && _mesh )
5329 _idPtr = &_idArray[0];
5330 _idEndPtr = _idPtr + _idArray->length();
5338 virtual const SMDS_MeshElement* next()
5340 const SMDS_MeshElement* res = _elem;
5342 while ( _idPtr < _idEndPtr && !_elem )
5344 if ( _type == SMDSAbs_Node )
5346 _elem = _mesh->FindNode( *_idPtr++ );
5348 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5349 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5357 //-----------------------------------------------------------------------------
5359 struct NodeOfElemIterator : public SMDS_ElemIterator
5361 TColStd_MapOfInteger _checkedNodeIDs;
5362 SMDS_ElemIteratorPtr _elemIter;
5363 SMDS_ElemIteratorPtr _nodeIter;
5364 const SMDS_MeshElement* _node;
5366 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5368 if ( _elemIter && _elemIter->more() )
5370 _nodeIter = _elemIter->next()->nodesIterator();
5378 virtual const SMDS_MeshElement* next()
5380 const SMDS_MeshElement* res = _node;
5382 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5384 if ( _nodeIter->more() )
5386 _node = _nodeIter->next();
5387 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5392 _nodeIter = _elemIter->next()->nodesIterator();
5400 //=============================================================================
5402 * Return iterator on elements of given type in given object
5404 //=============================================================================
5406 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5407 SMESH::ElementType theType)
5409 SMDS_ElemIteratorPtr elemIt;
5410 bool typeOK = ( theType == SMESH::ALL );
5411 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5413 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5414 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5415 if ( !mesh_i ) return elemIt;
5416 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5418 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5420 elemIt = meshDS->elementsIterator( elemType );
5423 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5425 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5428 elemIt = sm->GetElements();
5429 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5431 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5432 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5436 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5438 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5439 if ( groupDS && ( elemType == groupDS->GetType() ||
5440 elemType == SMDSAbs_Node ||
5441 elemType == SMDSAbs_All ))
5443 elemIt = groupDS->GetElements();
5444 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5447 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5449 if ( filter_i->GetElementType() == theType ||
5450 elemType == SMDSAbs_Node ||
5451 elemType == SMDSAbs_All)
5453 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5454 if ( pred_i && pred_i->GetPredicate() )
5456 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5457 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5458 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5459 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5465 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5466 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5467 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5469 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5472 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5473 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5477 SMESH::long_array_var ids = theObject->GetIDs();
5478 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5480 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5483 if ( elemIt && elemIt->more() && !typeOK )
5485 if ( elemType == SMDSAbs_Node )
5487 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5491 elemIt = SMDS_ElemIteratorPtr();
5497 //=============================================================================
5498 namespace // Finding concurrent hypotheses
5499 //=============================================================================
5503 * \brief mapping of mesh dimension into shape type
5505 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5507 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5509 case 0: aType = TopAbs_VERTEX; break;
5510 case 1: aType = TopAbs_EDGE; break;
5511 case 2: aType = TopAbs_FACE; break;
5513 default:aType = TopAbs_SOLID; break;
5518 //-----------------------------------------------------------------------------
5520 * \brief Internal structure used to find concurent submeshes
5522 * It represents a pair < submesh, concurent dimension >, where
5523 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5524 * with another submesh. In other words, it is dimension of a hypothesis assigned
5531 int _dim; //!< a dimension the algo can build (concurrent dimension)
5532 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5533 TopTools_MapOfShape _shapeMap;
5534 SMESH_subMesh* _subMesh;
5535 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5537 //-----------------------------------------------------------------------------
5538 // Return the algorithm
5539 const SMESH_Algo* GetAlgo() const
5540 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5542 //-----------------------------------------------------------------------------
5544 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5546 const TopoDS_Shape& theShape)
5548 _subMesh = (SMESH_subMesh*)theSubMesh;
5549 SetShape( theDim, theShape );
5552 //-----------------------------------------------------------------------------
5554 void SetShape(const int theDim,
5555 const TopoDS_Shape& theShape)
5558 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5559 if (_dim >= _ownDim)
5560 _shapeMap.Add( theShape );
5562 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5563 for( ; anExp.More(); anExp.Next() )
5564 _shapeMap.Add( anExp.Current() );
5568 //-----------------------------------------------------------------------------
5569 //! Check sharing of sub-shapes
5570 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5571 const TopTools_MapOfShape& theToFind,
5572 const TopAbs_ShapeEnum theType)
5574 bool isShared = false;
5575 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5576 for (; !isShared && anItr.More(); anItr.Next() )
5578 const TopoDS_Shape aSubSh = anItr.Key();
5579 // check for case when concurrent dimensions are same
5580 isShared = theToFind.Contains( aSubSh );
5581 // check for sub-shape with concurrent dimension
5582 TopExp_Explorer anExp( aSubSh, theType );
5583 for ( ; !isShared && anExp.More(); anExp.Next() )
5584 isShared = theToFind.Contains( anExp.Current() );
5589 //-----------------------------------------------------------------------------
5590 //! check algorithms
5591 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5592 const SMESHDS_Hypothesis* theA2)
5594 if ( !theA1 || !theA2 ||
5595 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5596 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5597 return false; // one of the hypothesis is not algorithm
5598 // check algorithm names (should be equal)
5599 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5603 //-----------------------------------------------------------------------------
5604 //! Check if sub-shape hypotheses are concurrent
5605 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5607 if ( _subMesh == theOther->_subMesh )
5608 return false; // same sub-shape - should not be
5610 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5611 // any of the two submeshes is not on COMPOUND shape )
5612 // -> no concurrency
5613 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5614 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5615 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5616 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5617 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5620 // bool checkSubShape = ( _dim >= theOther->_dim )
5621 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5622 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5623 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5624 if ( !checkSubShape )
5627 // check algorithms to be same
5628 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5629 return true; // different algorithms -> concurrency !
5631 // check hypothesises for concurrence (skip first as algorithm)
5633 // pointers should be same, because it is referened from mesh hypothesis partition
5634 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5635 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5636 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5637 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5639 // the submeshes are concurrent if their algorithms has different parameters
5640 return nbSame != (int)theOther->_hypotheses.size() - 1;
5643 // Return true if algorithm of this SMESH_DimHyp is used if no
5644 // sub-mesh order is imposed by the user
5645 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5647 // NeedDiscreteBoundary() algo has a higher priority
5648 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5649 theOther->GetAlgo()->NeedDiscreteBoundary() )
5650 return !this->GetAlgo()->NeedDiscreteBoundary();
5652 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5655 }; // end of SMESH_DimHyp
5656 //-----------------------------------------------------------------------------
5658 typedef list<const SMESH_DimHyp*> TDimHypList;
5660 //-----------------------------------------------------------------------------
5662 void addDimHypInstance(const int theDim,
5663 const TopoDS_Shape& theShape,
5664 const SMESH_Algo* theAlgo,
5665 const SMESH_subMesh* theSubMesh,
5666 const list <const SMESHDS_Hypothesis*>& theHypList,
5667 TDimHypList* theDimHypListArr )
5669 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5670 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5671 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5672 dimHyp->_hypotheses.push_front(theAlgo);
5673 listOfdimHyp.push_back( dimHyp );
5676 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5677 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5678 theHypList.begin(), theHypList.end() );
5681 //-----------------------------------------------------------------------------
5682 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5683 TDimHypList& theListOfConcurr)
5685 if ( theListOfConcurr.empty() )
5687 theListOfConcurr.push_back( theDimHyp );
5691 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5692 while ( hypIt != theListOfConcurr.end() &&
5693 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5695 theListOfConcurr.insert( hypIt, theDimHyp );
5699 //-----------------------------------------------------------------------------
5700 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5701 const TDimHypList& theListOfDimHyp,
5702 TDimHypList& theListOfConcurrHyp,
5703 set<int>& theSetOfConcurrId )
5705 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5706 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5708 const SMESH_DimHyp* curDimHyp = *rIt;
5709 if ( curDimHyp == theDimHyp )
5710 break; // meet own dimHyp pointer in same dimension
5712 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5713 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5715 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5720 //-----------------------------------------------------------------------------
5721 void unionLists(TListOfInt& theListOfId,
5722 TListOfListOfInt& theListOfListOfId,
5725 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5726 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5728 continue; //skip already treated lists
5729 // check if other list has any same submesh object
5730 TListOfInt& otherListOfId = *it;
5731 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5732 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5735 // union two lists (from source into target)
5736 TListOfInt::iterator it2 = otherListOfId.begin();
5737 for ( ; it2 != otherListOfId.end(); it2++ ) {
5738 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5739 theListOfId.push_back(*it2);
5741 // clear source list
5742 otherListOfId.clear();
5745 //-----------------------------------------------------------------------------
5747 //! free memory allocated for dimension-hypothesis objects
5748 void removeDimHyps( TDimHypList* theArrOfList )
5750 for (int i = 0; i < 4; i++ ) {
5751 TDimHypList& listOfdimHyp = theArrOfList[i];
5752 TDimHypList::const_iterator it = listOfdimHyp.begin();
5753 for ( ; it != listOfdimHyp.end(); it++ )
5758 //-----------------------------------------------------------------------------
5760 * \brief find common submeshes with given submesh
5761 * \param theSubMeshList list of already collected submesh to check
5762 * \param theSubMesh given submesh to intersect with other
5763 * \param theCommonSubMeshes collected common submeshes
5765 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5766 const SMESH_subMesh* theSubMesh,
5767 set<const SMESH_subMesh*>& theCommon )
5771 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5772 for ( ; it != theSubMeshList.end(); it++ )
5773 theSubMesh->FindIntersection( *it, theCommon );
5774 theSubMeshList.push_back( theSubMesh );
5775 //theCommon.insert( theSubMesh );
5778 //-----------------------------------------------------------------------------
5779 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5781 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5782 for ( ; listsIt != smLists.end(); ++listsIt )
5784 const TListOfInt& smIDs = *listsIt;
5785 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5793 //=============================================================================
5795 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5797 //=============================================================================
5799 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5801 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5802 if ( isSubMeshInList( submeshID, anOrder ))
5805 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5806 return isSubMeshInList( submeshID, allConurrent );
5809 //=============================================================================
5811 * \brief Return submesh objects list in meshing order
5813 //=============================================================================
5815 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5817 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5819 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5821 return aResult._retn();
5823 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5824 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5825 anOrder.splice( anOrder.end(), allConurrent );
5828 TListOfListOfInt::iterator listIt = anOrder.begin();
5829 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5830 unionLists( *listIt, anOrder, listIndx + 1 );
5832 // convert submesh ids into interface instances
5833 // and dump command into python
5834 convertMeshOrder( anOrder, aResult, false );
5836 return aResult._retn();
5839 //=============================================================================
5841 * \brief Finds concurrent sub-meshes
5843 //=============================================================================
5845 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5847 TListOfListOfInt anOrder;
5848 ::SMESH_Mesh& mesh = GetImpl();
5850 // collect submeshes and detect concurrent algorithms and hypothesises
5851 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5853 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5854 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5855 ::SMESH_subMesh* sm = (*i_sm).second;
5857 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5859 // list of assigned hypothesises
5860 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5861 // Find out dimensions where the submesh can be concurrent.
5862 // We define the dimensions by algo of each of hypotheses in hypList
5863 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5864 for( ; hypIt != hypList.end(); hypIt++ ) {
5865 SMESH_Algo* anAlgo = 0;
5866 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5867 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5868 // hyp it-self is algo
5869 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5871 // try to find algorithm with help of sub-shapes
5872 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5873 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5874 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5877 continue; // no algorithm assigned to a current submesh
5879 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5880 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5882 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5883 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5884 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5886 } // end iterations on submesh
5888 // iterate on created dimension-hypotheses and check for concurrents
5889 for ( int i = 0; i < 4; i++ ) {
5890 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5891 // check for concurrents in own and other dimensions (step-by-step)
5892 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5893 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5894 const SMESH_DimHyp* dimHyp = *dhIt;
5895 TDimHypList listOfConcurr;
5896 set<int> setOfConcurrIds;
5897 // looking for concurrents and collect into own list
5898 for ( int j = i; j < 4; j++ )
5899 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5900 // check if any concurrents found
5901 if ( listOfConcurr.size() > 0 ) {
5902 // add own submesh to list of concurrent
5903 addInOrderOfPriority( dimHyp, listOfConcurr );
5904 list<int> listOfConcurrIds;
5905 TDimHypList::iterator hypIt = listOfConcurr.begin();
5906 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5907 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5908 anOrder.push_back( listOfConcurrIds );
5913 removeDimHyps(dimHypListArr);
5915 // now, minimise the number of concurrent groups
5916 // Here we assume that lists of submeshes can have same submesh
5917 // in case of multi-dimension algorithms, as result
5918 // list with common submesh has to be united into one list
5920 TListOfListOfInt::iterator listIt = anOrder.begin();
5921 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5922 unionLists( *listIt, anOrder, listIndx + 1 );
5928 //=============================================================================
5930 * \brief Set submesh object order
5931 * \param theSubMeshArray submesh array order
5933 //=============================================================================
5935 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5938 _preMeshInfo->ForgetOrLoad();
5941 ::SMESH_Mesh& mesh = GetImpl();
5943 TPythonDump aPythonDump; // prevent dump of called methods
5944 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5946 TListOfListOfInt subMeshOrder;
5947 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5949 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5950 TListOfInt subMeshIds;
5952 aPythonDump << ", ";
5953 aPythonDump << "[ ";
5954 // Collect subMeshes which should be clear
5955 // do it list-by-list, because modification of submesh order
5956 // take effect between concurrent submeshes only
5957 set<const SMESH_subMesh*> subMeshToClear;
5958 list<const SMESH_subMesh*> subMeshList;
5959 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5961 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5963 aPythonDump << ", ";
5964 aPythonDump << subMesh;
5965 subMeshIds.push_back( subMesh->GetId() );
5966 // detect common parts of submeshes
5967 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5968 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5970 aPythonDump << " ]";
5971 subMeshOrder.push_back( subMeshIds );
5973 // clear collected submeshes
5974 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5975 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5976 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5977 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5979 aPythonDump << " ])";
5981 mesh.SetMeshOrder( subMeshOrder );
5987 //=============================================================================
5989 * \brief Convert submesh ids into submesh interfaces
5991 //=============================================================================
5993 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5994 SMESH::submesh_array_array& theResOrder,
5995 const bool theIsDump)
5997 int nbSet = theIdsOrder.size();
5998 TPythonDump aPythonDump; // prevent dump of called methods
6000 aPythonDump << "[ ";
6001 theResOrder.length(nbSet);
6002 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6004 for( ; it != theIdsOrder.end(); it++ ) {
6005 // translate submesh identificators into submesh objects
6006 // takeing into account real number of concurrent lists
6007 const TListOfInt& aSubOrder = (*it);
6008 if (!aSubOrder.size())
6011 aPythonDump << "[ ";
6012 // convert shape indeces into interfaces
6013 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6014 aResSubSet->length(aSubOrder.size());
6015 TListOfInt::const_iterator subIt = aSubOrder.begin();
6017 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6018 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6020 SMESH::SMESH_subMesh_var subMesh =
6021 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6024 aPythonDump << ", ";
6025 aPythonDump << subMesh;
6027 aResSubSet[ j++ ] = subMesh;
6030 aPythonDump << " ]";
6032 theResOrder[ listIndx++ ] = aResSubSet;
6034 // correct number of lists
6035 theResOrder.length( listIndx );
6038 // finilise python dump
6039 aPythonDump << " ]";
6040 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6044 //================================================================================
6046 // Implementation of SMESH_MeshPartDS
6048 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6049 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6051 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6052 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6054 _meshDS = mesh_i->GetImpl().GetMeshDS();
6056 SetPersistentId( _meshDS->GetPersistentId() );
6058 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6060 // <meshPart> is the whole mesh
6061 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6063 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6064 myGroupSet = _meshDS->GetGroups();
6069 SMESH::long_array_var anIDs = meshPart->GetIDs();
6070 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6071 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6073 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6074 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6075 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6080 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6081 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6082 if ( _elements[ e->GetType() ].insert( e ).second )
6085 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6086 while ( nIt->more() )
6088 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6089 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6096 ShapeToMesh( _meshDS->ShapeToMesh() );
6098 _meshDS = 0; // to enforce iteration on _elements and _nodes
6101 // -------------------------------------------------------------------------------------
6102 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6103 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6106 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6107 for ( ; partIt != meshPart.end(); ++partIt )
6108 if ( const SMDS_MeshElement * e = *partIt )
6109 if ( _elements[ e->GetType() ].insert( e ).second )
6112 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6113 while ( nIt->more() )
6115 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6116 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6122 // -------------------------------------------------------------------------------------
6123 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6125 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6127 typedef SMDS_SetIterator
6128 <const SMDS_MeshElement*,
6129 TIDSortedElemSet::const_iterator,
6130 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6131 SMDS_MeshElement::GeomFilter
6134 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6136 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6137 _elements[type].end(),
6138 SMDS_MeshElement::GeomFilter( geomType )));
6140 // -------------------------------------------------------------------------------------
6141 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6143 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6145 typedef SMDS_SetIterator
6146 <const SMDS_MeshElement*,
6147 TIDSortedElemSet::const_iterator,
6148 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6149 SMDS_MeshElement::EntityFilter
6152 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6154 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6155 _elements[type].end(),
6156 SMDS_MeshElement::EntityFilter( entity )));
6158 // -------------------------------------------------------------------------------------
6159 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6161 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6162 if ( type == SMDSAbs_All && !_meshDS )
6164 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6166 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6167 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6169 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6171 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6172 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6174 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6175 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6177 // -------------------------------------------------------------------------------------
6178 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6179 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6181 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6182 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6183 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6185 // -------------------------------------------------------------------------------------
6186 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6187 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6188 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6189 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6190 #undef _GET_ITER_DEFINE
6192 // END Implementation of SMESH_MeshPartDS
6194 //================================================================================