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_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
100 int SMESH_Mesh_i::_idGenerator = 0;
102 //=============================================================================
106 //=============================================================================
108 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
110 : SALOME::GenericObj_i( thePOA )
114 _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 cached shapes if no more meshes remain; (the cache 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::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
243 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
244 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
250 catch(SALOME_Exception & S_ex) {
251 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
253 return aShapeObj._retn();
256 //================================================================================
258 * \brief Return false if the mesh is not yet fully loaded from the study file
260 //================================================================================
262 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
264 Unexpect aCatch(SALOME_SalomeException);
265 return !_preMeshInfo;
268 //================================================================================
270 * \brief Load full mesh data from the study file
272 //================================================================================
274 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->FullLoadFromFile();
281 //================================================================================
283 * \brief Remove all nodes and elements
285 //================================================================================
287 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
289 Unexpect aCatch(SALOME_SalomeException);
291 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
295 //CheckGeomGroupModif(); // issue 20145
297 catch(SALOME_Exception & S_ex) {
298 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
301 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
303 SMESH::SMESH_Mesh_var mesh = _this();
304 _gen_i->UpdateIcons( mesh );
307 //================================================================================
309 * \brief Remove all nodes and elements for indicated shape
311 //================================================================================
313 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
314 throw (SALOME::SALOME_Exception)
316 Unexpect aCatch(SALOME_SalomeException);
318 _preMeshInfo->FullLoadFromFile();
321 _impl->ClearSubMesh( ShapeID );
323 catch(SALOME_Exception & S_ex) {
324 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
326 _impl->GetMeshDS()->Modified();
328 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
331 //=============================================================================
333 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
335 //=============================================================================
337 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
339 SMESH::DriverMED_ReadStatus res;
342 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
343 res = SMESH::DRS_OK; break;
344 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
345 res = SMESH::DRS_EMPTY; break;
346 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
347 res = SMESH::DRS_WARN_RENUMBER; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
349 res = SMESH::DRS_WARN_SKIP_ELEM; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
351 res = SMESH::DRS_WARN_DESCENDING; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
354 res = SMESH::DRS_FAIL; break;
359 //=============================================================================
361 * Convert ::SMESH_ComputeError to SMESH::ComputeError
363 //=============================================================================
365 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
367 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
368 errVar->subShapeID = -1;
369 errVar->hasBadMesh = false;
371 if ( !errorPtr || errorPtr->IsOK() )
373 errVar->code = SMESH::COMPERR_OK;
377 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
378 errVar->comment = errorPtr->myComment.c_str();
380 return errVar._retn();
383 //=============================================================================
387 * Imports mesh data from MED file
389 //=============================================================================
391 SMESH::DriverMED_ReadStatus
392 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
393 throw ( SALOME::SALOME_Exception )
395 Unexpect aCatch(SALOME_SalomeException);
398 status = _impl->MEDToMesh( theFileName, theMeshName );
400 catch( SALOME_Exception& S_ex ) {
401 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
404 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
407 CreateGroupServants();
409 int major, minor, release;
410 major = minor = release = 0;
411 MED::GetMEDVersion(theFileName, major, minor, release);
412 _medFileInfo = new SMESH::MedFileInfo();
413 _medFileInfo->fileName = theFileName;
414 _medFileInfo->fileSize = 0;
415 _medFileInfo->major = major;
416 _medFileInfo->minor = minor;
417 _medFileInfo->release = release;
418 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
420 return ConvertDriverMEDReadStatus(status);
423 //================================================================================
425 * \brief Imports mesh data from the CGNS file
427 //================================================================================
429 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
430 const int theMeshIndex,
431 std::string& theMeshName )
432 throw ( SALOME::SALOME_Exception )
434 Unexpect aCatch(SALOME_SalomeException);
437 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
439 catch( SALOME_Exception& S_ex ) {
440 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
443 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
446 CreateGroupServants();
448 return ConvertDriverMEDReadStatus(status);
451 //=============================================================================
455 * Imports mesh data from MED file
457 //=============================================================================
459 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
460 throw ( SALOME::SALOME_Exception )
464 // Read mesh with name = <theMeshName> into SMESH_Mesh
465 _impl->UNVToMesh( theFileName );
467 CreateGroupServants();
469 SMESH_CATCH( SMESH::throwCorbaException );
474 //=============================================================================
478 * Imports mesh data from STL file
480 //=============================================================================
481 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
482 throw ( SALOME::SALOME_Exception )
486 // Read mesh with name = <theMeshName> into SMESH_Mesh
487 std::string name = _impl->STLToMesh( theFileName );
490 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
491 _gen_i->SetName( meshSO, name.c_str() );
494 SMESH_CATCH( SMESH::throwCorbaException );
499 //================================================================================
501 * \brief Function used in SMESH_CATCH by ImportGMFFile()
503 //================================================================================
507 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
509 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
513 //================================================================================
515 * \brief Imports data from a GMF file and returns an error description
517 //================================================================================
519 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
520 bool theMakeRequiredGroups )
521 throw (SALOME::SALOME_Exception)
523 SMESH_ComputeErrorPtr error;
526 #define SMESH_CAUGHT error =
529 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
531 SMESH_CATCH( exceptionToComputeError );
535 CreateGroupServants();
537 return ConvertComputeError( error );
540 //=============================================================================
544 //=============================================================================
546 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
548 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
549 (SMESH_Hypothesis::Hypothesis_Status theStatus)
552 RETURNCASE( HYP_OK );
553 RETURNCASE( HYP_MISSING );
554 RETURNCASE( HYP_CONCURRENT );
555 RETURNCASE( HYP_BAD_PARAMETER );
556 RETURNCASE( HYP_HIDDEN_ALGO );
557 RETURNCASE( HYP_HIDING_ALGO );
558 RETURNCASE( HYP_UNKNOWN_FATAL );
559 RETURNCASE( HYP_INCOMPATIBLE );
560 RETURNCASE( HYP_NOTCONFORM );
561 RETURNCASE( HYP_ALREADY_EXIST );
562 RETURNCASE( HYP_BAD_DIM );
563 RETURNCASE( HYP_BAD_SUBSHAPE );
564 RETURNCASE( HYP_BAD_GEOMETRY );
565 RETURNCASE( HYP_NEED_SHAPE );
566 RETURNCASE( HYP_INCOMPAT_HYPS );
569 return SMESH::HYP_UNKNOWN_FATAL;
572 //=============================================================================
576 * calls internal addHypothesis() and then adds a reference to <anHyp> under
577 * the SObject actually having a reference to <aSubShape>.
578 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
580 //=============================================================================
582 SMESH::Hypothesis_Status
583 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
584 SMESH::SMESH_Hypothesis_ptr anHyp,
585 CORBA::String_out anErrorText)
586 throw(SALOME::SALOME_Exception)
588 Unexpect aCatch(SALOME_SalomeException);
590 _preMeshInfo->ForgetOrLoad();
593 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
594 anErrorText = error.c_str();
596 SMESH::SMESH_Mesh_var mesh( _this() );
597 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
599 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
600 _gen_i->UpdateIcons( mesh );
602 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
604 // Update Python script
605 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
606 << aSubShape << ", " << anHyp << " )";
608 return ConvertHypothesisStatus(status);
611 //=============================================================================
615 //=============================================================================
617 SMESH_Hypothesis::Hypothesis_Status
618 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
619 SMESH::SMESH_Hypothesis_ptr anHyp,
620 std::string* anErrorText)
622 if(MYDEBUG) MESSAGE("addHypothesis");
624 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
625 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
627 if (CORBA::is_nil( anHyp ))
628 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
630 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
633 TopoDS_Shape myLocSubShape;
634 //use PseudoShape in case if mesh has no shape
636 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
638 myLocSubShape = _impl->GetShapeToMesh();
640 const int hypId = anHyp->GetId();
642 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
643 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
645 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
647 // assure there is a corresponding submesh
648 if ( !_impl->IsMainShape( myLocSubShape )) {
649 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
650 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
651 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
654 else if ( anErrorText )
656 *anErrorText = error;
659 catch(SALOME_Exception & S_ex)
661 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
666 //=============================================================================
670 //=============================================================================
672 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
673 SMESH::SMESH_Hypothesis_ptr anHyp)
674 throw(SALOME::SALOME_Exception)
676 Unexpect aCatch(SALOME_SalomeException);
678 _preMeshInfo->ForgetOrLoad();
680 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
681 SMESH::SMESH_Mesh_var mesh = _this();
683 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
685 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
686 _gen_i->UpdateIcons( mesh );
688 // Update Python script
689 if(_impl->HasShapeToMesh())
690 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
691 << aSubShape << ", " << anHyp << " )";
693 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
696 return ConvertHypothesisStatus(status);
699 //=============================================================================
703 //=============================================================================
705 SMESH_Hypothesis::Hypothesis_Status
706 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
707 SMESH::SMESH_Hypothesis_ptr anHyp)
709 if(MYDEBUG) MESSAGE("removeHypothesis()");
711 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
712 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
714 if (CORBA::is_nil( anHyp ))
715 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
717 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
720 TopoDS_Shape myLocSubShape;
721 //use PseudoShape in case if mesh has no shape
722 if( _impl->HasShapeToMesh() )
723 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
725 myLocSubShape = _impl->GetShapeToMesh();
727 const int hypId = anHyp->GetId();
728 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
729 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
731 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
735 catch(SALOME_Exception & S_ex)
737 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
742 //=============================================================================
746 //=============================================================================
748 SMESH::ListOfHypothesis *
749 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
750 throw(SALOME::SALOME_Exception)
752 Unexpect aCatch(SALOME_SalomeException);
753 if (MYDEBUG) MESSAGE("GetHypothesisList");
754 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
755 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
757 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
760 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
761 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
762 myLocSubShape = _impl->GetShapeToMesh();
763 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
764 int i = 0, n = aLocalList.size();
767 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
768 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
769 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
771 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
772 if ( id_hypptr != _mapHypo.end() )
773 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
777 catch(SALOME_Exception & S_ex) {
778 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
781 return aList._retn();
784 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
786 Unexpect aCatch(SALOME_SalomeException);
787 if (MYDEBUG) MESSAGE("GetSubMeshes");
789 SMESH::submesh_array_var aList = new SMESH::submesh_array();
792 TPythonDump aPythonDump;
793 if ( !_mapSubMeshIor.empty() )
797 aList->length( _mapSubMeshIor.size() );
799 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
800 for ( ; it != _mapSubMeshIor.end(); it++ ) {
801 if ( CORBA::is_nil( it->second )) continue;
802 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
804 if (i > 1) aPythonDump << ", ";
805 aPythonDump << it->second;
809 catch(SALOME_Exception & S_ex) {
810 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
813 // Update Python script
814 if ( !_mapSubMeshIor.empty() )
815 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
817 return aList._retn();
820 //=============================================================================
824 //=============================================================================
826 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
827 const char* theName )
828 throw(SALOME::SALOME_Exception)
830 Unexpect aCatch(SALOME_SalomeException);
831 if (CORBA::is_nil(aSubShape))
832 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
834 SMESH::SMESH_subMesh_var subMesh;
835 SMESH::SMESH_Mesh_var aMesh = _this();
837 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
839 //Get or Create the SMESH_subMesh object implementation
841 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
843 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
845 TopoDS_Iterator it( myLocSubShape );
847 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
849 subMesh = getSubMesh( subMeshId );
851 // create a new subMesh object servant if there is none for the shape
852 if ( subMesh->_is_nil() )
853 subMesh = createSubMesh( aSubShape );
854 if ( _gen_i->CanPublishInStudy( subMesh ))
856 SALOMEDS::SObject_wrap aSO =
857 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
858 if ( !aSO->_is_nil()) {
859 // Update Python script
860 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
861 << aSubShape << ", '" << theName << "' )";
865 catch(SALOME_Exception & S_ex) {
866 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
868 return subMesh._retn();
871 //=============================================================================
875 //=============================================================================
877 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
878 throw (SALOME::SALOME_Exception)
882 if ( theSubMesh->_is_nil() )
885 GEOM::GEOM_Object_var aSubShape;
886 // Remove submesh's SObject
887 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
888 if ( !anSO->_is_nil() ) {
889 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
890 SALOMEDS::SObject_wrap anObj, aRef;
891 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
892 anObj->ReferencedObject( aRef.inout() ))
894 CORBA::Object_var obj = aRef->GetObject();
895 aSubShape = GEOM::GEOM_Object::_narrow( obj );
897 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
898 // aSubShape = theSubMesh->GetSubShape();
900 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
901 builder->RemoveObjectWithChildren( anSO );
903 // Update Python script
904 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
907 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
909 _preMeshInfo->ForgetOrLoad();
911 SMESH_CATCH( SMESH::throwCorbaException );
914 //=============================================================================
918 //=============================================================================
920 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
921 const char* theName )
922 throw(SALOME::SALOME_Exception)
924 Unexpect aCatch(SALOME_SalomeException);
926 _preMeshInfo->FullLoadFromFile();
928 SMESH::SMESH_Group_var aNewGroup =
929 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
931 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
933 SMESH::SMESH_Mesh_var mesh = _this();
934 SALOMEDS::SObject_wrap aSO =
935 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
936 if ( !aSO->_is_nil())
937 // Update Python script
938 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
939 << theElemType << ", '" << theName << "' )";
941 return aNewGroup._retn();
944 //=============================================================================
948 //=============================================================================
949 SMESH::SMESH_GroupOnGeom_ptr
950 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
952 GEOM::GEOM_Object_ptr theGeomObj)
953 throw(SALOME::SALOME_Exception)
955 Unexpect aCatch(SALOME_SalomeException);
957 _preMeshInfo->FullLoadFromFile();
959 SMESH::SMESH_GroupOnGeom_var aNewGroup;
961 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
962 if ( !aShape.IsNull() )
965 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
967 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
969 SMESH::SMESH_Mesh_var mesh = _this();
970 SALOMEDS::SObject_wrap aSO =
971 _gen_i->PublishGroup( 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::SObject_wrap aSO =
1019 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1021 if ( !aSO->_is_nil())
1022 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1023 << theElemType << ", '" << theName << "', " << theFilter << " )";
1025 return aNewGroup._retn();
1028 //=============================================================================
1032 //=============================================================================
1034 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1035 throw (SALOME::SALOME_Exception)
1037 if ( theGroup->_is_nil() )
1042 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1046 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1047 if ( !aGroupSO->_is_nil() )
1049 // Update Python script
1050 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1052 // Remove group's SObject
1053 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1054 builder->RemoveObjectWithChildren( aGroupSO );
1056 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1058 // Remove the group from SMESH data structures
1059 removeGroup( aGroup->GetLocalID() );
1061 SMESH_CATCH( SMESH::throwCorbaException );
1064 //=============================================================================
1066 * Remove group with its contents
1068 //=============================================================================
1070 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1071 throw (SALOME::SALOME_Exception)
1075 _preMeshInfo->FullLoadFromFile();
1077 if ( theGroup->_is_nil() )
1080 vector<int> nodeIds; // to remove nodes becoming free
1081 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1082 if ( !isNodal && !theGroup->IsEmpty() )
1084 CORBA::Long elemID = theGroup->GetID( 1 );
1085 int nbElemNodes = GetElemNbNodes( elemID );
1086 if ( nbElemNodes > 0 )
1087 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1090 // Retrieve contents
1091 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1092 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1093 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1094 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1095 elems.assign( elemBeg, elemEnd );
1097 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1100 RemoveGroup( theGroup );
1103 for ( size_t i = 0; i < elems.size(); ++i )
1105 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1109 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1110 nodeIds.push_back( nIt->next()->GetID() );
1112 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1116 _impl->GetMeshDS()->RemoveElement( elems[i] );
1120 // Remove free nodes
1121 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1122 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1123 if ( n->NbInverseElements() == 0 )
1124 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1126 // Update Python script (theGroup must be alive for this)
1127 pyDump << SMESH::SMESH_Mesh_var(_this())
1128 << ".RemoveGroupWithContents( " << theGroup << " )";
1130 SMESH_CATCH( SMESH::throwCorbaException );
1133 //================================================================================
1135 * \brief Get the list of groups existing in the mesh
1136 * \retval SMESH::ListOfGroups * - list of groups
1138 //================================================================================
1140 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1142 Unexpect aCatch(SALOME_SalomeException);
1143 if (MYDEBUG) MESSAGE("GetGroups");
1145 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1148 TPythonDump aPythonDump;
1149 if ( !_mapGroups.empty() )
1151 aPythonDump << "[ ";
1153 aList->length( _mapGroups.size() );
1155 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1156 for ( ; it != _mapGroups.end(); it++ ) {
1157 if ( CORBA::is_nil( it->second )) continue;
1158 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1160 if (i > 1) aPythonDump << ", ";
1161 aPythonDump << it->second;
1165 catch(SALOME_Exception & S_ex) {
1166 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1168 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1170 return aList._retn();
1173 //=============================================================================
1175 * Get number of groups existing in the mesh
1177 //=============================================================================
1179 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1181 Unexpect aCatch(SALOME_SalomeException);
1182 return _mapGroups.size();
1185 //=============================================================================
1187 * New group including all mesh elements present in initial groups is created.
1189 //=============================================================================
1191 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1192 SMESH::SMESH_GroupBase_ptr theGroup2,
1193 const char* theName )
1194 throw (SALOME::SALOME_Exception)
1196 SMESH::SMESH_Group_var aResGrp;
1200 _preMeshInfo->FullLoadFromFile();
1202 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1203 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1205 if ( theGroup1->GetType() != theGroup2->GetType() )
1206 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1211 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1212 if ( aResGrp->_is_nil() )
1213 return SMESH::SMESH_Group::_nil();
1215 aResGrp->AddFrom( theGroup1 );
1216 aResGrp->AddFrom( theGroup2 );
1218 // Update Python script
1219 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1220 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1222 SMESH_CATCH( SMESH::throwCorbaException );
1224 return aResGrp._retn();
1227 //=============================================================================
1229 * \brief New group including all mesh elements present in initial groups is created.
1230 * \param theGroups list of groups
1231 * \param theName name of group to be created
1232 * \return pointer to the new group
1234 //=============================================================================
1236 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1237 const char* theName )
1238 throw (SALOME::SALOME_Exception)
1240 SMESH::SMESH_Group_var aResGrp;
1243 _preMeshInfo->FullLoadFromFile();
1246 return SMESH::SMESH_Group::_nil();
1251 SMESH::ElementType aType = SMESH::ALL;
1252 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1254 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1255 if ( CORBA::is_nil( aGrp ) )
1257 if ( aType == SMESH::ALL )
1258 aType = aGrp->GetType();
1259 else if ( aType != aGrp->GetType() )
1260 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1263 if ( aType == SMESH::ALL )
1264 return SMESH::SMESH_Group::_nil();
1269 aResGrp = CreateGroup( aType, theName );
1270 if ( aResGrp->_is_nil() )
1271 return SMESH::SMESH_Group::_nil();
1273 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1274 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1276 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1277 if ( !CORBA::is_nil( aGrp ) )
1279 aResGrp->AddFrom( aGrp );
1280 if ( g > 0 ) pyDump << ", ";
1284 pyDump << " ], '" << theName << "' )";
1286 SMESH_CATCH( SMESH::throwCorbaException );
1288 return aResGrp._retn();
1291 //=============================================================================
1293 * New group is created. All mesh elements that are
1294 * present in both initial groups are added to the new one.
1296 //=============================================================================
1298 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1299 SMESH::SMESH_GroupBase_ptr theGroup2,
1300 const char* theName )
1301 throw (SALOME::SALOME_Exception)
1303 SMESH::SMESH_Group_var aResGrp;
1308 _preMeshInfo->FullLoadFromFile();
1310 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1311 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1313 if ( theGroup1->GetType() != theGroup2->GetType() )
1314 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1318 // Create Intersection
1319 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1320 if ( aResGrp->_is_nil() )
1321 return aResGrp._retn();
1323 SMESHDS_GroupBase* groupDS1 = 0;
1324 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1325 groupDS1 = grp_i->GetGroupDS();
1327 SMESHDS_GroupBase* groupDS2 = 0;
1328 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1329 groupDS2 = grp_i->GetGroupDS();
1331 SMESHDS_Group* resGroupDS = 0;
1332 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1333 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1335 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1337 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1338 while ( elemIt1->more() )
1340 const SMDS_MeshElement* e = elemIt1->next();
1341 if ( groupDS2->Contains( e ))
1342 resGroupDS->SMDSGroup().Add( e );
1345 // Update Python script
1346 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1347 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1349 SMESH_CATCH( SMESH::throwCorbaException );
1351 return aResGrp._retn();
1354 //=============================================================================
1356 \brief Intersect list of groups. New group is created. All mesh elements that
1357 are present in all initial groups simultaneously are added to the new one.
1358 \param theGroups list of groups
1359 \param theName name of group to be created
1360 \return pointer on the group
1362 //=============================================================================
1363 SMESH::SMESH_Group_ptr
1364 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1365 const char* theName )
1366 throw (SALOME::SALOME_Exception)
1368 SMESH::SMESH_Group_var aResGrp;
1373 _preMeshInfo->FullLoadFromFile();
1376 return SMESH::SMESH_Group::_nil();
1378 // check types and get SMESHDS_GroupBase's
1379 SMESH::ElementType aType = SMESH::ALL;
1380 vector< SMESHDS_GroupBase* > groupVec;
1381 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1383 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1384 if ( CORBA::is_nil( aGrp ) )
1386 if ( aType == SMESH::ALL )
1387 aType = aGrp->GetType();
1388 else if ( aType != aGrp->GetType() )
1389 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1392 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1393 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1395 if ( grpDS->IsEmpty() )
1400 groupVec.push_back( grpDS );
1403 if ( aType == SMESH::ALL ) // all groups are nil
1404 return SMESH::SMESH_Group::_nil();
1409 aResGrp = CreateGroup( aType, theName );
1411 SMESHDS_Group* resGroupDS = 0;
1412 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1413 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1414 if ( !resGroupDS || groupVec.empty() )
1415 return aResGrp._retn();
1418 size_t i, nb = groupVec.size();
1419 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1420 while ( elemIt1->more() )
1422 const SMDS_MeshElement* e = elemIt1->next();
1424 for ( i = 1; ( i < nb && inAll ); ++i )
1425 inAll = groupVec[i]->Contains( e );
1428 resGroupDS->SMDSGroup().Add( e );
1431 // Update Python script
1432 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1433 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1435 SMESH_CATCH( SMESH::throwCorbaException );
1437 return aResGrp._retn();
1440 //=============================================================================
1442 * New group is created. All mesh elements that are present in
1443 * a main group but is not present in a tool group are added to the new one
1445 //=============================================================================
1447 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1448 SMESH::SMESH_GroupBase_ptr theGroup2,
1449 const char* theName )
1450 throw (SALOME::SALOME_Exception)
1452 SMESH::SMESH_Group_var aResGrp;
1457 _preMeshInfo->FullLoadFromFile();
1459 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1460 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1462 if ( theGroup1->GetType() != theGroup2->GetType() )
1463 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1467 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1468 if ( aResGrp->_is_nil() )
1469 return aResGrp._retn();
1471 SMESHDS_GroupBase* groupDS1 = 0;
1472 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1473 groupDS1 = grp_i->GetGroupDS();
1475 SMESHDS_GroupBase* groupDS2 = 0;
1476 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1477 groupDS2 = grp_i->GetGroupDS();
1479 SMESHDS_Group* resGroupDS = 0;
1480 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1481 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1483 if ( groupDS1 && groupDS2 && resGroupDS )
1485 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1486 while ( elemIt1->more() )
1488 const SMDS_MeshElement* e = elemIt1->next();
1489 if ( !groupDS2->Contains( e ))
1490 resGroupDS->SMDSGroup().Add( e );
1493 // Update Python script
1494 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1495 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1497 SMESH_CATCH( SMESH::throwCorbaException );
1499 return aResGrp._retn();
1502 //=============================================================================
1504 \brief Cut lists of groups. New group is created. All mesh elements that are
1505 present in main groups but do not present in tool groups are added to the new one
1506 \param theMainGroups list of main groups
1507 \param theToolGroups list of tool groups
1508 \param theName name of group to be created
1509 \return pointer on the group
1511 //=============================================================================
1512 SMESH::SMESH_Group_ptr
1513 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1514 const SMESH::ListOfGroups& theToolGroups,
1515 const char* theName )
1516 throw (SALOME::SALOME_Exception)
1518 SMESH::SMESH_Group_var aResGrp;
1523 _preMeshInfo->FullLoadFromFile();
1526 return SMESH::SMESH_Group::_nil();
1528 // check types and get SMESHDS_GroupBase's
1529 SMESH::ElementType aType = SMESH::ALL;
1530 vector< SMESHDS_GroupBase* > toolGroupVec;
1531 vector< SMDS_ElemIteratorPtr > mainIterVec;
1533 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1535 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1536 if ( CORBA::is_nil( aGrp ) )
1538 if ( aType == SMESH::ALL )
1539 aType = aGrp->GetType();
1540 else if ( aType != aGrp->GetType() )
1541 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1543 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1544 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1545 if ( !grpDS->IsEmpty() )
1546 mainIterVec.push_back( grpDS->GetElements() );
1548 if ( aType == SMESH::ALL ) // all main groups are nil
1549 return SMESH::SMESH_Group::_nil();
1550 if ( mainIterVec.empty() ) // all main groups are empty
1551 return aResGrp._retn();
1553 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1555 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1556 if ( CORBA::is_nil( aGrp ) )
1558 if ( aType != aGrp->GetType() )
1559 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1561 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1562 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1563 toolGroupVec.push_back( grpDS );
1569 aResGrp = CreateGroup( aType, theName );
1571 SMESHDS_Group* resGroupDS = 0;
1572 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1573 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1575 return aResGrp._retn();
1578 size_t i, nb = toolGroupVec.size();
1579 SMDS_ElemIteratorPtr mainElemIt
1580 ( new SMDS_IteratorOnIterators
1581 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1582 while ( mainElemIt->more() )
1584 const SMDS_MeshElement* e = mainElemIt->next();
1586 for ( i = 0; ( i < nb && !isIn ); ++i )
1587 isIn = toolGroupVec[i]->Contains( e );
1590 resGroupDS->SMDSGroup().Add( e );
1593 // Update Python script
1594 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1595 << ".CutListOfGroups( " << theMainGroups << ", "
1596 << theToolGroups << ", '" << theName << "' )";
1598 SMESH_CATCH( SMESH::throwCorbaException );
1600 return aResGrp._retn();
1603 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1605 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1606 bool & toStopChecking )
1608 toStopChecking = ( nbCommon < nbChecked );
1609 return nbCommon == nbNodes;
1611 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1612 bool & toStopChecking )
1614 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1615 return nbCommon == nbCorners;
1617 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1618 bool & toStopChecking )
1620 return nbCommon > 0;
1622 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1623 bool & toStopChecking )
1625 return nbCommon >= (nbNodes+1) / 2;
1629 //=============================================================================
1631 * Create a group of entities basing on nodes of other groups.
1632 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1633 * \param [in] anElemType - a type of elements to include to the new group.
1634 * \param [in] theName - a name of the new group.
1635 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1636 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1637 * new group provided that it is based on nodes of an element of \a aListOfGroups
1638 * \return SMESH_Group - the created group
1640 // IMP 19939, bug 22010, IMP 22635
1641 //=============================================================================
1643 SMESH::SMESH_Group_ptr
1644 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1645 SMESH::ElementType theElemType,
1646 const char* theName,
1647 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1648 CORBA::Boolean theUnderlyingOnly)
1649 throw (SALOME::SALOME_Exception)
1651 SMESH::SMESH_Group_var aResGrp;
1655 _preMeshInfo->FullLoadFromFile();
1657 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1659 if ( !theName || !aMeshDS )
1660 return SMESH::SMESH_Group::_nil();
1662 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1664 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1665 SMESH_Comment nbCoNoStr( "SMESH.");
1666 switch ( theNbCommonNodes ) {
1667 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1668 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1669 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1670 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1671 default: return aResGrp._retn();
1673 int nbChecked, nbCommon, nbNodes, nbCorners;
1679 aResGrp = CreateGroup( theElemType, theName );
1680 if ( aResGrp->_is_nil() )
1681 return SMESH::SMESH_Group::_nil();
1683 SMESHDS_GroupBase* groupBaseDS =
1684 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1685 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1687 vector<bool> isNodeInGroups;
1689 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1691 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1692 if ( CORBA::is_nil( aGrp ) )
1694 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1695 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1698 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1699 if ( !elIt ) continue;
1701 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1703 while ( elIt->more() ) {
1704 const SMDS_MeshElement* el = elIt->next();
1705 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1706 while ( nIt->more() )
1707 resGroupCore.Add( nIt->next() );
1710 // get elements of theElemType based on nodes of every element of group
1711 else if ( theUnderlyingOnly )
1713 while ( elIt->more() )
1715 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1716 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1717 TIDSortedElemSet checkedElems;
1718 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1719 while ( nIt->more() )
1721 const SMDS_MeshNode* n = nIt->next();
1722 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1723 // check nodes of elements of theElemType around el
1724 while ( elOfTypeIt->more() )
1726 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1727 if ( !checkedElems.insert( elOfType ).second ) continue;
1728 nbNodes = elOfType->NbNodes();
1729 nbCorners = elOfType->NbCornerNodes();
1731 bool toStopChecking = false;
1732 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1733 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1734 if ( elNodes.count( nIt2->next() ) &&
1735 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1737 resGroupCore.Add( elOfType );
1744 // get all nodes of elements of groups
1747 while ( elIt->more() )
1749 const SMDS_MeshElement* el = elIt->next(); // an element of group
1750 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1751 while ( nIt->more() )
1753 const SMDS_MeshNode* n = nIt->next();
1754 if ( n->GetID() >= (int) isNodeInGroups.size() )
1755 isNodeInGroups.resize( n->GetID() + 1, false );
1756 isNodeInGroups[ n->GetID() ] = true;
1762 // Get elements of theElemType based on a certain number of nodes of elements of groups
1763 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1765 const SMDS_MeshNode* n;
1766 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1767 const int isNodeInGroupsSize = isNodeInGroups.size();
1768 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1770 if ( !isNodeInGroups[ iN ] ||
1771 !( n = aMeshDS->FindNode( iN )))
1774 // check nodes of elements of theElemType around n
1775 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1776 while ( elOfTypeIt->more() )
1778 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1779 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1784 nbNodes = elOfType->NbNodes();
1785 nbCorners = elOfType->NbCornerNodes();
1787 bool toStopChecking = false;
1788 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1789 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1791 const int nID = nIt->next()->GetID();
1792 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1793 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1795 resGroupCore.Add( elOfType );
1803 // Update Python script
1804 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1805 << ".CreateDimGroup( "
1806 << theGroups << ", " << theElemType << ", '" << theName << "', "
1807 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1809 SMESH_CATCH( SMESH::throwCorbaException );
1811 return aResGrp._retn();
1814 //================================================================================
1816 * \brief Remember GEOM group data
1818 //================================================================================
1820 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1821 CORBA::Object_ptr theSmeshObj)
1823 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1826 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1827 if ( groupSO->_is_nil() )
1830 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1831 GEOM::GEOM_IGroupOperations_wrap groupOp =
1832 geomGen->GetIGroupOperations();
1833 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1836 _geomGroupData.push_back( TGeomGroupData() );
1837 TGeomGroupData & groupData = _geomGroupData.back();
1839 CORBA::String_var entry = groupSO->GetID();
1840 groupData._groupEntry = entry.in();
1842 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1843 groupData._indices.insert( ids[i] );
1845 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1846 // shape index in SMESHDS
1847 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1848 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1851 //================================================================================
1853 * Remove GEOM group data relating to removed smesh object
1855 //================================================================================
1857 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1859 list<TGeomGroupData>::iterator
1860 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1861 for ( ; data != dataEnd; ++data ) {
1862 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1863 _geomGroupData.erase( data );
1869 //================================================================================
1871 * \brief Return new group contents if it has been changed and update group data
1873 //================================================================================
1875 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1877 TopoDS_Shape newShape;
1880 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
1881 if ( !groupSO->_is_nil() )
1883 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1884 if ( CORBA::is_nil( groupObj )) return newShape;
1885 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1887 // get indices of group items
1888 set<int> curIndices;
1889 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1890 GEOM::GEOM_IGroupOperations_wrap groupOp =
1891 geomGen->GetIGroupOperations();
1892 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1893 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1894 curIndices.insert( ids[i] );
1896 if ( groupData._indices == curIndices )
1897 return newShape; // group not changed
1900 groupData._indices = curIndices;
1902 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1903 if ( !geomClient ) return newShape;
1904 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1905 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1906 newShape = _gen_i->GeomObjectToShape( geomGroup );
1909 if ( newShape.IsNull() ) {
1910 // geom group becomes empty - return empty compound
1911 TopoDS_Compound compound;
1912 BRep_Builder().MakeCompound(compound);
1913 newShape = compound;
1920 //-----------------------------------------------------------------------------
1922 * \brief Storage of shape and index used in CheckGeomGroupModif()
1924 struct TIndexedShape
1927 TopoDS_Shape _shape;
1928 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1930 //-----------------------------------------------------------------------------
1932 * \brief Data to re-create a group on geometry
1934 struct TGroupOnGeomData
1938 SMDSAbs_ElementType _type;
1940 Quantity_Color _color;
1944 //=============================================================================
1946 * \brief Update data if geometry changes
1950 //=============================================================================
1952 void SMESH_Mesh_i::CheckGeomModif()
1954 if ( !_impl->HasShapeToMesh() ) 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 modify 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 CORBA::Long nbEntities = NbNodes() + NbElements();
2104 // Check if group contents changed
2106 typedef map< string, TopoDS_Shape > TEntry2Geom;
2107 TEntry2Geom newGroupContents;
2109 list<TGeomGroupData>::iterator
2110 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2111 for ( ; data != dataEnd; ++data )
2113 pair< TEntry2Geom::iterator, bool > it_new =
2114 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2115 bool processedGroup = !it_new.second;
2116 TopoDS_Shape& newShape = it_new.first->second;
2117 if ( !processedGroup )
2118 newShape = newGroupShape( *data );
2119 if ( newShape.IsNull() )
2120 continue; // no changes
2123 _preMeshInfo->ForgetOrLoad();
2125 if ( processedGroup ) { // update group indices
2126 list<TGeomGroupData>::iterator data2 = data;
2127 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2128 data->_indices = data2->_indices;
2131 // Update SMESH objects according to new GEOM group contents
2133 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2134 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2136 int oldID = submesh->GetId();
2137 if ( !_mapSubMeshIor.count( oldID ))
2139 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2141 // update hypotheses
2142 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2143 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2144 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2146 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2147 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2149 // care of submeshes
2150 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2151 int newID = newSubmesh->GetId();
2152 if ( newID != oldID ) {
2153 _mapSubMesh [ newID ] = newSubmesh;
2154 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2155 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2156 _mapSubMesh. erase(oldID);
2157 _mapSubMesh_i. erase(oldID);
2158 _mapSubMeshIor.erase(oldID);
2159 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2164 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2165 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2166 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2168 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2170 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2171 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2172 ds->SetShape( newShape );
2177 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2178 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2180 // Remove groups and submeshes basing on removed sub-shapes
2182 TopTools_MapOfShape newShapeMap;
2183 TopoDS_Iterator shapeIt( newShape );
2184 for ( ; shapeIt.More(); shapeIt.Next() )
2185 newShapeMap.Add( shapeIt.Value() );
2187 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2188 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2190 if ( newShapeMap.Contains( shapeIt.Value() ))
2192 TopTools_IndexedMapOfShape oldShapeMap;
2193 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2194 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2196 const TopoDS_Shape& oldShape = oldShapeMap(i);
2197 int oldInd = meshDS->ShapeToIndex( oldShape );
2199 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2200 if ( i_smIor != _mapSubMeshIor.end() ) {
2201 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2204 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2205 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2207 // check if a group bases on oldInd shape
2208 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2209 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2210 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2211 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2213 RemoveGroup( i_grp->second ); // several groups can base on same shape
2214 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2219 // Reassign hypotheses and update groups after setting the new shape to mesh
2221 // collect anassigned hypotheses
2222 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2223 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2224 TShapeHypList assignedHyps;
2225 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2227 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2228 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2229 if ( !hyps.empty() ) {
2230 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2231 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2232 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2235 // collect shapes supporting groups
2236 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2237 TShapeTypeList groupData;
2238 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2239 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2240 for ( ; grIt != groups.end(); ++grIt )
2242 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2244 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2246 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2248 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2249 _impl->ShapeToMesh( newShape );
2251 // reassign hypotheses
2252 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2253 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2255 TIndexedShape& geom = indS_hyps->first;
2256 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2257 int oldID = geom._index;
2258 int newID = meshDS->ShapeToIndex( geom._shape );
2259 if ( oldID == 1 ) { // main shape
2261 geom._shape = newShape;
2265 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2266 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2267 // care of sub-meshes
2268 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2269 if ( newID != oldID ) {
2270 _mapSubMesh [ newID ] = newSubmesh;
2271 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2272 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2273 _mapSubMesh. erase(oldID);
2274 _mapSubMesh_i. erase(oldID);
2275 _mapSubMeshIor.erase(oldID);
2276 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2280 TShapeTypeList::iterator geomType = groupData.begin();
2281 for ( ; geomType != groupData.end(); ++geomType )
2283 const TIndexedShape& geom = geomType->first;
2284 int oldID = geom._index;
2285 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2288 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2289 CORBA::String_var name = groupSO->GetName();
2291 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2293 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2294 group_i->changeLocalId( newID );
2297 break; // everything has been updated
2300 } // loop on group data
2304 CORBA::Long newNbEntities = NbNodes() + NbElements();
2305 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2306 if ( newNbEntities != nbEntities )
2308 // Add all SObjects with icons to soToUpdateIcons
2309 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2311 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2312 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2313 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2315 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2316 i_gr != _mapGroups.end(); ++i_gr ) // groups
2317 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2320 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2321 for ( ; so != soToUpdateIcons.end(); ++so )
2322 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2325 //=============================================================================
2327 * \brief Create standalone group from a group on geometry or filter
2329 //=============================================================================
2331 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2332 throw (SALOME::SALOME_Exception)
2334 SMESH::SMESH_Group_var aGroup;
2339 _preMeshInfo->FullLoadFromFile();
2341 if ( theGroup->_is_nil() )
2342 return aGroup._retn();
2344 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2346 return aGroup._retn();
2348 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2350 const int anId = aGroupToRem->GetLocalID();
2351 if ( !_impl->ConvertToStandalone( anId ) )
2352 return aGroup._retn();
2353 removeGeomGroupData( theGroup );
2355 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2357 // remove old instance of group from own map
2358 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2359 _mapGroups.erase( anId );
2361 SALOMEDS::StudyBuilder_var builder;
2362 SALOMEDS::SObject_wrap aGroupSO;
2363 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2364 if ( !aStudy->_is_nil() ) {
2365 builder = aStudy->NewBuilder();
2366 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2367 if ( !aGroupSO->_is_nil() )
2369 // remove reference to geometry
2370 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2371 for ( ; chItr->More(); chItr->Next() )
2372 // Remove group's child SObject
2373 builder->RemoveObject( chItr->Value() );
2375 // Update Python script
2376 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2377 << ".ConvertToStandalone( " << aGroupSO << " )";
2379 // change icon of Group on Filter
2382 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2383 const int isEmpty = ( elemTypes->length() == 0 );
2386 SALOMEDS::GenericAttribute_wrap anAttr =
2387 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2388 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2389 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2395 // remember new group in own map
2396 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2397 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2399 // register CORBA object for persistence
2400 _gen_i->RegisterObject( aGroup );
2402 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2403 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2404 //aGroup->Register();
2405 aGroupToRem->UnRegister();
2407 SMESH_CATCH( SMESH::throwCorbaException );
2409 return aGroup._retn();
2412 //=============================================================================
2416 //=============================================================================
2418 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2420 if(MYDEBUG) MESSAGE( "createSubMesh" );
2421 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2422 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2423 const int subMeshId = mySubMesh->GetId();
2425 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2426 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2428 _mapSubMesh [subMeshId] = mySubMesh;
2429 _mapSubMesh_i [subMeshId] = subMeshServant;
2430 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2432 subMeshServant->Register();
2434 // register CORBA object for persistence
2435 int nextId = _gen_i->RegisterObject( subMesh );
2436 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2437 else { nextId = 0; } // avoid "unused variable" warning
2439 // to track changes of GEOM groups
2440 addGeomGroupData( theSubShapeObject, subMesh );
2442 return subMesh._retn();
2445 //=======================================================================
2446 //function : getSubMesh
2448 //=======================================================================
2450 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2452 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2453 if ( it == _mapSubMeshIor.end() )
2454 return SMESH::SMESH_subMesh::_nil();
2456 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2459 //=============================================================================
2463 //=============================================================================
2465 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2466 GEOM::GEOM_Object_ptr theSubShapeObject )
2468 bool isHypChanged = false;
2469 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2470 return isHypChanged;
2472 const int subMeshId = theSubMesh->GetId();
2474 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2476 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2478 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2481 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2482 isHypChanged = !hyps.empty();
2483 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2484 for ( ; hyp != hyps.end(); ++hyp )
2485 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2492 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2493 isHypChanged = ( aHypList->length() > 0 );
2494 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2495 removeHypothesis( theSubShapeObject, aHypList[i] );
2498 catch( const SALOME::SALOME_Exception& ) {
2499 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2501 removeGeomGroupData( theSubShapeObject );
2505 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2506 if ( id_smi != _mapSubMesh_i.end() )
2507 id_smi->second->UnRegister();
2509 // remove a CORBA object
2510 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2511 if ( id_smptr != _mapSubMeshIor.end() )
2512 SMESH::SMESH_subMesh_var( id_smptr->second );
2514 _mapSubMesh.erase(subMeshId);
2515 _mapSubMesh_i.erase(subMeshId);
2516 _mapSubMeshIor.erase(subMeshId);
2518 return isHypChanged;
2521 //=============================================================================
2525 //=============================================================================
2527 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2528 const char* theName,
2529 const TopoDS_Shape& theShape,
2530 const SMESH_PredicatePtr& thePredicate )
2532 std::string newName;
2533 if ( !theName || !theName[0] )
2535 std::set< std::string > presentNames;
2536 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2537 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2539 CORBA::String_var name = i_gr->second->GetName();
2540 presentNames.insert( name.in() );
2543 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2544 } while ( !presentNames.insert( newName ).second );
2545 theName = newName.c_str();
2548 SMESH::SMESH_GroupBase_var aGroup;
2549 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2551 SMESH_GroupBase_i* aGroupImpl;
2552 if ( !theShape.IsNull() )
2553 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2554 else if ( thePredicate )
2555 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2557 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2559 aGroup = aGroupImpl->_this();
2560 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2561 aGroupImpl->Register();
2563 // register CORBA object for persistence
2564 int nextId = _gen_i->RegisterObject( aGroup );
2565 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2566 else { nextId = 0; } // avoid "unused variable" warning in release mode
2568 // to track changes of GEOM groups
2569 if ( !theShape.IsNull() ) {
2570 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2571 addGeomGroupData( geom, aGroup );
2574 return aGroup._retn();
2577 //=============================================================================
2579 * SMESH_Mesh_i::removeGroup
2581 * Should be called by ~SMESH_Group_i()
2583 //=============================================================================
2585 void SMESH_Mesh_i::removeGroup( const int theId )
2587 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2588 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2589 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2590 _mapGroups.erase( theId );
2591 removeGeomGroupData( group );
2592 if ( !_impl->RemoveGroup( theId ))
2594 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2595 RemoveGroup( group );
2597 group->UnRegister();
2601 //=============================================================================
2605 //=============================================================================
2607 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2608 throw(SALOME::SALOME_Exception)
2610 SMESH::log_array_var aLog;
2614 _preMeshInfo->FullLoadFromFile();
2616 list < SMESHDS_Command * >logDS = _impl->GetLog();
2617 aLog = new SMESH::log_array;
2619 int lg = logDS.size();
2622 list < SMESHDS_Command * >::iterator its = logDS.begin();
2623 while(its != logDS.end()){
2624 SMESHDS_Command *com = *its;
2625 int comType = com->GetType();
2627 int lgcom = com->GetNumber();
2629 const list < int >&intList = com->GetIndexes();
2630 int inum = intList.size();
2632 list < int >::const_iterator ii = intList.begin();
2633 const list < double >&coordList = com->GetCoords();
2634 int rnum = coordList.size();
2636 list < double >::const_iterator ir = coordList.begin();
2637 aLog[indexLog].commandType = comType;
2638 aLog[indexLog].number = lgcom;
2639 aLog[indexLog].coords.length(rnum);
2640 aLog[indexLog].indexes.length(inum);
2641 for(int i = 0; i < rnum; i++){
2642 aLog[indexLog].coords[i] = *ir;
2643 //MESSAGE(" "<<i<<" "<<ir.Value());
2646 for(int i = 0; i < inum; i++){
2647 aLog[indexLog].indexes[i] = *ii;
2648 //MESSAGE(" "<<i<<" "<<ii.Value());
2657 SMESH_CATCH( SMESH::throwCorbaException );
2659 return aLog._retn();
2663 //=============================================================================
2667 //=============================================================================
2669 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2673 SMESH_CATCH( SMESH::throwCorbaException );
2676 //=============================================================================
2680 //=============================================================================
2682 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2687 //=============================================================================
2690 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2691 // issue 0020918: groups removal is caused by hyp modification
2692 // issue 0021208: to forget not loaded mesh data at hyp modification
2693 struct TCallUp_i : public SMESH_Mesh::TCallUp
2695 SMESH_Mesh_i* _mesh;
2696 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2697 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2698 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2699 virtual void Load () { _mesh->Load(); }
2703 //================================================================================
2705 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2707 //================================================================================
2709 void SMESH_Mesh_i::onHypothesisModified()
2712 _preMeshInfo->ForgetOrLoad();
2714 SMESH::SMESH_Mesh_var mesh = _this();
2715 _gen_i->UpdateIcons( mesh );
2718 //=============================================================================
2722 //=============================================================================
2724 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2726 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2729 _impl->SetCallUp( new TCallUp_i(this));
2732 //=============================================================================
2736 //=============================================================================
2738 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2740 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2744 //=============================================================================
2746 * Return mesh editor
2748 //=============================================================================
2750 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2751 throw (SALOME::SALOME_Exception)
2753 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2757 _preMeshInfo->FullLoadFromFile();
2759 // Create MeshEditor
2761 _editor = new SMESH_MeshEditor_i( this, false );
2762 aMeshEdVar = _editor->_this();
2764 // Update Python script
2765 TPythonDump() << _editor << " = "
2766 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2768 SMESH_CATCH( SMESH::throwCorbaException );
2770 return aMeshEdVar._retn();
2773 //=============================================================================
2775 * Return mesh edition previewer
2777 //=============================================================================
2779 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2780 throw (SALOME::SALOME_Exception)
2782 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2786 _preMeshInfo->FullLoadFromFile();
2788 if ( !_previewEditor )
2789 _previewEditor = new SMESH_MeshEditor_i( this, true );
2790 aMeshEdVar = _previewEditor->_this();
2792 SMESH_CATCH( SMESH::throwCorbaException );
2794 return aMeshEdVar._retn();
2797 //================================================================================
2799 * \brief Return true if the mesh has been edited since a last total re-compute
2800 * and those modifications may prevent successful partial re-compute
2802 //================================================================================
2804 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2806 Unexpect aCatch(SALOME_SalomeException);
2807 return _impl->HasModificationsToDiscard();
2810 //================================================================================
2812 * \brief Returns a random unique color
2814 //================================================================================
2816 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2818 const int MAX_ATTEMPTS = 100;
2820 double tolerance = 0.5;
2821 SALOMEDS::Color col;
2825 // generate random color
2826 double red = (double)rand() / RAND_MAX;
2827 double green = (double)rand() / RAND_MAX;
2828 double blue = (double)rand() / RAND_MAX;
2829 // check existence in the list of the existing colors
2830 bool matched = false;
2831 std::list<SALOMEDS::Color>::const_iterator it;
2832 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2833 SALOMEDS::Color color = *it;
2834 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2835 matched = tol < tolerance;
2837 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2838 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2846 //=============================================================================
2848 * Sets auto-color mode. If it is on, groups get unique random colors
2850 //=============================================================================
2852 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2854 Unexpect aCatch(SALOME_SalomeException);
2855 _impl->SetAutoColor(theAutoColor);
2857 TPythonDump pyDump; // not to dump group->SetColor() from below code
2858 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2860 std::list<SALOMEDS::Color> aReservedColors;
2861 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2862 for ( ; it != _mapGroups.end(); it++ ) {
2863 if ( CORBA::is_nil( it->second )) continue;
2864 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2865 it->second->SetColor( aColor );
2866 aReservedColors.push_back( aColor );
2870 //=============================================================================
2872 * Returns true if auto-color mode is on
2874 //=============================================================================
2876 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2878 Unexpect aCatch(SALOME_SalomeException);
2879 return _impl->GetAutoColor();
2882 //=============================================================================
2884 * Checks if there are groups with equal names
2886 //=============================================================================
2888 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2890 return _impl->HasDuplicatedGroupNamesMED();
2893 //================================================================================
2895 * \brief Care of a file before exporting mesh into it
2897 //================================================================================
2899 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2901 SMESH_File aFile( file );
2903 if (aFile.exists()) {
2904 // existing filesystem node
2905 if ( !aFile.isDirectory() ) {
2906 if ( aFile.openForWriting() ) {
2907 if ( overwrite && ! aFile.remove()) {
2908 msg << "Can't replace " << aFile.getName();
2911 msg << "Can't write into " << aFile.getName();
2914 msg << "Location " << aFile.getName() << " is not a file";
2918 // nonexisting file; check if it can be created
2919 if ( !aFile.openForWriting() ) {
2920 msg << "You cannot create the file "
2922 << ". Check the directory existence and access rights";
2930 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2934 //================================================================================
2936 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2937 * \param file - file name
2938 * \param overwrite - to erase the file or not
2939 * \retval string - mesh name
2941 //================================================================================
2943 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2944 CORBA::Boolean overwrite)
2947 PrepareForWriting(file, overwrite);
2948 string aMeshName = "Mesh";
2949 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2950 if ( !aStudy->_is_nil() ) {
2951 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
2952 if ( !aMeshSO->_is_nil() ) {
2953 CORBA::String_var name = aMeshSO->GetName();
2955 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2956 if ( !aStudy->GetProperties()->IsLocked() )
2958 SALOMEDS::GenericAttribute_wrap anAttr;
2959 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2960 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2961 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2962 ASSERT(!aFileName->_is_nil());
2963 aFileName->SetValue(file);
2964 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2965 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2966 ASSERT(!aFileType->_is_nil());
2967 aFileType->SetValue("FICHIERMED");
2971 // Update Python script
2972 // set name of mesh before export
2973 TPythonDump() << _gen_i << ".SetName("
2974 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2976 // check names of groups
2982 //================================================================================
2984 * \brief Export to MED file
2986 //================================================================================
2988 void SMESH_Mesh_i::ExportMED(const char* file,
2989 CORBA::Boolean auto_groups,
2990 CORBA::Boolean overwrite,
2991 CORBA::Boolean autoDimension)
2992 throw(SALOME::SALOME_Exception)
2994 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
2997 _preMeshInfo->FullLoadFromFile();
2999 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3000 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, 0, autoDimension );
3002 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3003 << file << "', " << auto_groups << ", "
3004 << overwrite << ", "
3005 << autoDimension << " )";
3007 SMESH_CATCH( SMESH::throwCorbaException );
3010 //================================================================================
3012 * \brief Export a mesh to a SAUV file
3014 //================================================================================
3016 void SMESH_Mesh_i::ExportSAUV (const char* file,
3017 CORBA::Boolean auto_groups)
3018 throw(SALOME::SALOME_Exception)
3020 Unexpect aCatch(SALOME_SalomeException);
3022 _preMeshInfo->FullLoadFromFile();
3024 string aMeshName = prepareMeshNameAndGroups(file, true);
3025 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3026 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3027 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3031 //================================================================================
3033 * \brief Export a mesh to a DAT file
3035 //================================================================================
3037 void SMESH_Mesh_i::ExportDAT (const char *file)
3038 throw(SALOME::SALOME_Exception)
3040 Unexpect aCatch(SALOME_SalomeException);
3042 _preMeshInfo->FullLoadFromFile();
3044 // Update Python script
3045 // check names of groups
3047 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3050 PrepareForWriting(file);
3051 _impl->ExportDAT(file);
3054 //================================================================================
3056 * \brief Export a mesh to an UNV file
3058 //================================================================================
3060 void SMESH_Mesh_i::ExportUNV (const char *file)
3061 throw(SALOME::SALOME_Exception)
3063 Unexpect aCatch(SALOME_SalomeException);
3065 _preMeshInfo->FullLoadFromFile();
3067 // Update Python script
3068 // check names of groups
3070 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3073 PrepareForWriting(file);
3074 _impl->ExportUNV(file);
3077 //================================================================================
3079 * \brief Export a mesh to an STL file
3081 //================================================================================
3083 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3084 throw(SALOME::SALOME_Exception)
3086 Unexpect aCatch(SALOME_SalomeException);
3088 _preMeshInfo->FullLoadFromFile();
3090 // Update Python script
3091 // check names of groups
3093 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3094 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3096 CORBA::String_var name;
3097 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3098 if ( !so->_is_nil() )
3099 name = so->GetName();
3102 PrepareForWriting( file );
3103 _impl->ExportSTL( file, isascii, name.in() );
3106 //================================================================================
3108 * \brief Export a part of mesh to a med file
3110 //================================================================================
3112 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3114 CORBA::Boolean auto_groups,
3115 CORBA::Boolean overwrite,
3116 CORBA::Boolean autoDimension,
3117 const GEOM::ListOfFields& fields,
3118 const char* geomAssocFields)
3119 throw (SALOME::SALOME_Exception)
3123 _preMeshInfo->FullLoadFromFile();
3126 bool have0dField = false;
3127 if ( fields.length() > 0 )
3129 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3130 if ( shapeToMesh->_is_nil() )
3131 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3133 for ( size_t i = 0; i < fields.length(); ++i )
3135 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3136 THROW_SALOME_CORBA_EXCEPTION
3137 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3138 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3139 if ( fieldShape->_is_nil() )
3140 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3141 if ( !fieldShape->IsSame( shapeToMesh ) )
3142 THROW_SALOME_CORBA_EXCEPTION
3143 ( "Field defined not on shape", SALOME::BAD_PARAM);
3144 if ( fields[i]->GetDimension() == 0 )
3147 if ( geomAssocFields )
3148 for ( int i = 0; geomAssocFields[i]; ++i )
3149 switch ( geomAssocFields[i] ) {
3150 case 'v':case 'e':case 'f':case 's': break;
3151 case 'V':case 'E':case 'F':case 'S': break;
3152 default: THROW_SALOME_CORBA_EXCEPTION
3153 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3157 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3161 string aMeshName = "Mesh";
3162 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3163 if ( CORBA::is_nil( meshPart ) ||
3164 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3166 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3167 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3168 0, autoDimension, /*addODOnVertices=*/have0dField);
3169 meshDS = _impl->GetMeshDS();
3174 _preMeshInfo->FullLoadFromFile();
3176 PrepareForWriting(file, overwrite);
3178 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3179 if ( !SO->_is_nil() ) {
3180 CORBA::String_var name = SO->GetName();
3184 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3185 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3186 partDS, autoDimension, /*addODOnVertices=*/have0dField);
3187 meshDS = tmpDSDeleter._obj = partDS;
3192 if ( _impl->HasShapeToMesh() )
3194 DriverMED_W_Field fieldWriter;
3195 fieldWriter.SetFile( file );
3196 fieldWriter.SetMeshName( aMeshName );
3197 fieldWriter.AddODOnVertices( have0dField );
3199 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3203 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3204 goList->length( fields.length() );
3205 for ( size_t i = 0; i < fields.length(); ++i )
3207 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3210 TPythonDump() << _this() << ".ExportPartToMED( "
3211 << meshPart << ", r'" << file << "', "
3212 << auto_groups << ", " << overwrite << ", "
3213 << autoDimension << ", " << goList
3214 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3216 SMESH_CATCH( SMESH::throwCorbaException );
3219 //================================================================================
3221 * Write GEOM fields to MED file
3223 //================================================================================
3225 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3226 SMESHDS_Mesh* meshDS,
3227 const GEOM::ListOfFields& fields,
3228 const char* geomAssocFields)
3230 #define METH "SMESH_Mesh_i::exportMEDFields() "
3232 if (( fields.length() < 1 ) &&
3233 ( !geomAssocFields || !geomAssocFields[0] ))
3236 std::vector< std::vector< double > > dblVals;
3237 std::vector< std::vector< int > > intVals;
3238 std::vector< int > subIdsByDim[ 4 ];
3239 const double noneDblValue = 0.;
3240 const double noneIntValue = 0;
3242 for ( size_t iF = 0; iF < fields.length(); ++iF )
3246 int dim = fields[ iF ]->GetDimension();
3247 SMDSAbs_ElementType elemType;
3248 TopAbs_ShapeEnum shapeType;
3250 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3251 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3252 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3253 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3255 continue; // skip fields on whole shape
3257 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3258 if ( dataType == GEOM::FDT_String )
3260 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3261 if ( stepIDs->length() < 1 )
3263 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3264 if ( comps->length() < 1 )
3266 CORBA::String_var name = fields[ iF ]->GetName();
3268 if ( !fieldWriter.Set( meshDS,
3272 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3275 for ( size_t iC = 0; iC < comps->length(); ++iC )
3276 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3278 dblVals.resize( comps->length() );
3279 intVals.resize( comps->length() );
3281 // find sub-shape IDs
3283 std::vector< int >& subIds = subIdsByDim[ dim ];
3284 if ( subIds.empty() )
3285 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3286 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3287 subIds.push_back( id );
3291 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3295 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3297 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3298 if ( step->_is_nil() )
3301 CORBA::Long stamp = step->GetStamp();
3302 CORBA::Long id = step->GetID();
3303 fieldWriter.SetDtIt( int( stamp ), int( id ));
3305 // fill dblVals or intVals
3306 for ( size_t iC = 0; iC < comps->length(); ++iC )
3307 if ( dataType == GEOM::FDT_Double )
3309 dblVals[ iC ].clear();
3310 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3314 intVals[ iC ].clear();
3315 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3319 case GEOM::FDT_Double:
3321 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3322 if ( dblStep->_is_nil() ) continue;
3323 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3324 if ( vv->length() != subIds.size() * comps->length() )
3325 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3326 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3327 for ( size_t iC = 0; iC < comps->length(); ++iC )
3328 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3333 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3334 if ( intStep->_is_nil() ) continue;
3335 GEOM::ListOfLong_var vv = intStep->GetValues();
3336 if ( vv->length() != subIds.size() * comps->length() )
3337 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3338 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3339 for ( size_t iC = 0; iC < comps->length(); ++iC )
3340 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3343 case GEOM::FDT_Bool:
3345 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3346 if ( boolStep->_is_nil() ) continue;
3347 GEOM::short_array_var vv = boolStep->GetValues();
3348 if ( vv->length() != subIds.size() * comps->length() )
3349 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3350 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3351 for ( size_t iC = 0; iC < comps->length(); ++iC )
3352 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3358 // pass values to fieldWriter
3359 elemIt = fieldWriter.GetOrderedElems();
3360 if ( dataType == GEOM::FDT_Double )
3361 while ( elemIt->more() )
3363 const SMDS_MeshElement* e = elemIt->next();
3364 const int shapeID = e->getshapeId();
3365 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3366 for ( size_t iC = 0; iC < comps->length(); ++iC )
3367 fieldWriter.AddValue( noneDblValue );
3369 for ( size_t iC = 0; iC < comps->length(); ++iC )
3370 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3373 while ( elemIt->more() )
3375 const SMDS_MeshElement* e = elemIt->next();
3376 const int shapeID = e->getshapeId();
3377 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3378 for ( size_t iC = 0; iC < comps->length(); ++iC )
3379 fieldWriter.AddValue( (double) noneIntValue );
3381 for ( size_t iC = 0; iC < comps->length(); ++iC )
3382 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3386 fieldWriter.Perform();
3387 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3388 if ( res && res->IsKO() )
3390 if ( res->myComment.empty() )
3391 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3393 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3399 if ( !geomAssocFields || !geomAssocFields[0] )
3402 // write geomAssocFields
3404 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3405 shapeDim[ TopAbs_COMPOUND ] = 3;
3406 shapeDim[ TopAbs_COMPSOLID ] = 3;
3407 shapeDim[ TopAbs_SOLID ] = 3;
3408 shapeDim[ TopAbs_SHELL ] = 2;
3409 shapeDim[ TopAbs_FACE ] = 2;
3410 shapeDim[ TopAbs_WIRE ] = 1;
3411 shapeDim[ TopAbs_EDGE ] = 1;
3412 shapeDim[ TopAbs_VERTEX ] = 0;
3413 shapeDim[ TopAbs_SHAPE ] = 3;
3415 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3417 std::vector< std::string > compNames;
3418 switch ( geomAssocFields[ iF ]) {
3420 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3421 compNames.push_back( "dim" );
3424 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3427 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3430 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3434 compNames.push_back( "id" );
3435 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3436 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3438 fieldWriter.SetDtIt( -1, -1 );
3440 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3444 if ( compNames.size() == 2 ) // _vertices_
3445 while ( elemIt->more() )
3447 const SMDS_MeshElement* e = elemIt->next();
3448 const int shapeID = e->getshapeId();
3451 fieldWriter.AddValue( (double) -1 );
3452 fieldWriter.AddValue( (double) -1 );
3456 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3457 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3458 fieldWriter.AddValue( (double) shapeID );
3462 while ( elemIt->more() )
3464 const SMDS_MeshElement* e = elemIt->next();
3465 const int shapeID = e->getshapeId();
3467 fieldWriter.AddValue( (double) -1 );
3469 fieldWriter.AddValue( (double) shapeID );
3473 fieldWriter.Perform();
3474 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3475 if ( res && res->IsKO() )
3477 if ( res->myComment.empty() )
3478 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3480 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3483 } // loop on geomAssocFields
3488 //================================================================================
3490 * \brief Export a part of mesh to a DAT file
3492 //================================================================================
3494 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3496 throw (SALOME::SALOME_Exception)
3498 Unexpect aCatch(SALOME_SalomeException);
3500 _preMeshInfo->FullLoadFromFile();
3502 PrepareForWriting(file);
3504 SMESH_MeshPartDS partDS( meshPart );
3505 _impl->ExportDAT(file,&partDS);
3507 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3508 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3510 //================================================================================
3512 * \brief Export a part of mesh to an UNV file
3514 //================================================================================
3516 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3518 throw (SALOME::SALOME_Exception)
3520 Unexpect aCatch(SALOME_SalomeException);
3522 _preMeshInfo->FullLoadFromFile();
3524 PrepareForWriting(file);
3526 SMESH_MeshPartDS partDS( meshPart );
3527 _impl->ExportUNV(file, &partDS);
3529 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3530 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3532 //================================================================================
3534 * \brief Export a part of mesh to an STL file
3536 //================================================================================
3538 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3540 ::CORBA::Boolean isascii)
3541 throw (SALOME::SALOME_Exception)
3543 Unexpect aCatch(SALOME_SalomeException);
3545 _preMeshInfo->FullLoadFromFile();
3547 PrepareForWriting(file);
3549 CORBA::String_var name;
3550 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3551 if ( !so->_is_nil() )
3552 name = so->GetName();
3554 SMESH_MeshPartDS partDS( meshPart );
3555 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3557 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3558 << meshPart<< ", r'" << file << "', " << isascii << ")";
3561 //================================================================================
3563 * \brief Export a part of mesh to an STL file
3565 //================================================================================
3567 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3569 CORBA::Boolean overwrite,
3570 CORBA::Boolean groupElemsByType)
3571 throw (SALOME::SALOME_Exception)
3574 Unexpect aCatch(SALOME_SalomeException);
3576 _preMeshInfo->FullLoadFromFile();
3578 PrepareForWriting(file,overwrite);
3580 std::string meshName("");
3581 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3582 if ( !so->_is_nil() )
3584 CORBA::String_var name = so->GetName();
3585 meshName = name.in();
3589 SMESH_MeshPartDS partDS( meshPart );
3590 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3592 SMESH_CATCH( SMESH::throwCorbaException );
3594 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3595 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3597 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3601 //================================================================================
3603 * \brief Export a part of mesh to a GMF file
3605 //================================================================================
3607 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3609 bool withRequiredGroups)
3610 throw (SALOME::SALOME_Exception)
3612 Unexpect aCatch(SALOME_SalomeException);
3614 _preMeshInfo->FullLoadFromFile();
3616 PrepareForWriting(file,/*overwrite=*/true);
3618 SMESH_MeshPartDS partDS( meshPart );
3619 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3621 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3622 << meshPart<< ", r'"
3624 << withRequiredGroups << ")";
3627 //=============================================================================
3629 * Return computation progress [0.,1]
3631 //=============================================================================
3633 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3637 return _impl->GetComputeProgress();
3639 SMESH_CATCH( SMESH::doNothing );
3643 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3645 Unexpect aCatch(SALOME_SalomeException);
3647 return _preMeshInfo->NbNodes();
3649 return _impl->NbNodes();
3652 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3654 Unexpect aCatch(SALOME_SalomeException);
3656 return _preMeshInfo->NbElements();
3658 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3661 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3663 Unexpect aCatch(SALOME_SalomeException);
3665 return _preMeshInfo->Nb0DElements();
3667 return _impl->Nb0DElements();
3670 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3672 Unexpect aCatch(SALOME_SalomeException);
3674 return _preMeshInfo->NbBalls();
3676 return _impl->NbBalls();
3679 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3681 Unexpect aCatch(SALOME_SalomeException);
3683 return _preMeshInfo->NbEdges();
3685 return _impl->NbEdges();
3688 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3689 throw(SALOME::SALOME_Exception)
3691 Unexpect aCatch(SALOME_SalomeException);
3693 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3695 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3698 //=============================================================================
3700 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3702 Unexpect aCatch(SALOME_SalomeException);
3704 return _preMeshInfo->NbFaces();
3706 return _impl->NbFaces();
3709 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3711 Unexpect aCatch(SALOME_SalomeException);
3713 return _preMeshInfo->NbTriangles();
3715 return _impl->NbTriangles();
3718 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3720 Unexpect aCatch(SALOME_SalomeException);
3722 return _preMeshInfo->NbBiQuadTriangles();
3724 return _impl->NbBiQuadTriangles();
3727 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3729 Unexpect aCatch(SALOME_SalomeException);
3731 return _preMeshInfo->NbQuadrangles();
3733 return _impl->NbQuadrangles();
3736 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3738 Unexpect aCatch(SALOME_SalomeException);
3740 return _preMeshInfo->NbBiQuadQuadrangles();
3742 return _impl->NbBiQuadQuadrangles();
3745 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3747 Unexpect aCatch(SALOME_SalomeException);
3749 return _preMeshInfo->NbPolygons();
3751 return _impl->NbPolygons();
3754 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3756 Unexpect aCatch(SALOME_SalomeException);
3758 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3760 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3763 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3764 throw(SALOME::SALOME_Exception)
3766 Unexpect aCatch(SALOME_SalomeException);
3768 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3770 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3773 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3774 throw(SALOME::SALOME_Exception)
3776 Unexpect aCatch(SALOME_SalomeException);
3778 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3780 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3783 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3784 throw(SALOME::SALOME_Exception)
3786 Unexpect aCatch(SALOME_SalomeException);
3788 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3790 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3793 //=============================================================================
3795 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3797 Unexpect aCatch(SALOME_SalomeException);
3799 return _preMeshInfo->NbVolumes();
3801 return _impl->NbVolumes();
3804 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3806 Unexpect aCatch(SALOME_SalomeException);
3808 return _preMeshInfo->NbTetras();
3810 return _impl->NbTetras();
3813 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3815 Unexpect aCatch(SALOME_SalomeException);
3817 return _preMeshInfo->NbHexas();
3819 return _impl->NbHexas();
3822 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3824 Unexpect aCatch(SALOME_SalomeException);
3826 return _preMeshInfo->NbTriQuadHexas();
3828 return _impl->NbTriQuadraticHexas();
3831 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3833 Unexpect aCatch(SALOME_SalomeException);
3835 return _preMeshInfo->NbPyramids();
3837 return _impl->NbPyramids();
3840 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3842 Unexpect aCatch(SALOME_SalomeException);
3844 return _preMeshInfo->NbPrisms();
3846 return _impl->NbPrisms();
3849 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3851 Unexpect aCatch(SALOME_SalomeException);
3853 return _preMeshInfo->NbHexPrisms();
3855 return _impl->NbHexagonalPrisms();
3858 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3860 Unexpect aCatch(SALOME_SalomeException);
3862 return _preMeshInfo->NbPolyhedrons();
3864 return _impl->NbPolyhedrons();
3867 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3868 throw(SALOME::SALOME_Exception)
3870 Unexpect aCatch(SALOME_SalomeException);
3872 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3874 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3877 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3878 throw(SALOME::SALOME_Exception)
3880 Unexpect aCatch(SALOME_SalomeException);
3882 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3884 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3887 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3888 throw(SALOME::SALOME_Exception)
3890 Unexpect aCatch(SALOME_SalomeException);
3892 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3894 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3897 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3898 throw(SALOME::SALOME_Exception)
3900 Unexpect aCatch(SALOME_SalomeException);
3902 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3904 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3907 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3908 throw(SALOME::SALOME_Exception)
3910 Unexpect aCatch(SALOME_SalomeException);
3912 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3914 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3917 //=============================================================================
3919 * Returns nb of published sub-meshes
3921 //=============================================================================
3923 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3925 Unexpect aCatch(SALOME_SalomeException);
3926 return _mapSubMesh_i.size();
3929 //=============================================================================
3931 * Dumps mesh into a string
3933 //=============================================================================
3935 char* SMESH_Mesh_i::Dump()
3939 return CORBA::string_dup( os.str().c_str() );
3942 //=============================================================================
3944 * Method of SMESH_IDSource interface
3946 //=============================================================================
3948 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3950 return GetElementsId();
3953 //=============================================================================
3955 * Returns ids of all elements
3957 //=============================================================================
3959 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3960 throw (SALOME::SALOME_Exception)
3962 Unexpect aCatch(SALOME_SalomeException);
3964 _preMeshInfo->FullLoadFromFile();
3966 SMESH::long_array_var aResult = new SMESH::long_array();
3967 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3969 if ( aSMESHDS_Mesh == NULL )
3970 return aResult._retn();
3972 long nbElements = NbElements();
3973 aResult->length( nbElements );
3974 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3975 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3976 aResult[i] = anIt->next()->GetID();
3978 return aResult._retn();
3982 //=============================================================================
3984 * Returns ids of all elements of given type
3986 //=============================================================================
3988 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3989 throw (SALOME::SALOME_Exception)
3991 Unexpect aCatch(SALOME_SalomeException);
3993 _preMeshInfo->FullLoadFromFile();
3995 SMESH::long_array_var aResult = new SMESH::long_array();
3996 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3998 if ( aSMESHDS_Mesh == NULL )
3999 return aResult._retn();
4001 long nbElements = NbElements();
4003 // No sense in returning ids of elements along with ids of nodes:
4004 // when theElemType == SMESH::ALL, return node ids only if
4005 // there are no elements
4006 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4007 return GetNodesId();
4009 aResult->length( nbElements );
4013 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4014 while ( i < nbElements && anIt->more() )
4015 aResult[i++] = anIt->next()->GetID();
4017 aResult->length( i );
4019 return aResult._retn();
4022 //=============================================================================
4024 * Returns ids of all nodes
4026 //=============================================================================
4028 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4029 throw (SALOME::SALOME_Exception)
4031 Unexpect aCatch(SALOME_SalomeException);
4033 _preMeshInfo->FullLoadFromFile();
4035 SMESH::long_array_var aResult = new SMESH::long_array();
4036 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4038 if ( aMeshDS == NULL )
4039 return aResult._retn();
4041 long nbNodes = NbNodes();
4042 aResult->length( nbNodes );
4043 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4044 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4045 aResult[i] = anIt->next()->GetID();
4047 return aResult._retn();
4050 //=============================================================================
4054 //=============================================================================
4056 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4057 throw (SALOME::SALOME_Exception)
4059 SMESH::ElementType type = SMESH::ALL;
4063 _preMeshInfo->FullLoadFromFile();
4065 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4067 SMESH_CATCH( SMESH::throwCorbaException );
4072 //=============================================================================
4076 //=============================================================================
4078 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4079 throw (SALOME::SALOME_Exception)
4082 _preMeshInfo->FullLoadFromFile();
4084 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4086 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4088 return ( SMESH::EntityType ) e->GetEntityType();
4091 //=============================================================================
4095 //=============================================================================
4097 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4098 throw (SALOME::SALOME_Exception)
4101 _preMeshInfo->FullLoadFromFile();
4103 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4105 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4107 return ( SMESH::GeometryType ) e->GetGeomType();
4110 //=============================================================================
4112 * Returns ID of elements for given submesh
4114 //=============================================================================
4115 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4116 throw (SALOME::SALOME_Exception)
4118 SMESH::long_array_var aResult = new SMESH::long_array();
4122 _preMeshInfo->FullLoadFromFile();
4124 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4125 if(!SM) return aResult._retn();
4127 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4128 if(!SDSM) return aResult._retn();
4130 aResult->length(SDSM->NbElements());
4132 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4134 while ( eIt->more() ) {
4135 aResult[i++] = eIt->next()->GetID();
4138 SMESH_CATCH( SMESH::throwCorbaException );
4140 return aResult._retn();
4143 //=============================================================================
4145 * Returns ID of nodes for given submesh
4146 * If param all==true - returns all nodes, else -
4147 * returns only nodes on shapes.
4149 //=============================================================================
4151 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4153 throw (SALOME::SALOME_Exception)
4155 SMESH::long_array_var aResult = new SMESH::long_array();
4159 _preMeshInfo->FullLoadFromFile();
4161 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4162 if(!SM) return aResult._retn();
4164 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4165 if(!SDSM) return aResult._retn();
4168 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4169 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4170 while ( nIt->more() ) {
4171 const SMDS_MeshNode* elem = nIt->next();
4172 theElems.insert( elem->GetID() );
4175 else { // all nodes of submesh elements
4176 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4177 while ( eIt->more() ) {
4178 const SMDS_MeshElement* anElem = eIt->next();
4179 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4180 while ( nIt->more() ) {
4181 const SMDS_MeshElement* elem = nIt->next();
4182 theElems.insert( elem->GetID() );
4187 aResult->length(theElems.size());
4188 set<int>::iterator itElem;
4190 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4191 aResult[i++] = *itElem;
4193 SMESH_CATCH( SMESH::throwCorbaException );
4195 return aResult._retn();
4198 //=============================================================================
4200 * Returns type of elements for given submesh
4202 //=============================================================================
4204 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4205 throw (SALOME::SALOME_Exception)
4207 SMESH::ElementType type = SMESH::ALL;
4211 _preMeshInfo->FullLoadFromFile();
4213 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4214 if(!SM) return SMESH::ALL;
4216 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4217 if(!SDSM) return SMESH::ALL;
4219 if(SDSM->NbElements()==0)
4220 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4222 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4223 const SMDS_MeshElement* anElem = eIt->next();
4225 type = ( SMESH::ElementType ) anElem->GetType();
4227 SMESH_CATCH( SMESH::throwCorbaException );
4233 //=============================================================================
4235 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4237 //=============================================================================
4239 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4242 _preMeshInfo->FullLoadFromFile();
4244 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4245 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4250 //=============================================================================
4252 * Get XYZ coordinates of node as list of double
4253 * If there is not node for given ID - returns empty list
4255 //=============================================================================
4257 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4260 _preMeshInfo->FullLoadFromFile();
4262 SMESH::double_array_var aResult = new SMESH::double_array();
4263 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4264 if ( aMeshDS == NULL )
4265 return aResult._retn();
4268 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4270 return aResult._retn();
4274 aResult[0] = aNode->X();
4275 aResult[1] = aNode->Y();
4276 aResult[2] = aNode->Z();
4277 return aResult._retn();
4281 //=============================================================================
4283 * For given node returns list of IDs of inverse elements
4284 * If there is not node for given ID - returns empty list
4286 //=============================================================================
4288 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4291 _preMeshInfo->FullLoadFromFile();
4293 SMESH::long_array_var aResult = new SMESH::long_array();
4294 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4295 if ( aMeshDS == NULL )
4296 return aResult._retn();
4299 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4301 return aResult._retn();
4303 // find inverse elements
4304 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4305 aResult->length( aNode->NbInverseElements() );
4306 for( int i = 0; eIt->more(); ++i )
4308 const SMDS_MeshElement* elem = eIt->next();
4309 aResult[ i ] = elem->GetID();
4311 return aResult._retn();
4314 //=============================================================================
4316 * \brief Return position of a node on shape
4318 //=============================================================================
4320 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4323 _preMeshInfo->FullLoadFromFile();
4325 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4326 aNodePosition->shapeID = 0;
4327 aNodePosition->shapeType = GEOM::SHAPE;
4329 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4330 if ( !mesh ) return aNodePosition;
4332 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4334 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4336 aNodePosition->shapeID = aNode->getshapeId();
4337 switch ( pos->GetTypeOfPosition() ) {
4339 aNodePosition->shapeType = GEOM::EDGE;
4340 aNodePosition->params.length(1);
4341 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4343 case SMDS_TOP_FACE: {
4344 SMDS_FacePositionPtr fPos = pos;
4345 aNodePosition->shapeType = GEOM::FACE;
4346 aNodePosition->params.length(2);
4347 aNodePosition->params[0] = fPos->GetUParameter();
4348 aNodePosition->params[1] = fPos->GetVParameter();
4351 case SMDS_TOP_VERTEX:
4352 aNodePosition->shapeType = GEOM::VERTEX;
4354 case SMDS_TOP_3DSPACE:
4355 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4356 aNodePosition->shapeType = GEOM::SOLID;
4357 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4358 aNodePosition->shapeType = GEOM::SHELL;
4364 return aNodePosition;
4367 //=============================================================================
4369 * \brief Return position of an element on shape
4371 //=============================================================================
4373 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4376 _preMeshInfo->FullLoadFromFile();
4378 SMESH::ElementPosition anElementPosition;
4379 anElementPosition.shapeID = 0;
4380 anElementPosition.shapeType = GEOM::SHAPE;
4382 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4383 if ( !mesh ) return anElementPosition;
4385 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4387 anElementPosition.shapeID = anElem->getshapeId();
4388 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4389 if ( !aSp.IsNull() ) {
4390 switch ( aSp.ShapeType() ) {
4392 anElementPosition.shapeType = GEOM::EDGE;
4395 anElementPosition.shapeType = GEOM::FACE;
4398 anElementPosition.shapeType = GEOM::VERTEX;
4401 anElementPosition.shapeType = GEOM::SOLID;
4404 anElementPosition.shapeType = GEOM::SHELL;
4410 return anElementPosition;
4413 //=============================================================================
4415 * If given element is node returns IDs of shape from position
4416 * If there is not node for given ID - returns -1
4418 //=============================================================================
4420 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4423 _preMeshInfo->FullLoadFromFile();
4425 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4426 if ( aMeshDS == NULL )
4430 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4432 return aNode->getshapeId();
4439 //=============================================================================
4441 * For given element returns ID of result shape after
4442 * ::FindShape() from SMESH_MeshEditor
4443 * If there is not element for given ID - returns -1
4445 //=============================================================================
4447 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4450 _preMeshInfo->FullLoadFromFile();
4452 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4453 if ( aMeshDS == NULL )
4456 // try to find element
4457 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4461 ::SMESH_MeshEditor aMeshEditor(_impl);
4462 int index = aMeshEditor.FindShape( elem );
4470 //=============================================================================
4472 * Returns number of nodes for given element
4473 * If there is not element for given ID - returns -1
4475 //=============================================================================
4477 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4480 _preMeshInfo->FullLoadFromFile();
4482 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4483 if ( aMeshDS == NULL ) return -1;
4484 // try to find element
4485 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4486 if(!elem) return -1;
4487 return elem->NbNodes();
4491 //=============================================================================
4493 * Returns ID of node by given index for given element
4494 * If there is not element for given ID - returns -1
4495 * If there is not node for given index - returns -2
4497 //=============================================================================
4499 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4502 _preMeshInfo->FullLoadFromFile();
4504 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4505 if ( aMeshDS == NULL ) return -1;
4506 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4507 if(!elem) return -1;
4508 if( index>=elem->NbNodes() || index<0 ) return -1;
4509 return elem->GetNode(index)->GetID();
4512 //=============================================================================
4514 * Returns IDs of nodes of given element
4516 //=============================================================================
4518 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4521 _preMeshInfo->FullLoadFromFile();
4523 SMESH::long_array_var aResult = new SMESH::long_array();
4524 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4526 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4528 aResult->length( elem->NbNodes() );
4529 for ( int i = 0; i < elem->NbNodes(); ++i )
4530 aResult[ i ] = elem->GetNode( i )->GetID();
4533 return aResult._retn();
4536 //=============================================================================
4538 * Returns true if given node is medium node
4539 * in given quadratic element
4541 //=============================================================================
4543 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4546 _preMeshInfo->FullLoadFromFile();
4548 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4549 if ( aMeshDS == NULL ) return false;
4551 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4552 if(!aNode) return false;
4553 // try to find element
4554 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4555 if(!elem) return false;
4557 return elem->IsMediumNode(aNode);
4561 //=============================================================================
4563 * Returns true if given node is medium node
4564 * in one of quadratic elements
4566 //=============================================================================
4568 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4569 SMESH::ElementType theElemType)
4572 _preMeshInfo->FullLoadFromFile();
4574 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4575 if ( aMeshDS == NULL ) return false;
4578 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4579 if(!aNode) return false;
4581 SMESH_MesherHelper aHelper( *(_impl) );
4583 SMDSAbs_ElementType aType;
4584 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4585 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4586 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4587 else aType = SMDSAbs_All;
4589 return aHelper.IsMedium(aNode,aType);
4593 //=============================================================================
4595 * Returns number of edges for given element
4597 //=============================================================================
4599 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4602 _preMeshInfo->FullLoadFromFile();
4604 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4605 if ( aMeshDS == NULL ) return -1;
4606 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4607 if(!elem) return -1;
4608 return elem->NbEdges();
4612 //=============================================================================
4614 * Returns number of faces for given element
4616 //=============================================================================
4618 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4621 _preMeshInfo->FullLoadFromFile();
4623 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4624 if ( aMeshDS == NULL ) return -1;
4625 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4626 if(!elem) return -1;
4627 return elem->NbFaces();
4630 //=======================================================================
4631 //function : GetElemFaceNodes
4632 //purpose : Returns nodes of given face (counted from zero) for given element.
4633 //=======================================================================
4635 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4636 CORBA::Short faceIndex)
4639 _preMeshInfo->FullLoadFromFile();
4641 SMESH::long_array_var aResult = new SMESH::long_array();
4642 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4644 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4646 SMDS_VolumeTool vtool( elem );
4647 if ( faceIndex < vtool.NbFaces() )
4649 aResult->length( vtool.NbFaceNodes( faceIndex ));
4650 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4651 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4652 aResult[ i ] = nn[ i ]->GetID();
4656 return aResult._retn();
4659 //=======================================================================
4660 //function : GetElemFaceNodes
4661 //purpose : Returns three components of normal of given mesh face.
4662 //=======================================================================
4664 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4665 CORBA::Boolean normalized)
4668 _preMeshInfo->FullLoadFromFile();
4670 SMESH::double_array_var aResult = new SMESH::double_array();
4672 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4675 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4677 aResult->length( 3 );
4678 aResult[ 0 ] = normal.X();
4679 aResult[ 1 ] = normal.Y();
4680 aResult[ 2 ] = normal.Z();
4683 return aResult._retn();
4686 //=======================================================================
4687 //function : FindElementByNodes
4688 //purpose : Returns an element based on all given nodes.
4689 //=======================================================================
4691 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4694 _preMeshInfo->FullLoadFromFile();
4696 CORBA::Long elemID(0);
4697 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4699 vector< const SMDS_MeshNode * > nn( nodes.length() );
4700 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4701 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4704 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4705 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4706 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4707 _impl->NbVolumes( ORDER_QUADRATIC )))
4708 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4710 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4715 //================================================================================
4717 * \brief Return elements including all given nodes.
4719 //================================================================================
4721 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4722 SMESH::ElementType elemType)
4725 _preMeshInfo->FullLoadFromFile();
4727 SMESH::long_array_var result = new SMESH::long_array();
4729 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4731 vector< const SMDS_MeshNode * > nn( nodes.length() );
4732 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4733 nn[i] = mesh->FindNode( nodes[i] );
4735 std::vector<const SMDS_MeshElement *> elems;
4736 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4737 result->length( elems.size() );
4738 for ( size_t i = 0; i < elems.size(); ++i )
4739 result[i] = elems[i]->GetID();
4741 return result._retn();
4744 //=============================================================================
4746 * Returns true if given element is polygon
4748 //=============================================================================
4750 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4753 _preMeshInfo->FullLoadFromFile();
4755 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4756 if ( aMeshDS == NULL ) return false;
4757 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4758 if(!elem) return false;
4759 return elem->IsPoly();
4763 //=============================================================================
4765 * Returns true if given element is quadratic
4767 //=============================================================================
4769 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4772 _preMeshInfo->FullLoadFromFile();
4774 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4775 if ( aMeshDS == NULL ) return false;
4776 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4777 if(!elem) return false;
4778 return elem->IsQuadratic();
4781 //=============================================================================
4783 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4785 //=============================================================================
4787 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4790 _preMeshInfo->FullLoadFromFile();
4792 if ( const SMDS_BallElement* ball =
4793 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4794 return ball->GetDiameter();
4799 //=============================================================================
4801 * Returns bary center for given element
4803 //=============================================================================
4805 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4808 _preMeshInfo->FullLoadFromFile();
4810 SMESH::double_array_var aResult = new SMESH::double_array();
4811 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4812 if ( aMeshDS == NULL )
4813 return aResult._retn();
4815 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4817 return aResult._retn();
4819 if(elem->GetType()==SMDSAbs_Volume) {
4820 SMDS_VolumeTool aTool;
4821 if(aTool.Set(elem)) {
4823 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4828 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4830 double x=0., y=0., z=0.;
4831 for(; anIt->more(); ) {
4833 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4847 return aResult._retn();
4850 //================================================================================
4852 * \brief Create a group of elements preventing computation of a sub-shape
4854 //================================================================================
4856 SMESH::ListOfGroups*
4857 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4858 const char* theGroupName )
4859 throw ( SALOME::SALOME_Exception )
4861 Unexpect aCatch(SALOME_SalomeException);
4863 if ( !theGroupName || strlen( theGroupName) == 0 )
4864 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4866 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4867 ::SMESH_MeshEditor::ElemFeatures elemType;
4869 // submesh by subshape id
4870 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4871 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4874 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4875 if ( error && error->HasBadElems() )
4877 // sort bad elements by type
4878 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4879 const list<const SMDS_MeshElement*>& badElems =
4880 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4881 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4882 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4883 for ( ; elemIt != elemEnd; ++elemIt )
4885 const SMDS_MeshElement* elem = *elemIt;
4886 if ( !elem ) continue;
4888 if ( elem->GetID() < 1 )
4890 // elem is a temporary element, make a real element
4891 vector< const SMDS_MeshNode* > nodes;
4892 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4893 while ( nIt->more() && elem )
4895 nodes.push_back( nIt->next() );
4896 if ( nodes.back()->GetID() < 1 )
4897 elem = 0; // a temporary element on temporary nodes
4901 ::SMESH_MeshEditor editor( _impl );
4902 elem = editor.AddElement( nodes, elemType.Init( elem ));
4906 elemsByType[ elem->GetType() ].push_back( elem );
4909 // how many groups to create?
4911 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4912 nbTypes += int( !elemsByType[ i ].empty() );
4913 groups->length( nbTypes );
4916 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4918 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4919 if ( elems.empty() ) continue;
4921 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4922 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4924 SMESH::SMESH_Mesh_var mesh = _this();
4925 SALOMEDS::SObject_wrap aSO =
4926 _gen_i->PublishGroup( mesh, groups[ iG ],
4927 GEOM::GEOM_Object::_nil(), theGroupName);
4929 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4930 if ( !grp_i ) continue;
4932 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4933 for ( size_t iE = 0; iE < elems.size(); ++iE )
4934 grpDS->SMDSGroup().Add( elems[ iE ]);
4939 return groups._retn();
4942 //=============================================================================
4944 * Create and publish group servants if any groups were imported or created anyhow
4946 //=============================================================================
4948 void SMESH_Mesh_i::CreateGroupServants()
4950 SMESH::SMESH_Mesh_var aMesh = _this();
4953 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4954 while ( groupIt->more() )
4956 ::SMESH_Group* group = groupIt->next();
4957 int anId = group->GetGroupDS()->GetID();
4959 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4960 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4962 addedIDs.insert( anId );
4964 SMESH_GroupBase_i* aGroupImpl;
4966 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4967 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4969 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4970 shape = groupOnGeom->GetShape();
4973 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4976 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4977 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4978 aGroupImpl->Register();
4980 // register CORBA object for persistence
4981 int nextId = _gen_i->RegisterObject( groupVar );
4982 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4983 else { nextId = 0; } // avoid "unused variable" warning in release mode
4985 // publishing the groups in the study
4986 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4987 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
4989 if ( !addedIDs.empty() )
4992 set<int>::iterator id = addedIDs.begin();
4993 for ( ; id != addedIDs.end(); ++id )
4995 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4996 int i = std::distance( _mapGroups.begin(), it );
4997 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5002 //=============================================================================
5004 * \brief Return true if all sub-meshes are computed OK - to update an icon
5006 //=============================================================================
5008 bool SMESH_Mesh_i::IsComputedOK()
5010 return _impl->IsComputedOK();
5013 //=============================================================================
5015 * \brief Return groups cantained in _mapGroups by their IDs
5017 //=============================================================================
5019 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5021 int nbGroups = groupIDs.size();
5022 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5023 aList->length( nbGroups );
5025 list<int>::const_iterator ids = groupIDs.begin();
5026 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5028 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5029 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5030 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5032 aList->length( nbGroups );
5033 return aList._retn();
5036 //=============================================================================
5038 * \brief Return information about imported file
5040 //=============================================================================
5042 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5044 SMESH::MedFileInfo_var res( _medFileInfo );
5045 if ( !res.operator->() ) {
5046 res = new SMESH::MedFileInfo;
5048 res->fileSize = res->major = res->minor = res->release = -1;
5053 //=============================================================================
5055 * \brief Pass names of mesh groups from study to mesh DS
5057 //=============================================================================
5059 void SMESH_Mesh_i::checkGroupNames()
5061 int nbGrp = NbGroups();
5065 SMESH::ListOfGroups* grpList = 0;
5066 // avoid dump of "GetGroups"
5068 // store python dump into a local variable inside local scope
5069 SMESH::TPythonDump pDump; // do not delete this line of code
5070 grpList = GetGroups();
5073 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5074 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5077 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5078 if ( aGrpSO->_is_nil() )
5080 // correct name of the mesh group if necessary
5081 const char* guiName = aGrpSO->GetName();
5082 if ( strcmp(guiName, aGrp->GetName()) )
5083 aGrp->SetName( guiName );
5087 //=============================================================================
5089 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5091 //=============================================================================
5092 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5094 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5098 //=============================================================================
5100 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5102 //=============================================================================
5104 char* SMESH_Mesh_i::GetParameters()
5106 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5109 //=============================================================================
5111 * \brief Returns list of notebook variables used for last Mesh operation
5113 //=============================================================================
5114 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5116 SMESH::string_array_var aResult = new SMESH::string_array();
5117 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5119 CORBA::String_var aParameters = GetParameters();
5120 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5121 if ( aSections->length() > 0 ) {
5122 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5123 aResult->length( aVars.length() );
5124 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5125 aResult[i] = CORBA::string_dup( aVars[i] );
5128 return aResult._retn();
5131 //=======================================================================
5132 //function : GetTypes
5133 //purpose : Returns types of elements it contains
5134 //=======================================================================
5136 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5139 return _preMeshInfo->GetTypes();
5141 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5145 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5146 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5147 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5148 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5149 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5150 if (_impl->NbNodes() &&
5151 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5152 types->length( nbTypes );
5154 return types._retn();
5157 //=======================================================================
5158 //function : GetMesh
5159 //purpose : Returns self
5160 //=======================================================================
5162 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5164 return SMESH::SMESH_Mesh::_duplicate( _this() );
5167 //=======================================================================
5168 //function : IsMeshInfoCorrect
5169 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5170 // * happen if mesh data is not yet fully loaded from the file of study.
5171 //=======================================================================
5173 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5175 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5178 //=============================================================================
5180 * \brief Returns number of mesh elements per each \a EntityType
5182 //=============================================================================
5184 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5187 return _preMeshInfo->GetMeshInfo();
5189 SMESH::long_array_var aRes = new SMESH::long_array();
5190 aRes->length(SMESH::Entity_Last);
5191 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5193 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5195 return aRes._retn();
5196 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5197 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5198 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5199 return aRes._retn();
5202 //=============================================================================
5204 * \brief Returns number of mesh elements per each \a ElementType
5206 //=============================================================================
5208 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5210 SMESH::long_array_var aRes = new SMESH::long_array();
5211 aRes->length(SMESH::NB_ELEMENT_TYPES);
5212 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5215 const SMDS_MeshInfo* meshInfo = 0;
5217 meshInfo = _preMeshInfo;
5218 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5219 meshInfo = & meshDS->GetMeshInfo();
5222 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5223 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5225 return aRes._retn();
5228 //=============================================================================
5230 * Collect statistic of mesh elements given by iterator
5232 //=============================================================================
5234 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5235 SMESH::long_array& theInfo)
5237 if (!theItr) return;
5238 while (theItr->more())
5239 theInfo[ theItr->next()->GetEntityType() ]++;
5241 //=============================================================================
5243 * Returns mesh unstructed grid information.
5245 //=============================================================================
5247 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5249 SALOMEDS::TMPFile_var SeqFile;
5250 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5251 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5253 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5254 aWriter->WriteToOutputStringOn();
5255 aWriter->SetInputData(aGrid);
5256 aWriter->SetFileTypeToBinary();
5258 char* str = aWriter->GetOutputString();
5259 int size = aWriter->GetOutputStringLength();
5261 //Allocate octect buffer of required size
5262 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5263 //Copy ostrstream content to the octect buffer
5264 memcpy(OctetBuf, str, size);
5265 //Create and return TMPFile
5266 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5270 return SeqFile._retn();
5273 //=============================================================================
5274 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5275 * SMESH::ElementType type) */
5277 using namespace SMESH::Controls;
5278 //-----------------------------------------------------------------------------
5279 struct PredicateIterator : public SMDS_ElemIterator
5281 SMDS_ElemIteratorPtr _elemIter;
5282 PredicatePtr _predicate;
5283 const SMDS_MeshElement* _elem;
5285 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5286 PredicatePtr predicate):
5287 _elemIter(iterator), _predicate(predicate)
5295 virtual const SMDS_MeshElement* next()
5297 const SMDS_MeshElement* res = _elem;
5299 while ( _elemIter->more() && !_elem )
5301 _elem = _elemIter->next();
5302 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5309 //-----------------------------------------------------------------------------
5310 struct IDSourceIterator : public SMDS_ElemIterator
5312 const CORBA::Long* _idPtr;
5313 const CORBA::Long* _idEndPtr;
5314 SMESH::long_array_var _idArray;
5315 const SMDS_Mesh* _mesh;
5316 const SMDSAbs_ElementType _type;
5317 const SMDS_MeshElement* _elem;
5319 IDSourceIterator( const SMDS_Mesh* mesh,
5320 const CORBA::Long* ids,
5322 SMDSAbs_ElementType type):
5323 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5325 if ( _idPtr && nbIds && _mesh )
5328 IDSourceIterator( const SMDS_Mesh* mesh,
5329 SMESH::long_array* idArray,
5330 SMDSAbs_ElementType type):
5331 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5333 if ( idArray && _mesh )
5335 _idPtr = &_idArray[0];
5336 _idEndPtr = _idPtr + _idArray->length();
5344 virtual const SMDS_MeshElement* next()
5346 const SMDS_MeshElement* res = _elem;
5348 while ( _idPtr < _idEndPtr && !_elem )
5350 if ( _type == SMDSAbs_Node )
5352 _elem = _mesh->FindNode( *_idPtr++ );
5354 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5355 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5363 //-----------------------------------------------------------------------------
5365 struct NodeOfElemIterator : public SMDS_ElemIterator
5367 TColStd_MapOfInteger _checkedNodeIDs;
5368 SMDS_ElemIteratorPtr _elemIter;
5369 SMDS_ElemIteratorPtr _nodeIter;
5370 const SMDS_MeshElement* _node;
5372 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5374 if ( _elemIter && _elemIter->more() )
5376 _nodeIter = _elemIter->next()->nodesIterator();
5384 virtual const SMDS_MeshElement* next()
5386 const SMDS_MeshElement* res = _node;
5388 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5390 if ( _nodeIter->more() )
5392 _node = _nodeIter->next();
5393 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5398 _nodeIter = _elemIter->next()->nodesIterator();
5406 //=============================================================================
5408 * Return iterator on elements of given type in given object
5410 //=============================================================================
5412 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5413 SMESH::ElementType theType)
5415 SMDS_ElemIteratorPtr elemIt;
5416 bool typeOK = ( theType == SMESH::ALL );
5417 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5419 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5420 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5421 if ( !mesh_i ) return elemIt;
5422 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5424 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5426 elemIt = meshDS->elementsIterator( elemType );
5429 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5431 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5434 elemIt = sm->GetElements();
5435 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5437 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5438 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5442 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5444 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5445 if ( groupDS && ( elemType == groupDS->GetType() ||
5446 elemType == SMDSAbs_Node ||
5447 elemType == SMDSAbs_All ))
5449 elemIt = groupDS->GetElements();
5450 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5453 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5455 if ( filter_i->GetElementType() == theType ||
5456 elemType == SMDSAbs_Node ||
5457 elemType == SMDSAbs_All)
5459 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5460 if ( pred_i && pred_i->GetPredicate() )
5462 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5463 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5464 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5465 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5471 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5472 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5473 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5475 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5478 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5479 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5483 SMESH::long_array_var ids = theObject->GetIDs();
5484 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5486 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5489 if ( elemIt && elemIt->more() && !typeOK )
5491 if ( elemType == SMDSAbs_Node )
5493 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5497 elemIt = SMDS_ElemIteratorPtr();
5503 //=============================================================================
5504 namespace // Finding concurrent hypotheses
5505 //=============================================================================
5509 * \brief mapping of mesh dimension into shape type
5511 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5513 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5515 case 0: aType = TopAbs_VERTEX; break;
5516 case 1: aType = TopAbs_EDGE; break;
5517 case 2: aType = TopAbs_FACE; break;
5519 default:aType = TopAbs_SOLID; break;
5524 //-----------------------------------------------------------------------------
5526 * \brief Internal structure used to find concurrent submeshes
5528 * It represents a pair < submesh, concurrent dimension >, where
5529 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5530 * with another submesh. In other words, it is dimension of a hypothesis assigned
5537 int _dim; //!< a dimension the algo can build (concurrent dimension)
5538 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5539 TopTools_MapOfShape _shapeMap;
5540 SMESH_subMesh* _subMesh;
5541 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5543 //-----------------------------------------------------------------------------
5544 // Return the algorithm
5545 const SMESH_Algo* GetAlgo() const
5546 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5548 //-----------------------------------------------------------------------------
5550 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5552 const TopoDS_Shape& theShape)
5554 _subMesh = (SMESH_subMesh*)theSubMesh;
5555 SetShape( theDim, theShape );
5558 //-----------------------------------------------------------------------------
5560 void SetShape(const int theDim,
5561 const TopoDS_Shape& theShape)
5564 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5565 if (_dim >= _ownDim)
5566 _shapeMap.Add( theShape );
5568 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5569 for( ; anExp.More(); anExp.Next() )
5570 _shapeMap.Add( anExp.Current() );
5574 //-----------------------------------------------------------------------------
5575 //! Check sharing of sub-shapes
5576 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5577 const TopTools_MapOfShape& theToFind,
5578 const TopAbs_ShapeEnum theType)
5580 bool isShared = false;
5581 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5582 for (; !isShared && anItr.More(); anItr.Next() )
5584 const TopoDS_Shape aSubSh = anItr.Key();
5585 // check for case when concurrent dimensions are same
5586 isShared = theToFind.Contains( aSubSh );
5587 // check for sub-shape with concurrent dimension
5588 TopExp_Explorer anExp( aSubSh, theType );
5589 for ( ; !isShared && anExp.More(); anExp.Next() )
5590 isShared = theToFind.Contains( anExp.Current() );
5595 //-----------------------------------------------------------------------------
5596 //! check algorithms
5597 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5598 const SMESHDS_Hypothesis* theA2)
5600 if ( !theA1 || !theA2 ||
5601 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5602 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5603 return false; // one of the hypothesis is not algorithm
5604 // check algorithm names (should be equal)
5605 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5609 //-----------------------------------------------------------------------------
5610 //! Check if sub-shape hypotheses are concurrent
5611 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5613 if ( _subMesh == theOther->_subMesh )
5614 return false; // same sub-shape - should not be
5616 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5617 // any of the two submeshes is not on COMPOUND shape )
5618 // -> no concurrency
5619 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5620 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5621 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5622 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5623 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5626 // bool checkSubShape = ( _dim >= theOther->_dim )
5627 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5628 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5629 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5630 if ( !checkSubShape )
5633 // check algorithms to be same
5634 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5635 return true; // different algorithms -> concurrency !
5637 // check hypothesises for concurrence (skip first as algorithm)
5639 // pointers should be same, because it is referened from mesh hypothesis partition
5640 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5641 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5642 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5643 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5645 // the submeshes are concurrent if their algorithms has different parameters
5646 return nbSame != (int)theOther->_hypotheses.size() - 1;
5649 // Return true if algorithm of this SMESH_DimHyp is used if no
5650 // sub-mesh order is imposed by the user
5651 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5653 // NeedDiscreteBoundary() algo has a higher priority
5654 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5655 theOther->GetAlgo()->NeedDiscreteBoundary() )
5656 return !this->GetAlgo()->NeedDiscreteBoundary();
5658 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5661 }; // end of SMESH_DimHyp
5662 //-----------------------------------------------------------------------------
5664 typedef list<const SMESH_DimHyp*> TDimHypList;
5666 //-----------------------------------------------------------------------------
5668 void addDimHypInstance(const int theDim,
5669 const TopoDS_Shape& theShape,
5670 const SMESH_Algo* theAlgo,
5671 const SMESH_subMesh* theSubMesh,
5672 const list <const SMESHDS_Hypothesis*>& theHypList,
5673 TDimHypList* theDimHypListArr )
5675 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5676 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5677 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5678 dimHyp->_hypotheses.push_front(theAlgo);
5679 listOfdimHyp.push_back( dimHyp );
5682 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5683 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5684 theHypList.begin(), theHypList.end() );
5687 //-----------------------------------------------------------------------------
5688 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5689 TDimHypList& theListOfConcurr)
5691 if ( theListOfConcurr.empty() )
5693 theListOfConcurr.push_back( theDimHyp );
5697 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5698 while ( hypIt != theListOfConcurr.end() &&
5699 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5701 theListOfConcurr.insert( hypIt, theDimHyp );
5705 //-----------------------------------------------------------------------------
5706 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5707 const TDimHypList& theListOfDimHyp,
5708 TDimHypList& theListOfConcurrHyp,
5709 set<int>& theSetOfConcurrId )
5711 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5712 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5714 const SMESH_DimHyp* curDimHyp = *rIt;
5715 if ( curDimHyp == theDimHyp )
5716 break; // meet own dimHyp pointer in same dimension
5718 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5719 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5721 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5726 //-----------------------------------------------------------------------------
5727 void unionLists(TListOfInt& theListOfId,
5728 TListOfListOfInt& theListOfListOfId,
5731 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5732 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5734 continue; //skip already treated lists
5735 // check if other list has any same submesh object
5736 TListOfInt& otherListOfId = *it;
5737 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5738 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5741 // union two lists (from source into target)
5742 TListOfInt::iterator it2 = otherListOfId.begin();
5743 for ( ; it2 != otherListOfId.end(); it2++ ) {
5744 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5745 theListOfId.push_back(*it2);
5747 // clear source list
5748 otherListOfId.clear();
5751 //-----------------------------------------------------------------------------
5753 //! free memory allocated for dimension-hypothesis objects
5754 void removeDimHyps( TDimHypList* theArrOfList )
5756 for (int i = 0; i < 4; i++ ) {
5757 TDimHypList& listOfdimHyp = theArrOfList[i];
5758 TDimHypList::const_iterator it = listOfdimHyp.begin();
5759 for ( ; it != listOfdimHyp.end(); it++ )
5764 //-----------------------------------------------------------------------------
5766 * \brief find common submeshes with given submesh
5767 * \param theSubMeshList list of already collected submesh to check
5768 * \param theSubMesh given submesh to intersect with other
5769 * \param theCommonSubMeshes collected common submeshes
5771 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5772 const SMESH_subMesh* theSubMesh,
5773 set<const SMESH_subMesh*>& theCommon )
5777 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5778 for ( ; it != theSubMeshList.end(); it++ )
5779 theSubMesh->FindIntersection( *it, theCommon );
5780 theSubMeshList.push_back( theSubMesh );
5781 //theCommon.insert( theSubMesh );
5784 //-----------------------------------------------------------------------------
5785 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5787 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5788 for ( ; listsIt != smLists.end(); ++listsIt )
5790 const TListOfInt& smIDs = *listsIt;
5791 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5799 //=============================================================================
5801 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5803 //=============================================================================
5805 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5807 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5808 if ( isSubMeshInList( submeshID, anOrder ))
5811 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5812 return isSubMeshInList( submeshID, allConurrent );
5815 //=============================================================================
5817 * \brief Return submesh objects list in meshing order
5819 //=============================================================================
5821 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5823 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5825 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5827 return aResult._retn();
5829 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5830 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5831 anOrder.splice( anOrder.end(), allConurrent );
5834 TListOfListOfInt::iterator listIt = anOrder.begin();
5835 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5836 unionLists( *listIt, anOrder, listIndx + 1 );
5838 // convert submesh ids into interface instances
5839 // and dump command into python
5840 convertMeshOrder( anOrder, aResult, false );
5842 return aResult._retn();
5845 //=============================================================================
5847 * \brief Finds concurrent sub-meshes
5849 //=============================================================================
5851 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5853 TListOfListOfInt anOrder;
5854 ::SMESH_Mesh& mesh = GetImpl();
5856 // collect submeshes and detect concurrent algorithms and hypothesises
5857 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5859 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5860 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5861 ::SMESH_subMesh* sm = (*i_sm).second;
5863 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5865 // list of assigned hypothesises
5866 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5867 // Find out dimensions where the submesh can be concurrent.
5868 // We define the dimensions by algo of each of hypotheses in hypList
5869 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5870 for( ; hypIt != hypList.end(); hypIt++ ) {
5871 SMESH_Algo* anAlgo = 0;
5872 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5873 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5874 // hyp it-self is algo
5875 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5877 // try to find algorithm with help of sub-shapes
5878 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5879 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5880 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5883 continue; // no algorithm assigned to a current submesh
5885 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5886 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5888 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5889 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5890 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5892 } // end iterations on submesh
5894 // iterate on created dimension-hypotheses and check for concurrents
5895 for ( int i = 0; i < 4; i++ ) {
5896 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5897 // check for concurrents in own and other dimensions (step-by-step)
5898 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5899 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5900 const SMESH_DimHyp* dimHyp = *dhIt;
5901 TDimHypList listOfConcurr;
5902 set<int> setOfConcurrIds;
5903 // looking for concurrents and collect into own list
5904 for ( int j = i; j < 4; j++ )
5905 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5906 // check if any concurrents found
5907 if ( listOfConcurr.size() > 0 ) {
5908 // add own submesh to list of concurrent
5909 addInOrderOfPriority( dimHyp, listOfConcurr );
5910 list<int> listOfConcurrIds;
5911 TDimHypList::iterator hypIt = listOfConcurr.begin();
5912 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5913 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5914 anOrder.push_back( listOfConcurrIds );
5919 removeDimHyps(dimHypListArr);
5921 // now, minimize the number of concurrent groups
5922 // Here we assume that lists of submeshes can have same submesh
5923 // in case of multi-dimension algorithms, as result
5924 // list with common submesh has to be united into one list
5926 TListOfListOfInt::iterator listIt = anOrder.begin();
5927 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5928 unionLists( *listIt, anOrder, listIndx + 1 );
5934 //=============================================================================
5936 * \brief Set submesh object order
5937 * \param theSubMeshArray submesh array order
5939 //=============================================================================
5941 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5944 _preMeshInfo->ForgetOrLoad();
5947 ::SMESH_Mesh& mesh = GetImpl();
5949 TPythonDump aPythonDump; // prevent dump of called methods
5950 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5952 TListOfListOfInt subMeshOrder;
5953 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5955 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5956 TListOfInt subMeshIds;
5958 aPythonDump << ", ";
5959 aPythonDump << "[ ";
5960 // Collect subMeshes which should be clear
5961 // do it list-by-list, because modification of submesh order
5962 // take effect between concurrent submeshes only
5963 set<const SMESH_subMesh*> subMeshToClear;
5964 list<const SMESH_subMesh*> subMeshList;
5965 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5967 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5969 aPythonDump << ", ";
5970 aPythonDump << subMesh;
5971 subMeshIds.push_back( subMesh->GetId() );
5972 // detect common parts of submeshes
5973 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5974 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5976 aPythonDump << " ]";
5977 subMeshOrder.push_back( subMeshIds );
5979 // clear collected submeshes
5980 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5981 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5982 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5983 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5985 aPythonDump << " ])";
5987 mesh.SetMeshOrder( subMeshOrder );
5990 SMESH::SMESH_Mesh_var me = _this();
5991 _gen_i->UpdateIcons( me );
5996 //=============================================================================
5998 * \brief Convert submesh ids into submesh interfaces
6000 //=============================================================================
6002 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6003 SMESH::submesh_array_array& theResOrder,
6004 const bool theIsDump)
6006 int nbSet = theIdsOrder.size();
6007 TPythonDump aPythonDump; // prevent dump of called methods
6009 aPythonDump << "[ ";
6010 theResOrder.length(nbSet);
6011 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6013 for( ; it != theIdsOrder.end(); it++ ) {
6014 // translate submesh identificators into submesh objects
6015 // takeing into account real number of concurrent lists
6016 const TListOfInt& aSubOrder = (*it);
6017 if (!aSubOrder.size())
6020 aPythonDump << "[ ";
6021 // convert shape indices into interfaces
6022 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6023 aResSubSet->length(aSubOrder.size());
6024 TListOfInt::const_iterator subIt = aSubOrder.begin();
6026 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6027 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6029 SMESH::SMESH_subMesh_var subMesh =
6030 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6033 aPythonDump << ", ";
6034 aPythonDump << subMesh;
6036 aResSubSet[ j++ ] = subMesh;
6039 aPythonDump << " ]";
6041 theResOrder[ listIndx++ ] = aResSubSet;
6043 // correct number of lists
6044 theResOrder.length( listIndx );
6047 // finilise python dump
6048 aPythonDump << " ]";
6049 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6053 namespace // utils used by SMESH_MeshPartDS
6056 * \brief Class used to access to protected data of SMDS_MeshInfo
6058 struct TMeshInfo : public SMDS_MeshInfo
6060 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6063 * \brief Element holing its ID only
6065 struct TElemID : public SMDS_LinearEdge
6067 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6071 //================================================================================
6073 // Implementation of SMESH_MeshPartDS
6075 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6076 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6078 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6079 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6082 _meshDS = mesh_i->GetImpl().GetMeshDS();
6084 SetPersistentId( _meshDS->GetPersistentId() );
6086 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6088 // <meshPart> is the whole mesh
6089 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6091 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6092 myGroupSet = _meshDS->GetGroups();
6097 SMESH::long_array_var anIDs = meshPart->GetIDs();
6098 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6099 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6101 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6102 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6103 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6108 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6109 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6110 if ( _elements[ e->GetType() ].insert( e ).second )
6113 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6114 while ( nIt->more() )
6116 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6117 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6124 ShapeToMesh( _meshDS->ShapeToMesh() );
6126 _meshDS = 0; // to enforce iteration on _elements and _nodes
6129 // -------------------------------------------------------------------------------------
6130 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6131 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6134 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6135 for ( ; partIt != meshPart.end(); ++partIt )
6136 if ( const SMDS_MeshElement * e = *partIt )
6137 if ( _elements[ e->GetType() ].insert( e ).second )
6140 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6141 while ( nIt->more() )
6143 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6144 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6150 // -------------------------------------------------------------------------------------
6151 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6153 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6155 TElemID elem( IDelem );
6156 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6157 if ( !_elements[ iType ].empty() )
6159 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6160 if ( it != _elements[ iType ].end() )
6165 // -------------------------------------------------------------------------------------
6166 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6168 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6170 typedef SMDS_SetIterator
6171 <const SMDS_MeshElement*,
6172 TIDSortedElemSet::const_iterator,
6173 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6174 SMDS_MeshElement::GeomFilter
6177 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6179 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6180 _elements[type].end(),
6181 SMDS_MeshElement::GeomFilter( geomType )));
6183 // -------------------------------------------------------------------------------------
6184 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6186 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6188 typedef SMDS_SetIterator
6189 <const SMDS_MeshElement*,
6190 TIDSortedElemSet::const_iterator,
6191 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6192 SMDS_MeshElement::EntityFilter
6195 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6197 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6198 _elements[type].end(),
6199 SMDS_MeshElement::EntityFilter( entity )));
6201 // -------------------------------------------------------------------------------------
6202 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6204 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6205 if ( type == SMDSAbs_All && !_meshDS )
6207 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6209 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6210 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6212 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6214 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6215 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6217 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6218 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6220 // -------------------------------------------------------------------------------------
6221 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6222 iterType SMESH_MeshPartDS::methName() const \
6224 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6225 return _meshDS ? _meshDS->methName() : iterType \
6226 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6228 // -------------------------------------------------------------------------------------
6229 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6230 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6231 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6232 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6233 #undef _GET_ITER_DEFINE
6235 // END Implementation of SMESH_MeshPartDS
6237 //================================================================================